Replace static_lifetime usages with error_lifetime, lower outlives goals

This commit is contained in:
Lukas Wirth 2024-04-02 14:03:49 +02:00
parent 3691380c35
commit 0927f86247
15 changed files with 139 additions and 98 deletions

View file

@ -422,6 +422,10 @@ impl ModuleId {
} }
} }
pub fn crate_def_map(self, db: &dyn DefDatabase) -> Arc<DefMap> {
db.crate_def_map(self.krate)
}
pub fn krate(self) -> CrateId { pub fn krate(self) -> CrateId {
self.krate self.krate
} }
@ -438,6 +442,8 @@ impl ModuleId {
}) })
} }
/// Returns the module containing `self`, either the parent `mod`, or the module (or block) containing
/// the block, if `self` corresponds to a block expression.
pub fn containing_module(self, db: &dyn DefDatabase) -> Option<ModuleId> { pub fn containing_module(self, db: &dyn DefDatabase) -> Option<ModuleId> {
self.def_map(db).containing_module(self.local_id) self.def_map(db).containing_module(self.local_id)
} }
@ -929,6 +935,18 @@ impl GenericDefId {
GenericDefId::EnumVariantId(_) => (FileId::BOGUS.into(), None), GenericDefId::EnumVariantId(_) => (FileId::BOGUS.into(), None),
} }
} }
pub fn assoc_trait_container(self, db: &dyn DefDatabase) -> Option<TraitId> {
match match self {
GenericDefId::FunctionId(f) => f.lookup(db).container,
GenericDefId::TypeAliasId(t) => t.lookup(db).container,
GenericDefId::ConstId(c) => c.lookup(db).container,
_ => return None,
} {
ItemContainerId::TraitId(trait_) => Some(trait_),
_ => None,
}
}
} }
impl From<AssocItemId> for GenericDefId { impl From<AssocItemId> for GenericDefId {

View file

@ -1,6 +1,8 @@
//! Various extensions traits for Chalk types. //! Various extensions traits for Chalk types.
use chalk_ir::{cast::Cast, FloatTy, IntTy, Mutability, Scalar, TyVariableKind, UintTy}; use chalk_ir::{
cast::Cast, FloatTy, IntTy, Mutability, Scalar, TyVariableKind, TypeOutlives, UintTy,
};
use hir_def::{ use hir_def::{
builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType, BuiltinUint}, builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType, BuiltinUint},
generics::TypeOrConstParamData, generics::TypeOrConstParamData,
@ -312,7 +314,7 @@ impl TyExt for Ty {
.generic_predicates(id.parent) .generic_predicates(id.parent)
.iter() .iter()
.map(|pred| pred.clone().substitute(Interner, &substs)) .map(|pred| pred.clone().substitute(Interner, &substs))
.filter(|wc| match &wc.skip_binders() { .filter(|wc| match wc.skip_binders() {
WhereClause::Implemented(tr) => { WhereClause::Implemented(tr) => {
&tr.self_type_parameter(Interner) == self &tr.self_type_parameter(Interner) == self
} }
@ -320,6 +322,9 @@ impl TyExt for Ty {
alias: AliasTy::Projection(proj), alias: AliasTy::Projection(proj),
ty: _, ty: _,
}) => &proj.self_type_parameter(db) == self, }) => &proj.self_type_parameter(db) == self,
WhereClause::TypeOutlives(TypeOutlives { ty, lifetime: _ }) => {
ty == self
}
_ => false, _ => false,
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();

View file

@ -55,10 +55,10 @@ use triomphe::Arc;
use crate::{ use crate::{
db::HirDatabase, db::HirDatabase,
fold_tys, error_lifetime, fold_tys,
infer::{coerce::CoerceMany, unify::InferenceTable}, infer::{coerce::CoerceMany, unify::InferenceTable},
lower::ImplTraitLoweringMode, lower::ImplTraitLoweringMode,
static_lifetime, to_assoc_type_id, to_assoc_type_id,
traits::FnTrait, traits::FnTrait,
utils::{InTypeConstIdMetadata, UnevaluatedConstEvaluatorFolder}, utils::{InTypeConstIdMetadata, UnevaluatedConstEvaluatorFolder},
AliasEq, AliasTy, Binders, ClosureId, Const, DomainGoal, GenericArg, Goal, ImplTraitId, AliasEq, AliasTy, Binders, ClosureId, Const, DomainGoal, GenericArg, Goal, ImplTraitId,
@ -326,7 +326,7 @@ pub struct Adjustment {
impl Adjustment { impl Adjustment {
pub fn borrow(m: Mutability, ty: Ty) -> Self { pub fn borrow(m: Mutability, ty: Ty) -> Self {
let ty = TyKind::Ref(m, static_lifetime(), ty).intern(Interner); let ty = TyKind::Ref(m, error_lifetime(), ty).intern(Interner);
Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(m)), target: ty } Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(m)), target: ty }
} }
} }

View file

@ -22,9 +22,9 @@ use stdx::never;
use crate::{ use crate::{
db::{HirDatabase, InternedClosure}, db::{HirDatabase, InternedClosure},
from_chalk_trait_id, from_placeholder_idx, make_binders, error_lifetime, from_chalk_trait_id, from_placeholder_idx, make_binders,
mir::{BorrowKind, MirSpan, MutBorrowKind, ProjectionElem}, mir::{BorrowKind, MirSpan, MutBorrowKind, ProjectionElem},
static_lifetime, to_chalk_trait_id, to_chalk_trait_id,
traits::FnTrait, traits::FnTrait,
utils::{self, elaborate_clause_supertraits, generics, Generics}, utils::{self, elaborate_clause_supertraits, generics, Generics},
Adjust, Adjustment, AliasEq, AliasTy, Binders, BindingMode, ChalkTraitId, ClosureId, DynTy, Adjust, Adjustment, AliasEq, AliasTy, Binders, BindingMode, ChalkTraitId, ClosureId, DynTy,
@ -324,7 +324,7 @@ impl CapturedItemWithoutTy {
BorrowKind::Mut { .. } => Mutability::Mut, BorrowKind::Mut { .. } => Mutability::Mut,
_ => Mutability::Not, _ => Mutability::Not,
}; };
TyKind::Ref(m, static_lifetime(), ty).intern(Interner) TyKind::Ref(m, error_lifetime(), ty).intern(Interner)
} }
}; };
return CapturedItem { return CapturedItem {

View file

@ -18,11 +18,11 @@ use triomphe::Arc;
use crate::{ use crate::{
autoderef::{Autoderef, AutoderefKind}, autoderef::{Autoderef, AutoderefKind},
db::HirDatabase, db::HirDatabase,
error_lifetime,
infer::{ infer::{
Adjust, Adjustment, AutoBorrow, InferOk, InferenceContext, OverloadedDeref, PointerCast, Adjust, Adjustment, AutoBorrow, InferOk, InferenceContext, OverloadedDeref, PointerCast,
TypeError, TypeMismatch, TypeError, TypeMismatch,
}, },
static_lifetime,
utils::ClosureSubst, utils::ClosureSubst,
Canonical, DomainGoal, FnAbi, FnPointer, FnSig, Guidance, InEnvironment, Interner, Solution, Canonical, DomainGoal, FnAbi, FnPointer, FnSig, Guidance, InEnvironment, Interner, Solution,
Substitution, TraitEnvironment, Ty, TyBuilder, TyExt, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt,
@ -427,7 +427,7 @@ impl InferenceTable<'_> {
// compare those. Note that this means we use the target // compare those. Note that this means we use the target
// mutability [1], since it may be that we are coercing // mutability [1], since it may be that we are coercing
// from `&mut T` to `&U`. // from `&mut T` to `&U`.
let lt = static_lifetime(); // FIXME: handle lifetimes correctly, see rustc let lt = error_lifetime(); // FIXME: handle lifetimes correctly, see rustc
let derefd_from_ty = TyKind::Ref(to_mt, lt, referent_ty).intern(Interner); let derefd_from_ty = TyKind::Ref(to_mt, lt, referent_ty).intern(Interner);
match autoderef.table.try_unify(&derefd_from_ty, to_ty) { match autoderef.table.try_unify(&derefd_from_ty, to_ty) {
Ok(result) => { Ok(result) => {
@ -621,7 +621,7 @@ impl InferenceTable<'_> {
(TyKind::Ref(from_mt, _, from_inner), &TyKind::Ref(to_mt, _, _)) => { (TyKind::Ref(from_mt, _, from_inner), &TyKind::Ref(to_mt, _, _)) => {
coerce_mutabilities(*from_mt, to_mt)?; coerce_mutabilities(*from_mt, to_mt)?;
let lt = static_lifetime(); let lt = error_lifetime();
Some(( Some((
Adjustment { kind: Adjust::Deref(None), target: from_inner.clone() }, Adjustment { kind: Adjust::Deref(None), target: from_inner.clone() },
Adjustment { Adjustment {

View file

@ -23,6 +23,7 @@ use crate::{
autoderef::{builtin_deref, deref_by_trait, Autoderef}, autoderef::{builtin_deref, deref_by_trait, Autoderef},
consteval, consteval,
db::{InternedClosure, InternedCoroutine}, db::{InternedClosure, InternedCoroutine},
error_lifetime,
infer::{ infer::{
coerce::{CoerceMany, CoercionCause}, coerce::{CoerceMany, CoercionCause},
find_continuable, find_continuable,
@ -630,7 +631,7 @@ impl InferenceContext<'_> {
let inner_ty = self.infer_expr_inner(*expr, &expectation); let inner_ty = self.infer_expr_inner(*expr, &expectation);
match rawness { match rawness {
Rawness::RawPtr => TyKind::Raw(mutability, inner_ty), Rawness::RawPtr => TyKind::Raw(mutability, inner_ty),
Rawness::Ref => TyKind::Ref(mutability, static_lifetime(), inner_ty), Rawness::Ref => TyKind::Ref(mutability, error_lifetime(), inner_ty),
} }
.intern(Interner) .intern(Interner)
} }

View file

@ -12,6 +12,7 @@ use hir_expand::name::Name;
use crate::{ use crate::{
consteval::{try_const_usize, usize_const}, consteval::{try_const_usize, usize_const},
error_lifetime,
infer::{BindingMode, Expectation, InferenceContext, TypeMismatch}, infer::{BindingMode, Expectation, InferenceContext, TypeMismatch},
lower::lower_to_chalk_mutability, lower::lower_to_chalk_mutability,
primitive::UintTy, primitive::UintTy,
@ -396,14 +397,14 @@ impl InferenceContext<'_> {
None => { None => {
let inner_ty = self.table.new_type_var(); let inner_ty = self.table.new_type_var();
let ref_ty = let ref_ty =
TyKind::Ref(mutability, static_lifetime(), inner_ty.clone()).intern(Interner); TyKind::Ref(mutability, error_lifetime(), inner_ty.clone()).intern(Interner);
// Unification failure will be reported by the caller. // Unification failure will be reported by the caller.
self.unify(&ref_ty, expected); self.unify(&ref_ty, expected);
inner_ty inner_ty
} }
}; };
let subty = self.infer_pat(inner_pat, &expectation, default_bm); let subty = self.infer_pat(inner_pat, &expectation, default_bm);
TyKind::Ref(mutability, static_lifetime(), subty).intern(Interner) TyKind::Ref(mutability, error_lifetime(), subty).intern(Interner)
} }
fn infer_bind_pat( fn infer_bind_pat(
@ -430,7 +431,7 @@ impl InferenceContext<'_> {
let bound_ty = match mode { let bound_ty = match mode {
BindingMode::Ref(mutability) => { BindingMode::Ref(mutability) => {
TyKind::Ref(mutability, static_lifetime(), inner_ty.clone()).intern(Interner) TyKind::Ref(mutability, error_lifetime(), inner_ty.clone()).intern(Interner)
} }
BindingMode::Move => inner_ty.clone(), BindingMode::Move => inner_ty.clone(),
}; };

View file

@ -16,8 +16,8 @@ use triomphe::Arc;
use super::{InferOk, InferResult, InferenceContext, TypeError}; use super::{InferOk, InferResult, InferenceContext, TypeError};
use crate::{ use crate::{
consteval::unknown_const, db::HirDatabase, fold_generic_args, fold_tys_and_consts, consteval::unknown_const, db::HirDatabase, error_lifetime, fold_generic_args,
static_lifetime, to_chalk_trait_id, traits::FnTrait, AliasEq, AliasTy, BoundVar, Canonical, fold_tys_and_consts, to_chalk_trait_id, traits::FnTrait, AliasEq, AliasTy, BoundVar, Canonical,
Const, ConstValue, DebruijnIndex, DomainGoal, GenericArg, GenericArgData, Goal, GoalData, Const, ConstValue, DebruijnIndex, DomainGoal, GenericArg, GenericArgData, Goal, GoalData,
Guidance, InEnvironment, InferenceVar, Interner, Lifetime, OpaqueTyId, ParamKind, ProjectionTy, Guidance, InEnvironment, InferenceVar, Interner, Lifetime, OpaqueTyId, ParamKind, ProjectionTy,
ProjectionTyExt, Scalar, Solution, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt, ProjectionTyExt, Scalar, Solution, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt,
@ -43,40 +43,21 @@ impl InferenceContext<'_> {
let obligations = pending_obligations let obligations = pending_obligations
.iter() .iter()
.filter_map(|obligation| match obligation.value.value.goal.data(Interner) { .filter_map(|obligation| match obligation.value.value.goal.data(Interner) {
GoalData::DomainGoal(DomainGoal::Holds( GoalData::DomainGoal(DomainGoal::Holds(clause)) => {
clause @ WhereClause::AliasEq(AliasEq { let ty = match clause {
alias: AliasTy::Projection(projection), WhereClause::AliasEq(AliasEq {
.. alias: AliasTy::Projection(projection),
}), ..
)) => { }) => projection.self_type_parameter(self.db),
let projection_self = projection.self_type_parameter(self.db); WhereClause::Implemented(trait_ref) => {
let uncanonical = chalk_ir::Substitute::apply( trait_ref.self_type_parameter(Interner)
&obligation.free_vars, }
projection_self, WhereClause::TypeOutlives(to) => to.ty.clone(),
Interner, _ => return None,
); };
if matches!(
self.resolve_ty_shallow(&uncanonical).kind(Interner), let uncanonical =
TyKind::InferenceVar(iv, TyVariableKind::General) if *iv == root, chalk_ir::Substitute::apply(&obligation.free_vars, ty, Interner);
) {
Some(chalk_ir::Substitute::apply(
&obligation.free_vars,
clause.clone(),
Interner,
))
} else {
None
}
}
GoalData::DomainGoal(DomainGoal::Holds(
clause @ WhereClause::Implemented(trait_ref),
)) => {
let trait_ref_self = trait_ref.self_type_parameter(Interner);
let uncanonical = chalk_ir::Substitute::apply(
&obligation.free_vars,
trait_ref_self,
Interner,
);
if matches!( if matches!(
self.resolve_ty_shallow(&uncanonical).kind(Interner), self.resolve_ty_shallow(&uncanonical).kind(Interner),
TyKind::InferenceVar(iv, TyVariableKind::General) if *iv == root, TyKind::InferenceVar(iv, TyVariableKind::General) if *iv == root,
@ -121,8 +102,9 @@ impl<T: HasInterner<Interner = Interner>> Canonicalized<T> {
VariableKind::Ty(TyVariableKind::General) => ctx.new_type_var().cast(Interner), VariableKind::Ty(TyVariableKind::General) => ctx.new_type_var().cast(Interner),
VariableKind::Ty(TyVariableKind::Integer) => ctx.new_integer_var().cast(Interner), VariableKind::Ty(TyVariableKind::Integer) => ctx.new_integer_var().cast(Interner),
VariableKind::Ty(TyVariableKind::Float) => ctx.new_float_var().cast(Interner), VariableKind::Ty(TyVariableKind::Float) => ctx.new_float_var().cast(Interner),
// Chalk can sometimes return new lifetime variables. We just use the static lifetime everywhere // Chalk can sometimes return new lifetime variables. We just replace them by errors
VariableKind::Lifetime => static_lifetime().cast(Interner), // for now.
VariableKind::Lifetime => error_lifetime().cast(Interner),
VariableKind::Const(ty) => ctx.new_const_var(ty.clone()).cast(Interner), VariableKind::Const(ty) => ctx.new_const_var(ty.clone()).cast(Interner),
}), }),
); );
@ -1020,11 +1002,11 @@ mod resolve {
_var: InferenceVar, _var: InferenceVar,
_outer_binder: DebruijnIndex, _outer_binder: DebruijnIndex,
) -> Lifetime { ) -> Lifetime {
// fall back all lifetimes to 'static -- currently we don't deal // fall back all lifetimes to 'error -- currently we don't deal
// with any lifetimes, but we can sometimes get some lifetime // with any lifetimes, but we can sometimes get some lifetime
// variables through Chalk's unification, and this at least makes // variables through Chalk's unification, and this at least makes
// sure we don't leak them outside of inference // sure we don't leak them outside of inference
crate::static_lifetime() crate::error_lifetime()
} }
} }
} }

View file

@ -622,7 +622,7 @@ pub fn static_lifetime() -> Lifetime {
} }
pub fn error_lifetime() -> Lifetime { pub fn error_lifetime() -> Lifetime {
static_lifetime() LifetimeData::Static.intern(Interner)
} }
pub(crate) fn fold_free_vars<T: HasInterner<Interner = Interner> + TypeFoldable<Interner>>( pub(crate) fn fold_free_vars<T: HasInterner<Interner = Interner> + TypeFoldable<Interner>>(
@ -861,7 +861,7 @@ where
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
Err(NoSolution) Err(NoSolution)
} else { } else {
Ok(static_lifetime()) Ok(error_lifetime())
} }
} }
@ -873,7 +873,7 @@ where
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
Err(NoSolution) Err(NoSolution)
} else { } else {
Ok(static_lifetime()) Ok(error_lifetime())
} }
} }
} }

View file

@ -15,7 +15,10 @@ use base_db::{
CrateId, CrateId,
}; };
use chalk_ir::{ use chalk_ir::{
cast::Cast, fold::Shift, fold::TypeFoldable, interner::HasInterner, Mutability, Safety, cast::Cast,
fold::{Shift, TypeFoldable},
interner::HasInterner,
Mutability, Safety, TypeOutlives,
}; };
use either::Either; use either::Either;
@ -64,7 +67,7 @@ use crate::{
}, },
AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, ConstScalar, DebruijnIndex, DynTy, AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, ConstScalar, DebruijnIndex, DynTy,
FnAbi, FnPointer, FnSig, FnSubst, ImplTrait, ImplTraitId, ImplTraits, Interner, Lifetime, FnAbi, FnPointer, FnSig, FnSubst, ImplTrait, ImplTraitId, ImplTraits, Interner, Lifetime,
LifetimeData, ParamKind, PolyFnSig, ProjectionTy, QuantifiedWhereClause, LifetimeData, LifetimeOutlives, ParamKind, PolyFnSig, ProjectionTy, QuantifiedWhereClause,
QuantifiedWhereClauses, Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, QuantifiedWhereClauses, Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder,
TyKind, WhereClause, TyKind, WhereClause,
}; };
@ -282,7 +285,7 @@ impl<'a> TyLoweringContext<'a> {
let inner_ty = self.lower_ty(inner); let inner_ty = self.lower_ty(inner);
// FIXME: It should infer the eldided lifetimes instead of stubbing with static // FIXME: It should infer the eldided lifetimes instead of stubbing with static
let lifetime = let lifetime =
lifetime.as_ref().map_or_else(static_lifetime, |lr| self.lower_lifetime(lr)); lifetime.as_ref().map_or_else(error_lifetime, |lr| self.lower_lifetime(lr));
TyKind::Ref(lower_to_chalk_mutability(*mutability), lifetime, inner_ty) TyKind::Ref(lower_to_chalk_mutability(*mutability), lifetime, inner_ty)
.intern(Interner) .intern(Interner)
} }
@ -1048,7 +1051,13 @@ impl<'a> TyLoweringContext<'a> {
.collect::<Vec<_>>() .collect::<Vec<_>>()
.into_iter() .into_iter()
} }
WherePredicate::Lifetime { .. } => vec![].into_iter(), WherePredicate::Lifetime { bound, target } => {
vec![crate::wrap_empty_binders(WhereClause::LifetimeOutlives(LifetimeOutlives {
a: self.lower_lifetime(bound),
b: self.lower_lifetime(target),
}))]
.into_iter()
}
} }
} }
@ -1101,7 +1110,13 @@ impl<'a> TyLoweringContext<'a> {
bindings = self.lower_trait_ref_from_path(path, Some(self_ty)); bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
bindings.clone().map(WhereClause::Implemented).map(crate::wrap_empty_binders) bindings.clone().map(WhereClause::Implemented).map(crate::wrap_empty_binders)
} }
TypeBound::Lifetime(_) => None, TypeBound::Lifetime(l) => {
let lifetime = self.lower_lifetime(l);
Some(crate::wrap_empty_binders(WhereClause::TypeOutlives(TypeOutlives {
ty: self_ty,
lifetime,
})))
}
TypeBound::Error => None, TypeBound::Error => None,
}; };
trait_ref.into_iter().chain( trait_ref.into_iter().chain(
@ -1264,10 +1279,19 @@ impl<'a> TyLoweringContext<'a> {
// bounds in the input. // bounds in the input.
// INVARIANT: If this function returns `DynTy`, there should be at least one trait bound. // INVARIANT: If this function returns `DynTy`, there should be at least one trait bound.
// These invariants are utilized by `TyExt::dyn_trait()` and chalk. // These invariants are utilized by `TyExt::dyn_trait()` and chalk.
let mut lifetime = None;
let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| { let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
let mut bounds: Vec<_> = bounds let mut bounds: Vec<_> = bounds
.iter() .iter()
.flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)) .flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false))
.filter(|b| match b.skip_binders() {
WhereClause::Implemented(_) | WhereClause::AliasEq(_) => true,
WhereClause::LifetimeOutlives(_) => false,
WhereClause::TypeOutlives(t) => {
lifetime = Some(t.lifetime.clone());
false
}
})
.collect(); .collect();
let mut multiple_regular_traits = false; let mut multiple_regular_traits = false;
@ -1305,7 +1329,7 @@ impl<'a> TyLoweringContext<'a> {
_ => unreachable!(), _ => unreachable!(),
} }
} }
// We don't produce `WhereClause::{TypeOutlives, LifetimeOutlives}` yet. // `WhereClause::{TypeOutlives, LifetimeOutlives}` have been filtered out
_ => unreachable!(), _ => unreachable!(),
} }
}); });
@ -1325,7 +1349,21 @@ impl<'a> TyLoweringContext<'a> {
if let Some(bounds) = bounds { if let Some(bounds) = bounds {
let bounds = crate::make_single_type_binders(bounds); let bounds = crate::make_single_type_binders(bounds);
TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(Interner) TyKind::Dyn(DynTy {
bounds,
lifetime: match lifetime {
Some(it) => match it.bound_var(Interner) {
Some(bound_var) => LifetimeData::BoundVar(BoundVar::new(
DebruijnIndex::INNERMOST,
bound_var.index,
))
.intern(Interner),
None => it,
},
None => static_lifetime(),
},
})
.intern(Interner)
} else { } else {
// FIXME: report error // FIXME: report error
// (additional non-auto traits, associated type rebound, or no resolved trait) // (additional non-auto traits, associated type rebound, or no resolved trait)
@ -1657,18 +1695,7 @@ pub(crate) fn trait_environment_query(
} }
} }
let container: Option<ItemContainerId> = match def { if let Some(trait_id) = def.assoc_trait_container(db.upcast()) {
// FIXME: is there a function for this?
GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container),
GenericDefId::AdtId(_) => None,
GenericDefId::TraitId(_) => None,
GenericDefId::TraitAliasId(_) => None,
GenericDefId::TypeAliasId(t) => Some(t.lookup(db.upcast()).container),
GenericDefId::ImplId(_) => None,
GenericDefId::EnumVariantId(_) => None,
GenericDefId::ConstId(c) => Some(c.lookup(db.upcast()).container),
};
if let Some(ItemContainerId::TraitId(trait_id)) = container {
// add `Self: Trait<T1, T2, ...>` to the environment in trait // add `Self: Trait<T1, T2, ...>` to the environment in trait
// function default implementations (and speculative code // function default implementations (and speculative code
// inside consts or type aliases) // inside consts or type aliases)
@ -1796,8 +1823,7 @@ pub(crate) fn generic_defaults_query(
make_binders(db, &generic_params, val) make_binders(db, &generic_params, val)
} }
GenericParamDataRef::LifetimeParamData(_) => { GenericParamDataRef::LifetimeParamData(_) => {
// using static because it requires defaults make_binders(db, &generic_params, error_lifetime().cast(Interner))
make_binders(db, &generic_params, static_lifetime().cast(Interner))
} }
} }
})); }));
@ -1817,7 +1843,7 @@ pub(crate) fn generic_defaults_recover(
let val = match id { let val = match id {
GenericParamId::TypeParamId(_) => TyKind::Error.intern(Interner).cast(Interner), GenericParamId::TypeParamId(_) => TyKind::Error.intern(Interner).cast(Interner),
GenericParamId::ConstParamId(id) => unknown_const_as_generic(db.const_param_ty(id)), GenericParamId::ConstParamId(id) => unknown_const_as_generic(db.const_param_ty(id)),
GenericParamId::LifetimeParamId(_) => static_lifetime().cast(Interner), GenericParamId::LifetimeParamId(_) => error_lifetime().cast(Interner),
}; };
crate::make_binders(db, &generic_params, val) crate::make_binders(db, &generic_params, val)
})); }));

