Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/infer.rs')
| -rw-r--r-- | crates/hir-ty/src/infer.rs | 111 |
1 files changed, 75 insertions, 36 deletions
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index cad2e3ce99..38807b6f72 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs @@ -34,8 +34,8 @@ use chalk_ir::{ }; use either::Either; use hir_def::{ - AdtId, AssocItemId, DefWithBodyId, FieldId, FunctionId, GenericDefId, GenericParamId, ImplId, - ItemContainerId, Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId, VariantId, + AdtId, AssocItemId, ConstId, DefWithBodyId, FieldId, FunctionId, GenericDefId, GenericParamId, + ImplId, ItemContainerId, Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId, VariantId, builtin_type::{BuiltinInt, BuiltinType, BuiltinUint}, expr_store::{Body, ExpressionStore, HygieneId, path::Path}, hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId}, @@ -67,9 +67,9 @@ use crate::{ expr::ExprIsRead, unify::InferenceTable, }, - lower::{GenericArgsPosition, ImplTraitLoweringMode, diagnostics::TyLoweringDiagnostic}, + lower::{ImplTraitLoweringMode, LifetimeElisionKind, diagnostics::TyLoweringDiagnostic}, mir::MirSpan, - to_assoc_type_id, + static_lifetime, to_assoc_type_id, traits::FnTrait, utils::UnevaluatedConstEvaluatorFolder, }; @@ -96,7 +96,7 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<Infer DefWithBodyId::FunctionId(f) => { ctx.collect_fn(f); } - DefWithBodyId::ConstId(c) => ctx.collect_const(&db.const_signature(c)), + DefWithBodyId::ConstId(c) => ctx.collect_const(c, &db.const_signature(c)), DefWithBodyId::StaticId(s) => ctx.collect_static(&db.static_signature(s)), DefWithBodyId::VariantId(v) => { ctx.return_ty = TyBuilder::builtin( @@ -899,9 +899,13 @@ impl<'a> InferenceContext<'a> { result } - fn collect_const(&mut self, data: &ConstSignature) { - let return_ty = - self.make_ty(data.type_ref, &data.store, InferenceTyDiagnosticSource::Signature); + fn collect_const(&mut self, id: ConstId, data: &ConstSignature) { + let return_ty = self.make_ty( + data.type_ref, + &data.store, + InferenceTyDiagnosticSource::Signature, + LifetimeElisionKind::for_const(id.loc(self.db).container), + ); // Constants might be defining usage sites of TAITs. self.make_tait_coercion_table(iter::once(&return_ty)); @@ -910,8 +914,12 @@ impl<'a> InferenceContext<'a> { } fn collect_static(&mut self, data: &StaticSignature) { - let return_ty = - self.make_ty(data.type_ref, &data.store, InferenceTyDiagnosticSource::Signature); + let return_ty = self.make_ty( + data.type_ref, + &data.store, + InferenceTyDiagnosticSource::Signature, + LifetimeElisionKind::Elided(static_lifetime()), + ); // Statics might be defining usage sites of TAITs. self.make_tait_coercion_table(iter::once(&return_ty)); @@ -921,12 +929,15 @@ impl<'a> InferenceContext<'a> { fn collect_fn(&mut self, func: FunctionId) { let data = self.db.function_signature(func); - let mut param_tys = - self.with_ty_lowering(&data.store, InferenceTyDiagnosticSource::Signature, |ctx| { + let mut param_tys = self.with_ty_lowering( + &data.store, + InferenceTyDiagnosticSource::Signature, + LifetimeElisionKind::for_fn_params(&data), + |ctx| { ctx.type_param_mode(ParamLoweringMode::Placeholder); - ctx.in_fn_signature = true; data.params.iter().map(|&type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>() - }); + }, + ); // Check if function contains a va_list, if it does then we append it to the parameter types // that are collected from the function data @@ -967,10 +978,10 @@ impl<'a> InferenceContext<'a> { let return_ty = self.with_ty_lowering( &data.store, InferenceTyDiagnosticSource::Signature, + LifetimeElisionKind::for_fn_ret(), |ctx| { ctx.type_param_mode(ParamLoweringMode::Placeholder) .impl_trait_mode(ImplTraitLoweringMode::Opaque); - ctx.in_fn_signature = true; ctx.lower_ty(return_ty) }, ); @@ -1304,6 +1315,7 @@ impl<'a> InferenceContext<'a> { &mut self, store: &ExpressionStore, types_source: InferenceTyDiagnosticSource, + lifetime_elision: LifetimeElisionKind, f: impl FnOnce(&mut TyLoweringContext<'_>) -> R, ) -> R { let mut ctx = TyLoweringContext::new( @@ -1313,12 +1325,18 @@ impl<'a> InferenceContext<'a> { &self.diagnostics, types_source, self.generic_def, + lifetime_elision, ); f(&mut ctx) } fn with_body_ty_lowering<R>(&mut self, f: impl FnOnce(&mut TyLoweringContext<'_>) -> R) -> R { - self.with_ty_lowering(self.body, InferenceTyDiagnosticSource::Body, f) + self.with_ty_lowering( + self.body, + InferenceTyDiagnosticSource::Body, + LifetimeElisionKind::Infer, + f, + ) } fn make_ty( @@ -1326,29 +1344,46 @@ impl<'a> InferenceContext<'a> { type_ref: TypeRefId, store: &ExpressionStore, type_source: InferenceTyDiagnosticSource, + lifetime_elision: LifetimeElisionKind, ) -> Ty { - let ty = self.with_ty_lowering(store, type_source, |ctx| ctx.lower_ty(type_ref)); + let ty = self + .with_ty_lowering(store, type_source, lifetime_elision, |ctx| ctx.lower_ty(type_ref)); let ty = self.insert_type_vars(ty); self.normalize_associated_types_in(ty) } fn make_body_ty(&mut self, type_ref: TypeRefId) -> Ty { - self.make_ty(type_ref, self.body, InferenceTyDiagnosticSource::Body) + self.make_ty( + type_ref, + self.body, + InferenceTyDiagnosticSource::Body, + LifetimeElisionKind::Infer, + ) } fn make_body_const(&mut self, const_ref: ConstRef, ty: Ty) -> Const { - let const_ = self.with_ty_lowering(self.body, InferenceTyDiagnosticSource::Body, |ctx| { - ctx.type_param_mode = ParamLoweringMode::Placeholder; - ctx.lower_const(&const_ref, ty) - }); + let const_ = self.with_ty_lowering( + self.body, + InferenceTyDiagnosticSource::Body, + LifetimeElisionKind::Infer, + |ctx| { + ctx.type_param_mode = ParamLoweringMode::Placeholder; + ctx.lower_const(&const_ref, ty) + }, + ); self.insert_type_vars(const_) } fn make_path_as_body_const(&mut self, path: &Path, ty: Ty) -> Const { - let const_ = self.with_ty_lowering(self.body, InferenceTyDiagnosticSource::Body, |ctx| { - ctx.type_param_mode = ParamLoweringMode::Placeholder; - ctx.lower_path_as_const(path, ty) - }); + let const_ = self.with_ty_lowering( + self.body, + InferenceTyDiagnosticSource::Body, + LifetimeElisionKind::Infer, + |ctx| { + ctx.type_param_mode = ParamLoweringMode::Placeholder; + ctx.lower_path_as_const(path, ty) + }, + ); self.insert_type_vars(const_) } @@ -1357,9 +1392,12 @@ impl<'a> InferenceContext<'a> { } fn make_body_lifetime(&mut self, lifetime_ref: &LifetimeRef) -> Lifetime { - let lt = self.with_ty_lowering(self.body, InferenceTyDiagnosticSource::Body, |ctx| { - ctx.lower_lifetime(lifetime_ref) - }); + let lt = self.with_ty_lowering( + self.body, + InferenceTyDiagnosticSource::Body, + LifetimeElisionKind::Infer, + |ctx| ctx.lower_lifetime(lifetime_ref), + ); self.insert_type_vars(lt) } @@ -1529,8 +1567,9 @@ impl<'a> InferenceContext<'a> { &self.diagnostics, InferenceTyDiagnosticSource::Body, self.generic_def, + LifetimeElisionKind::Infer, ); - let mut path_ctx = ctx.at_path(path, node, GenericArgsPosition::Value); + let mut path_ctx = ctx.at_path(path, node); let (resolution, unresolved) = if value_ns { let Some(res) = path_ctx.resolve_path_in_value_ns(HygieneId::ROOT) else { return (self.err_ty(), None); @@ -1538,14 +1577,14 @@ impl<'a> InferenceContext<'a> { match res { ResolveValueResult::ValueNs(value, _) => match value { ValueNs::EnumVariantId(var) => { - let substs = path_ctx.substs_from_path(var.into(), true); + let substs = path_ctx.substs_from_path(var.into(), true, false); drop(ctx); let ty = self.db.ty(var.lookup(self.db).parent.into()); let ty = self.insert_type_vars(ty.substitute(Interner, &substs)); return (ty, Some(var.into())); } ValueNs::StructId(strukt) => { - let substs = path_ctx.substs_from_path(strukt.into(), true); + let substs = path_ctx.substs_from_path(strukt.into(), true, false); drop(ctx); let ty = self.db.ty(strukt.into()); let ty = self.insert_type_vars(ty.substitute(Interner, &substs)); @@ -1567,21 +1606,21 @@ impl<'a> InferenceContext<'a> { }; return match resolution { TypeNs::AdtId(AdtId::StructId(strukt)) => { - let substs = path_ctx.substs_from_path(strukt.into(), true); + let substs = path_ctx.substs_from_path(strukt.into(), true, false); drop(ctx); let ty = self.db.ty(strukt.into()); let ty = self.insert_type_vars(ty.substitute(Interner, &substs)); forbid_unresolved_segments((ty, Some(strukt.into())), unresolved) } TypeNs::AdtId(AdtId::UnionId(u)) => { - let substs = path_ctx.substs_from_path(u.into(), true); + let substs = path_ctx.substs_from_path(u.into(), true, false); drop(ctx); let ty = self.db.ty(u.into()); let ty = self.insert_type_vars(ty.substitute(Interner, &substs)); forbid_unresolved_segments((ty, Some(u.into())), unresolved) } TypeNs::EnumVariantId(var) => { - let substs = path_ctx.substs_from_path(var.into(), true); + let substs = path_ctx.substs_from_path(var.into(), true, false); drop(ctx); let ty = self.db.ty(var.lookup(self.db).parent.into()); let ty = self.insert_type_vars(ty.substitute(Interner, &substs)); @@ -1665,7 +1704,7 @@ impl<'a> InferenceContext<'a> { never!("resolver should always resolve lang item paths"); return (self.err_ty(), None); }; - let substs = path_ctx.substs_from_path_segment(it.into(), true, None); + let substs = path_ctx.substs_from_path_segment(it.into(), true, None, false); drop(ctx); let ty = self.db.ty(it.into()); let ty = self.insert_type_vars(ty.substitute(Interner, &substs)); |