diff options
Diffstat (limited to 'src/tools/rust-analyzer/crates/hir-ty/src/infer.rs')
| -rw-r--r-- | src/tools/rust-analyzer/crates/hir-ty/src/infer.rs | 333 |
1 files changed, 205 insertions, 128 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index 3e0ce7f1933..790914fdaf2 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -26,27 +26,26 @@ pub(crate) mod unify; use std::{cell::OnceCell, convert::identity, iter, ops::Index}; use chalk_ir::{ + DebruijnIndex, Mutability, Safety, Scalar, TyKind, TypeFlags, Variance, cast::Cast, fold::TypeFoldable, interner::HasInterner, visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}, - DebruijnIndex, Mutability, Safety, Scalar, TyKind, TypeFlags, Variance, }; use either::Either; use hir_def::{ + AdtId, AssocItemId, ConstId, DefWithBodyId, FieldId, FunctionId, GenericDefId, GenericParamId, + ImplId, ItemContainerId, Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId, VariantId, builtin_type::{BuiltinInt, BuiltinType, BuiltinUint}, - data::{ConstData, StaticData}, - expr_store::{Body, HygieneId}, + expr_store::{Body, ExpressionStore, HygieneId, path::Path}, hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId}, lang_item::{LangItem, LangItemTarget}, layout::Integer, - path::{ModPath, Path}, resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs}, - type_ref::{LifetimeRef, TypeRefId, TypesMap}, - AdtId, AssocItemId, DefWithBodyId, FieldId, FunctionId, ImplId, ItemContainerId, Lookup, - TraitId, TupleFieldId, TupleId, TypeAliasId, VariantId, + signatures::{ConstSignature, StaticSignature}, + type_ref::{ConstRef, LifetimeRefId, TypeRefId}, }; -use hir_expand::name::Name; +use hir_expand::{mod_path::ModPath, name::Name}; use indexmap::IndexSet; use intern::sym; use la_arena::{ArenaMap, Entry}; @@ -55,6 +54,10 @@ use stdx::{always, never}; use triomphe::Arc; use crate::{ + AliasEq, AliasTy, Binders, ClosureId, Const, DomainGoal, GenericArg, Goal, ImplTraitId, + ImplTraitIdx, InEnvironment, IncorrectGenericsLenKind, Interner, Lifetime, OpaqueTyId, + ParamLoweringMode, PathLoweringDiagnostic, ProjectionTy, Substitution, TraitEnvironment, Ty, + TyBuilder, TyExt, db::HirDatabase, fold_tys, generics::Generics, @@ -64,14 +67,11 @@ use crate::{ expr::ExprIsRead, unify::InferenceTable, }, - lower::{diagnostics::TyLoweringDiagnostic, ImplTraitLoweringMode}, + lower::{ImplTraitLoweringMode, LifetimeElisionKind, diagnostics::TyLoweringDiagnostic}, mir::MirSpan, - to_assoc_type_id, + static_lifetime, to_assoc_type_id, traits::FnTrait, - utils::{InTypeConstIdMetadata, UnevaluatedConstEvaluatorFolder}, - AliasEq, AliasTy, Binders, ClosureId, Const, DomainGoal, GenericArg, Goal, ImplTraitId, - ImplTraitIdx, InEnvironment, Interner, Lifetime, OpaqueTyId, ParamLoweringMode, - PathLoweringDiagnostic, ProjectionTy, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt, + utils::UnevaluatedConstEvaluatorFolder, }; // This lint has a false positive here. See the link below for details. @@ -88,7 +88,7 @@ pub(crate) use closure::{CaptureKind, CapturedItem, CapturedItemWithoutTy}; /// The entry point of type inference. pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> { let _p = tracing::info_span!("infer_query").entered(); - let resolver = def.resolver(db.upcast()); + let resolver = def.resolver(db); let body = db.body(def); let mut ctx = InferenceContext::new(db, def, &body, resolver); @@ -96,11 +96,11 @@ 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_data(c)), - DefWithBodyId::StaticId(s) => ctx.collect_static(&db.static_data(s)), + 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( - match db.enum_data(v.lookup(db.upcast()).parent).variant_body_type() { + match db.enum_signature(v.lookup(db).parent).variant_body_type() { hir_def::layout::IntegerType::Pointer(signed) => match signed { true => BuiltinType::Int(BuiltinInt::Isize), false => BuiltinType::Uint(BuiltinUint::Usize), @@ -124,16 +124,6 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<Infer }, ); } - DefWithBodyId::InTypeConstId(c) => { - // FIXME(const-generic-body): We should not get the return type in this way. - ctx.return_ty = c - .lookup(db.upcast()) - .expected_ty - .box_any() - .downcast::<InTypeConstIdMetadata>() - .unwrap() - .0; - } } ctx.infer_body(); @@ -286,6 +276,20 @@ pub enum InferenceDiagnostic { node: ExprOrPatId, diag: PathLoweringDiagnostic, }, + MethodCallIncorrectGenericsLen { + expr: ExprId, + provided_count: u32, + expected_count: u32, + kind: IncorrectGenericsLenKind, + def: GenericDefId, + }, + MethodCallIncorrectGenericsOrder { + expr: ExprId, + param_id: GenericParamId, + arg_idx: u32, + /// Whether the `GenericArgs` contains a `Self` arg. + has_self_arg: bool, + }, } /// A mismatch between an expected and an inferred type. @@ -489,7 +493,7 @@ pub struct InferenceResult { /// ``` /// the first `rest` has implicit `ref` binding mode, but the second `rest` binding mode is `move`. pub binding_modes: ArenaMap<PatId, BindingMode>, - pub expr_adjustments: FxHashMap<ExprId, Vec<Adjustment>>, + pub expr_adjustments: FxHashMap<ExprId, Box<[Adjustment]>>, pub(crate) closure_info: FxHashMap<ClosureId, (Vec<CapturedItem>, FnTrait)>, // FIXME: remove this field pub mutated_bindings_in_closure: FxHashSet<BindingId>, @@ -597,7 +601,8 @@ pub(crate) struct InferenceContext<'a> { /// Generally you should not resolve things via this resolver. Instead create a TyLoweringContext /// and resolve the path via its methods. This will ensure proper error reporting. pub(crate) resolver: Resolver, - generics: OnceCell<Option<Generics>>, + generic_def: GenericDefId, + generics: OnceCell<Generics>, table: unify::InferenceTable<'a>, /// The traits in scope, disregarding block modules. This is used for caching purposes. traits_in_scope: FxHashSet<TraitId>, @@ -708,8 +713,14 @@ impl<'a> InferenceContext<'a> { return_coercion: None, db, owner, + generic_def: match owner { + DefWithBodyId::FunctionId(it) => it.into(), + DefWithBodyId::StaticId(it) => it.into(), + DefWithBodyId::ConstId(it) => it.into(), + DefWithBodyId::VariantId(it) => it.lookup(db).parent.into(), + }, body, - traits_in_scope: resolver.traits_in_scope(db.upcast()), + traits_in_scope: resolver.traits_in_scope(db), resolver, diverges: Diverges::Maybe, breakables: Vec::new(), @@ -724,14 +735,8 @@ impl<'a> InferenceContext<'a> { } } - pub(crate) fn generics(&self) -> Option<&Generics> { - self.generics - .get_or_init(|| { - self.resolver - .generic_def() - .map(|def| crate::generics::generics(self.db.upcast(), def)) - }) - .as_ref() + pub(crate) fn generics(&self) -> &Generics { + self.generics.get_or_init(|| crate::generics::generics(self.db, self.generic_def)) } // FIXME: This function should be private in module. It is currently only used in the consteval, since we need @@ -780,8 +785,8 @@ impl<'a> InferenceContext<'a> { // Comment from rustc: // Even though coercion casts provide type hints, we check casts after fallback for // backwards compatibility. This makes fallback a stronger type hint than a cast coercion. - let mut apply_adjustments = |expr, adj| { - expr_adjustments.insert(expr, adj); + let mut apply_adjustments = |expr, adj: Vec<_>| { + expr_adjustments.insert(expr, adj.into_boxed_slice()); }; let mut set_coercion_cast = |expr| { coercion_casts.insert(expr); @@ -803,22 +808,27 @@ impl<'a> InferenceContext<'a> { *ty = table.resolve_completely(ty.clone()); *has_errors = *has_errors || ty.contains_unknown(); } + type_of_expr.shrink_to_fit(); for ty in type_of_pat.values_mut() { *ty = table.resolve_completely(ty.clone()); *has_errors = *has_errors || ty.contains_unknown(); } + type_of_pat.shrink_to_fit(); for ty in type_of_binding.values_mut() { *ty = table.resolve_completely(ty.clone()); *has_errors = *has_errors || ty.contains_unknown(); } + type_of_binding.shrink_to_fit(); for ty in type_of_rpit.values_mut() { *ty = table.resolve_completely(ty.clone()); *has_errors = *has_errors || ty.contains_unknown(); } + type_of_rpit.shrink_to_fit(); for ty in type_of_for_iterator.values_mut() { *ty = table.resolve_completely(ty.clone()); *has_errors = *has_errors || ty.contains_unknown(); } + type_of_for_iterator.shrink_to_fit(); *has_errors |= !type_mismatches.is_empty(); @@ -833,6 +843,7 @@ impl<'a> InferenceContext<'a> { ) .is_ok() }); + type_mismatches.shrink_to_fit(); diagnostics.retain_mut(|diagnostic| { use InferenceDiagnostic::*; match diagnostic { @@ -861,24 +872,29 @@ impl<'a> InferenceContext<'a> { } true }); + diagnostics.shrink_to_fit(); for (_, subst) in method_resolutions.values_mut() { *subst = table.resolve_completely(subst.clone()); *has_errors = *has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown()); } + method_resolutions.shrink_to_fit(); for (_, subst) in assoc_resolutions.values_mut() { *subst = table.resolve_completely(subst.clone()); *has_errors = *has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown()); } + assoc_resolutions.shrink_to_fit(); for adjustment in expr_adjustments.values_mut().flatten() { adjustment.target = table.resolve_completely(adjustment.target.clone()); *has_errors = *has_errors || adjustment.target.contains_unknown(); } + expr_adjustments.shrink_to_fit(); for adjustment in pat_adjustments.values_mut().flatten() { *adjustment = table.resolve_completely(adjustment.clone()); *has_errors = *has_errors || adjustment.contains_unknown(); } + pat_adjustments.shrink_to_fit(); result.tuple_field_access_types = tuple_field_accesses_rev .into_iter() .enumerate() @@ -888,15 +904,20 @@ impl<'a> InferenceContext<'a> { *has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown()); }) .collect(); + result.tuple_field_access_types.shrink_to_fit(); result.diagnostics = diagnostics; result } - fn collect_const(&mut self, data: &ConstData) { - let return_ty = - self.make_ty(data.type_ref, &data.types_map, 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)); @@ -904,9 +925,13 @@ impl<'a> InferenceContext<'a> { self.return_ty = return_ty; } - fn collect_static(&mut self, data: &StaticData) { - let return_ty = - self.make_ty(data.type_ref, &data.types_map, InferenceTyDiagnosticSource::Signature); + fn collect_static(&mut self, data: &StaticSignature) { + 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)); @@ -915,13 +940,17 @@ impl<'a> InferenceContext<'a> { } fn collect_fn(&mut self, func: FunctionId) { - let data = self.db.function_data(func); - let mut param_tys = - self.with_ty_lowering(&data.types_map, InferenceTyDiagnosticSource::Signature, |ctx| { - ctx.type_param_mode(ParamLoweringMode::Placeholder) - .impl_trait_mode(ImplTraitLoweringMode::Param); + let data = self.db.function_signature(func); + let mut param_tys = self.with_ty_lowering( + &data.store, + InferenceTyDiagnosticSource::Signature, + LifetimeElisionKind::for_fn_params(&data), + |ctx| { + ctx.type_param_mode(ParamLoweringMode::Placeholder); 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 if data.is_varargs() { @@ -956,35 +985,44 @@ impl<'a> InferenceContext<'a> { tait_candidates.insert(ty); } } - let return_ty = data.ret_type; - - let return_ty = - self.with_ty_lowering(&data.types_map, InferenceTyDiagnosticSource::Signature, |ctx| { - ctx.type_param_mode(ParamLoweringMode::Placeholder) - .impl_trait_mode(ImplTraitLoweringMode::Opaque) - .lower_ty(return_ty) - }); - let return_ty = self.insert_type_vars(return_ty); - - let return_ty = if let Some(rpits) = self.db.return_type_impl_traits(func) { - // RPIT opaque types use substitution of their parent function. - let fn_placeholders = TyBuilder::placeholder_subst(self.db, func); - let mut mode = ImplTraitReplacingMode::ReturnPosition(FxHashSet::default()); - let result = - self.insert_inference_vars_for_impl_trait(return_ty, fn_placeholders, &mut mode); - if let ImplTraitReplacingMode::ReturnPosition(taits) = mode { - tait_candidates.extend(taits); - } - let rpits = rpits.skip_binders(); - for (id, _) in rpits.impl_traits.iter() { - if let Entry::Vacant(e) = self.result.type_of_rpit.entry(id) { - never!("Missed RPIT in `insert_inference_vars_for_rpit`"); - e.insert(TyKind::Error.intern(Interner)); + let return_ty = match data.ret_type { + Some(return_ty) => { + 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.lower_ty(return_ty) + }, + ); + let return_ty = self.insert_type_vars(return_ty); + if let Some(rpits) = self.db.return_type_impl_traits(func) { + // RPIT opaque types use substitution of their parent function. + let fn_placeholders = TyBuilder::placeholder_subst(self.db, func); + let mut mode = ImplTraitReplacingMode::ReturnPosition(FxHashSet::default()); + let result = self.insert_inference_vars_for_impl_trait( + return_ty, + fn_placeholders, + &mut mode, + ); + if let ImplTraitReplacingMode::ReturnPosition(taits) = mode { + tait_candidates.extend(taits); + } + let rpits = rpits.skip_binders(); + for (id, _) in rpits.impl_traits.iter() { + if let Entry::Vacant(e) = self.result.type_of_rpit.entry(id) { + never!("Missed RPIT in `insert_inference_vars_for_rpit`"); + e.insert(TyKind::Error.intern(Interner)); + } + } + result + } else { + return_ty } } - result - } else { - return_ty + None => self.result.standard_types.unit.clone(), }; self.return_ty = self.normalize_associated_types_in(return_ty); @@ -1143,7 +1181,7 @@ impl<'a> InferenceContext<'a> { non_assocs: FxHashMap::default(), }; for ty in tait_candidates { - let _ = ty.visit_with(collector.as_dyn(), DebruijnIndex::INNERMOST); + _ = ty.visit_with(collector.as_dyn(), DebruijnIndex::INNERMOST); } // Non-assoc TAITs can be define-used everywhere as long as they are @@ -1190,11 +1228,7 @@ impl<'a> InferenceContext<'a> { if let Some(impl_id) = impl_id { taits.extend(collector.assocs.into_iter().filter_map(|(id, (impl_, ty))| { - if impl_ == impl_id { - Some((id, ty)) - } else { - None - } + if impl_ == impl_id { Some((id, ty)) } else { None } })); } @@ -1239,7 +1273,7 @@ impl<'a> InferenceContext<'a> { self.result.type_of_expr.insert(expr, ty); } - fn write_expr_adj(&mut self, expr: ExprId, adjustments: Vec<Adjustment>) { + fn write_expr_adj(&mut self, expr: ExprId, adjustments: Box<[Adjustment]>) { if adjustments.is_empty() { return; } @@ -1291,48 +1325,91 @@ impl<'a> InferenceContext<'a> { fn with_ty_lowering<R>( &mut self, - types_map: &TypesMap, + store: &ExpressionStore, types_source: InferenceTyDiagnosticSource, + lifetime_elision: LifetimeElisionKind, f: impl FnOnce(&mut TyLoweringContext<'_>) -> R, ) -> R { let mut ctx = TyLoweringContext::new( self.db, &self.resolver, - types_map, - self.owner.into(), + store, &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.types, InferenceTyDiagnosticSource::Body, f) + self.with_ty_lowering( + self.body, + InferenceTyDiagnosticSource::Body, + LifetimeElisionKind::Infer, + f, + ) } fn make_ty( &mut self, type_ref: TypeRefId, - types_map: &TypesMap, + store: &ExpressionStore, type_source: InferenceTyDiagnosticSource, + lifetime_elision: LifetimeElisionKind, ) -> Ty { - let ty = self.with_ty_lowering(types_map, 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.types, 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, + 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, + LifetimeElisionKind::Infer, + |ctx| { + ctx.type_param_mode = ParamLoweringMode::Placeholder; + ctx.lower_path_as_const(path, ty) + }, + ); + self.insert_type_vars(const_) } fn err_ty(&self) -> Ty { self.result.standard_types.unknown.clone() } - fn make_body_lifetime(&mut self, lifetime_ref: &LifetimeRef) -> Lifetime { - let lt = self.with_ty_lowering(TypesMap::EMPTY, InferenceTyDiagnosticSource::Body, |ctx| { - ctx.lower_lifetime(lifetime_ref) - }); + fn make_body_lifetime(&mut self, lifetime_ref: LifetimeRefId) -> Lifetime { + let lt = self.with_ty_lowering( + self.body, + InferenceTyDiagnosticSource::Body, + LifetimeElisionKind::Infer, + |ctx| ctx.lower_lifetime(lifetime_ref), + ); self.insert_type_vars(lt) } @@ -1460,7 +1537,7 @@ impl<'a> InferenceContext<'a> { ) -> Ty { match assoc_ty { Some(res_assoc_ty) => { - let trait_ = match res_assoc_ty.lookup(self.db.upcast()).container { + let trait_ = match res_assoc_ty.lookup(self.db).container { hir_def::ItemContainerId::TraitId(trait_) => trait_, _ => panic!("resolve_associated_type called with non-associated type"), }; @@ -1498,10 +1575,11 @@ impl<'a> InferenceContext<'a> { let mut ctx = TyLoweringContext::new( self.db, &self.resolver, - &self.body.types, - self.owner.into(), + &self.body.store, &self.diagnostics, InferenceTyDiagnosticSource::Body, + self.generic_def, + LifetimeElisionKind::Infer, ); let mut path_ctx = ctx.at_path(path, node); let (resolution, unresolved) = if value_ns { @@ -1511,14 +1589,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.upcast()).parent.into()); + 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)); @@ -1538,39 +1616,39 @@ impl<'a> InferenceContext<'a> { None => return (self.err_ty(), None), } }; - let Some(mod_path) = path.mod_path() else { - never!("resolver should always resolve lang item paths"); - return (self.err_ty(), None); - }; 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.upcast()).parent.into()); + let ty = self.db.ty(var.lookup(self.db).parent.into()); let ty = self.insert_type_vars(ty.substitute(Interner, &substs)); forbid_unresolved_segments((ty, Some(var.into())), unresolved) } TypeNs::SelfType(impl_id) => { - let generics = crate::generics::generics(self.db.upcast(), impl_id.into()); + let generics = crate::generics::generics(self.db, impl_id.into()); let substs = generics.placeholder_subst(self.db); let mut ty = self.db.impl_self_ty(impl_id).substitute(Interner, &substs); let Some(remaining_idx) = unresolved else { drop(ctx); + let Some(mod_path) = path.mod_path() else { + never!("resolver should always resolve lang item paths"); + return (self.err_ty(), None); + }; return self.resolve_variant_on_alias(ty, None, mod_path); }; @@ -1587,7 +1665,7 @@ impl<'a> InferenceContext<'a> { // If we can resolve to an enum variant, it takes priority over associated type // of the same name. if let Some((AdtId::EnumId(id), _)) = ty.as_adt() { - let enum_data = self.db.enum_data(id); + let enum_data = self.db.enum_variants(id); if let Some(variant) = enum_data.variant(current_segment.name) { return if remaining_segments.len() == 1 { (ty, Some(variant.into())) @@ -1609,7 +1687,7 @@ impl<'a> InferenceContext<'a> { // `lower_partly_resolved_path()` returns `None` as type namespace unless // `remaining_segments` is empty, which is never the case here. We don't know // which namespace the new `ty` is in until normalized anyway. - (ty, _) = path_ctx.lower_partly_resolved_path(resolution, false); + (ty, _) = path_ctx.lower_partly_resolved_path(resolution, true); tried_resolving_once = true; ty = self.table.insert_type_vars(ty); @@ -1634,7 +1712,11 @@ impl<'a> InferenceContext<'a> { (ty, variant) } TypeNs::TypeAliasId(it) => { - let substs = path_ctx.substs_from_path_segment(it.into(), true, None); + let Some(mod_path) = path.mod_path() else { + 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, false); drop(ctx); let ty = self.db.ty(it.into()); let ty = self.insert_type_vars(ty.substitute(Interner, &substs)); @@ -1652,7 +1734,8 @@ impl<'a> InferenceContext<'a> { TypeNs::AdtId(AdtId::EnumId(_)) | TypeNs::BuiltinType(_) | TypeNs::TraitId(_) - | TypeNs::TraitAliasId(_) => { + | TypeNs::TraitAliasId(_) + | TypeNs::ModuleId(_) => { // FIXME diagnostic (self.err_ty(), None) } @@ -1701,7 +1784,7 @@ impl<'a> InferenceContext<'a> { let segment = path.segments().last().unwrap(); // this could be an enum variant or associated type if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() { - let enum_data = self.db.enum_data(enum_id); + let enum_data = self.db.enum_variants(enum_id); if let Some(variant) = enum_data.variant(segment) { return (ty, Some(variant.into())); } @@ -1722,9 +1805,7 @@ impl<'a> InferenceContext<'a> { } fn resolve_output_on(&self, trait_: TraitId) -> Option<TypeAliasId> { - self.db - .trait_data(trait_) - .associated_type_by_name(&Name::new_symbol_root(sym::Output.clone())) + self.db.trait_items(trait_).associated_type_by_name(&Name::new_symbol_root(sym::Output)) } fn resolve_lang_trait(&self, lang: LangItem) -> Option<TraitId> { @@ -1743,7 +1824,7 @@ impl<'a> InferenceContext<'a> { let ItemContainerId::TraitId(trait_) = self .resolve_lang_item(LangItem::IntoFutureIntoFuture)? .as_function()? - .lookup(self.db.upcast()) + .lookup(self.db) .container else { return None; @@ -1914,11 +1995,7 @@ impl Expectation { match self { Expectation::HasType(ety) => { let ety = table.resolve_ty_shallow(ety); - if ety.is_ty_var() { - Expectation::None - } else { - Expectation::HasType(ety) - } + if ety.is_ty_var() { Expectation::None } else { Expectation::HasType(ety) } } Expectation::RValueLikeUnsized(ety) => Expectation::RValueLikeUnsized(ety.clone()), _ => Expectation::None, @@ -2044,7 +2121,7 @@ impl chalk_ir::zip::Zipper<Interner> for UnknownMismatch<'_> { | (_, TyKind::Error) | (TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(_, _), _) | (_, TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(_, _)) => { - return Err(chalk_ir::NoSolution) + return Err(chalk_ir::NoSolution); } _ => (), } |