View file

@ -22,10 +22,10 @@ use triomphe::Arc;
use crate::{ use crate::{
autoderef::{self, AutoderefKind}, autoderef::{self, AutoderefKind},
db::HirDatabase, db::HirDatabase,
from_chalk_trait_id, from_foreign_def_id, error_lifetime, from_chalk_trait_id, from_foreign_def_id,
infer::{unify::InferenceTable, Adjust, Adjustment, OverloadedDeref, PointerCast}, infer::{unify::InferenceTable, Adjust, Adjustment, OverloadedDeref, PointerCast},
primitive::{FloatTy, IntTy, UintTy}, primitive::{FloatTy, IntTy, UintTy},
static_lifetime, to_chalk_trait_id, to_chalk_trait_id,
utils::all_super_traits, utils::all_super_traits,
AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, DynTyExt, ForeignDefId, Goal, Guidance, AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, DynTyExt, ForeignDefId, Goal, Guidance,
InEnvironment, Interner, Scalar, Solution, Substitution, TraitEnvironment, TraitRef, InEnvironment, Interner, Scalar, Solution, Substitution, TraitEnvironment, TraitRef,
@ -1035,7 +1035,7 @@ fn iterate_method_candidates_with_autoref(
iterate_method_candidates_by_receiver(receiver_ty.clone(), maybe_reborrowed)?; iterate_method_candidates_by_receiver(receiver_ty.clone(), maybe_reborrowed)?;
let refed = Canonical { let refed = Canonical {
value: TyKind::Ref(Mutability::Not, static_lifetime(), receiver_ty.value.clone()) value: TyKind::Ref(Mutability::Not, error_lifetime(), receiver_ty.value.clone())
.intern(Interner), .intern(Interner),
binders: receiver_ty.binders.clone(), binders: receiver_ty.binders.clone(),
}; };
@ -1043,7 +1043,7 @@ fn iterate_method_candidates_with_autoref(
iterate_method_candidates_by_receiver(refed, first_adjustment.with_autoref(Mutability::Not))?; iterate_method_candidates_by_receiver(refed, first_adjustment.with_autoref(Mutability::Not))?;
let ref_muted = Canonical { let ref_muted = Canonical {
value: TyKind::Ref(Mutability::Mut, static_lifetime(), receiver_ty.value.clone()) value: TyKind::Ref(Mutability::Mut, error_lifetime(), receiver_ty.value.clone())
.intern(Interner), .intern(Interner),
binders: receiver_ty.binders, binders: receiver_ty.binders,
}; };
@ -1369,6 +1369,7 @@ pub(crate) fn resolve_indexing_op(
None None
} }
// FIXME: Replace this with a `Try` impl once stable
macro_rules! check_that { macro_rules! check_that {
($cond:expr) => { ($cond:expr) => {
if !$cond { if !$cond {
@ -1377,6 +1378,7 @@ macro_rules! check_that {
}; };
} }
#[derive(Debug)]
enum IsValidCandidate { enum IsValidCandidate {
Yes, Yes,
No, No,

View file

@ -9,11 +9,14 @@ use hir_def::{
resolver::HasResolver, resolver::HasResolver,
}; };
use crate::mir::eval::{ use crate::{
name, pad16, static_lifetime, Address, AdtId, Arc, BuiltinType, Evaluator, FunctionId, error_lifetime,
HasModule, HirDisplay, Interned, InternedClosure, Interner, Interval, IntervalAndTy, mir::eval::{
IntervalOrOwned, ItemContainerId, LangItem, Layout, Locals, Lookup, MirEvalError, MirSpan, name, pad16, Address, AdtId, Arc, BuiltinType, Evaluator, FunctionId, HasModule,
Mutability, Result, Substitution, Ty, TyBuilder, TyExt, HirDisplay, Interned, InternedClosure, Interner, Interval, IntervalAndTy, IntervalOrOwned,
ItemContainerId, LangItem, Layout, Locals, Lookup, MirEvalError, MirSpan, Mutability,
Result, Substitution, Ty, TyBuilder, TyExt,
},
}; };
mod simd; mod simd;
@ -247,7 +250,7 @@ impl Evaluator<'_> {
let tmp = self.heap_allocate(self.ptr_size(), self.ptr_size())?; let tmp = self.heap_allocate(self.ptr_size(), self.ptr_size())?;
let arg = IntervalAndTy { let arg = IntervalAndTy {
interval: Interval { addr: tmp, size: self.ptr_size() }, interval: Interval { addr: tmp, size: self.ptr_size() },
ty: TyKind::Ref(Mutability::Not, static_lifetime(), ty.clone()).intern(Interner), ty: TyKind::Ref(Mutability::Not, error_lifetime(), ty.clone()).intern(Interner),
}; };
let offset = layout.fields.offset(i).bytes_usize(); let offset = layout.fields.offset(i).bytes_usize();
self.write_memory(tmp, &addr.offset(offset).to_bytes())?; self.write_memory(tmp, &addr.offset(offset).to_bytes())?;

View file

@ -27,6 +27,7 @@ use crate::{
consteval::ConstEvalError, consteval::ConstEvalError,
db::{HirDatabase, InternedClosure}, db::{HirDatabase, InternedClosure},
display::HirDisplay, display::HirDisplay,
error_lifetime,
infer::{CaptureKind, CapturedItem, TypeMismatch}, infer::{CaptureKind, CapturedItem, TypeMismatch},
inhabitedness::is_ty_uninhabited_from, inhabitedness::is_ty_uninhabited_from,
layout::LayoutError, layout::LayoutError,
@ -2032,10 +2033,12 @@ pub fn mir_body_for_closure_query(
let closure_local = ctx.result.locals.alloc(Local { let closure_local = ctx.result.locals.alloc(Local {
ty: match kind { ty: match kind {
FnTrait::FnOnce => infer[expr].clone(), FnTrait::FnOnce => infer[expr].clone(),
FnTrait::FnMut => TyKind::Ref(Mutability::Mut, static_lifetime(), infer[expr].clone()) FnTrait::FnMut => {
.intern(Interner), TyKind::Ref(Mutability::Mut, error_lifetime(), infer[expr].clone()).intern(Interner)
FnTrait::Fn => TyKind::Ref(Mutability::Not, static_lifetime(), infer[expr].clone()) }
.intern(Interner), FnTrait::Fn => {
TyKind::Ref(Mutability::Not, error_lifetime(), infer[expr].clone()).intern(Interner)
}
}, },
}); });
ctx.result.param_locals.push(closure_local); ctx.result.param_locals.push(closure_local);

View file

@ -290,7 +290,7 @@ impl MirLowerCtx<'_> {
Some((_, _, mutability)) => mutability, Some((_, _, mutability)) => mutability,
None => Mutability::Not, None => Mutability::Not,
}; };
let result_ref = TyKind::Ref(mutability, static_lifetime(), result_ty).intern(Interner); let result_ref = TyKind::Ref(mutability, error_lifetime(), result_ty).intern(Interner);
let mut result: Place = self.temp(result_ref, current, span)?.into(); let mut result: Place = self.temp(result_ref, current, span)?.into();
let index_fn_op = Operand::const_zst( let index_fn_op = Operand::const_zst(
TyKind::FnDef( TyKind::FnDef(
@ -333,8 +333,8 @@ impl MirLowerCtx<'_> {
BorrowKind::Mut { kind: MutBorrowKind::Default }, BorrowKind::Mut { kind: MutBorrowKind::Default },
) )
}; };
let ty_ref = TyKind::Ref(chalk_mut, static_lifetime(), source_ty.clone()).intern(Interner); let ty_ref = TyKind::Ref(chalk_mut, error_lifetime(), source_ty.clone()).intern(Interner);
let target_ty_ref = TyKind::Ref(chalk_mut, static_lifetime(), target_ty).intern(Interner); let target_ty_ref = TyKind::Ref(chalk_mut, error_lifetime(), target_ty).intern(Interner);
let ref_place: Place = self.temp(ty_ref, current, span)?.into(); let ref_place: Place = self.temp(ty_ref, current, span)?.into();
self.push_assignment(current, ref_place, Rvalue::Ref(borrow_kind, place), span); self.push_assignment(current, ref_place, Rvalue::Ref(borrow_kind, place), span);
let deref_trait = self let deref_trait = self

View file

@ -3909,7 +3909,7 @@ impl Type {
inner.derived( inner.derived(
TyKind::Ref( TyKind::Ref(
if m.is_mut() { hir_ty::Mutability::Mut } else { hir_ty::Mutability::Not }, if m.is_mut() { hir_ty::Mutability::Mut } else { hir_ty::Mutability::Not },
hir_ty::static_lifetime(), hir_ty::error_lifetime(),
inner.ty.clone(), inner.ty.clone(),
) )
.intern(Interner), .intern(Interner),