Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/lower/path.rs')
| -rw-r--r-- | crates/hir-ty/src/lower/path.rs | 118 |
1 files changed, 94 insertions, 24 deletions
diff --git a/crates/hir-ty/src/lower/path.rs b/crates/hir-ty/src/lower/path.rs index 1e7e56ab88..0757d57500 100644 --- a/crates/hir-ty/src/lower/path.rs +++ b/crates/hir-ty/src/lower/path.rs @@ -25,9 +25,10 @@ use smallvec::SmallVec; use crate::{ GenericArgsProhibitedReason, IncorrectGenericsLenKind, PathGenericsSource, - PathLoweringDiagnostic, TyDefId, ValueTyDefId, + PathLoweringDiagnostic, Span, TyDefId, ValueTyDefId, db::HirDatabase, generics::{Generics, generics}, + infer::unify::InferenceTable, lower::{ AssocTypeShorthandResolution, ForbidParamsAfterReason, GenericPredicateSource, LifetimeElisionKind, PathDiagnosticCallbackData, const_param_ty, @@ -83,6 +84,11 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { } } + #[track_caller] + pub(crate) fn expect_table(&mut self) -> &mut InferenceTable<'db> { + self.ctx.expect_table() + } + #[inline] #[cold] fn on_diagnostic(&mut self, diag: PathLoweringDiagnostic) { @@ -148,13 +154,14 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { // We need the original resolution to lower `Self::AssocTy` correctly res: Option<TypeNs>, infer_args: bool, + span: Span, ) -> (Ty<'db>, Option<TypeNs>) { let remaining_segments = self.segments.len() - self.current_segment_idx; match remaining_segments { 0 => (ty, res), 1 => { // resolve unselected assoc types - (self.select_associated_type(res, infer_args), None) + (self.select_associated_type(res, infer_args, span), None) } _ => { // FIXME report error (ambiguous associated type) @@ -168,6 +175,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { &mut self, resolution: TypeNs, infer_args: bool, + span: Span, ) -> (Ty<'db>, Option<TypeNs>) { let remaining_segments = self.segments.skip(self.current_segment_idx + 1); tracing::debug!(?remaining_segments); @@ -182,6 +190,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { trait_, self.ctx.types.types.error, infer_args, + span, ); tracing::debug!(?trait_ref); self.skip_resolved_segment(); @@ -202,6 +211,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { infer_args, None, true, + span, ); let args = GenericArgs::new_from_iter( self.ctx.interner, @@ -249,9 +259,9 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { Ty::new_adt(self.ctx.interner, adt, args) } - TypeNs::AdtId(it) => self.lower_path_inner(it.into(), infer_args), - TypeNs::BuiltinType(it) => self.lower_path_inner(it.into(), infer_args), - TypeNs::TypeAliasId(it) => self.lower_path_inner(it.into(), infer_args), + TypeNs::AdtId(it) => self.lower_path_inner(it.into(), infer_args, span), + TypeNs::BuiltinType(it) => self.lower_path_inner(it.into(), infer_args, span), + TypeNs::TypeAliasId(it) => self.lower_path_inner(it.into(), infer_args, span), // FIXME: report error TypeNs::EnumVariantId(_) | TypeNs::ModuleId(_) => { return (self.ctx.types.types.error, None); @@ -261,7 +271,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { tracing::debug!(?ty); self.skip_resolved_segment(); - self.lower_ty_relative_path(ty, Some(resolution), infer_args) + self.lower_ty_relative_path(ty, Some(resolution), infer_args, span) } /// This returns whether to keep the resolution (`true`) of throw it (`false`). @@ -469,7 +479,12 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { } #[tracing::instrument(skip(self), ret)] - fn select_associated_type(&mut self, res: Option<TypeNs>, infer_args: bool) -> Ty<'db> { + fn select_associated_type( + &mut self, + res: Option<TypeNs>, + infer_args: bool, + span: Span, + ) -> Ty<'db> { let interner = self.ctx.interner; let db = self.ctx.db; let def = self.ctx.generic_def; @@ -526,7 +541,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { // generic params. It's inefficient to splice the `Substitution`s, so we may want // that method to optionally take parent `Substitution` as we already know them at // this point (`t.substitution`). - let substs = self.substs_from_path_segment(assoc_type.into(), infer_args, None, true); + let substs = self.substs_from_path_segment(assoc_type.into(), infer_args, None, true, span); let substs = GenericArgs::new_from_iter( interner, @@ -536,7 +551,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { Ty::new_projection_from_args(interner, assoc_type.into(), substs) } - fn lower_path_inner(&mut self, typeable: TyDefId, infer_args: bool) -> Ty<'db> { + fn lower_path_inner(&mut self, typeable: TyDefId, infer_args: bool, span: Span) -> Ty<'db> { let generic_def = match typeable { TyDefId::BuiltinType(builtinty) => { return Ty::from_builtin_type(self.ctx.interner, builtinty); @@ -544,7 +559,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { TyDefId::AdtId(it) => it.into(), TyDefId::TypeAliasId(it) => it.into(), }; - let args = self.substs_from_path_segment(generic_def, infer_args, None, false); + let args = self.substs_from_path_segment(generic_def, infer_args, None, false, span); let ty = ty_query(self.ctx.db, typeable); ty.instantiate(self.ctx.interner, args).skip_norm_wip() } @@ -559,6 +574,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { resolved: ValueTyDefId, infer_args: bool, lowering_assoc_type_generics: bool, + span: Span, ) -> GenericArgs<'db> { let interner = self.ctx.interner; let prev_current_segment_idx = self.current_segment_idx; @@ -602,6 +618,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { infer_args, None, lowering_assoc_type_generics, + span, ); self.current_segment_idx = prev_current_segment_idx; self.current_or_prev_segment = prev_current_segment; @@ -614,6 +631,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { infer_args: bool, explicit_self_ty: Option<Ty<'db>>, lowering_assoc_type_generics: bool, + span: Span, ) -> GenericArgs<'db> { let old_lifetime_elision = self.ctx.lifetime_elision; @@ -654,6 +672,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { PathGenericsSource::Segment(self.current_segment_u32()), lowering_assoc_type_generics, self.ctx.lifetime_elision, + span, ); self.ctx.lifetime_elision = old_lifetime_elision; result @@ -668,10 +687,12 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { generics_source: PathGenericsSource, lowering_assoc_type_generics: bool, lifetime_elision: LifetimeElisionKind<'db>, + span: Span, ) -> GenericArgs<'db> { struct LowererCtx<'a, 'b, 'c, 'db> { ctx: &'a mut PathLoweringContext<'b, 'c, 'db>, generics_source: PathGenericsSource, + span: Span, } impl<'db> GenericArgsLowerer<'db> for LowererCtx<'_, '_, '_, 'db> { @@ -734,13 +755,13 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { fn provided_type_like_const( &mut self, - _type_ref: TypeRefId, + type_ref: TypeRefId, const_ty: Ty<'db>, arg: TypeLikeConst<'_>, ) -> Const<'db> { match arg { TypeLikeConst::Path(path) => self.ctx.ctx.lower_path_as_const(path, const_ty), - TypeLikeConst::Infer => self.ctx.ctx.types.consts.error, + TypeLikeConst::Infer => self.ctx.ctx.next_const_var(type_ref.into()), } } @@ -751,15 +772,18 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { param: GenericParamDataRef<'_>, infer_args: bool, preceding_args: &[GenericArg<'db>], + had_count_error: bool, ) -> GenericArg<'db> { let default = || { self.ctx.ctx.db.generic_defaults(def).get(preceding_args.len()).map(|default| { default.instantiate(self.ctx.ctx.interner, preceding_args).skip_norm_wip() }) }; + // If `!infer_args`, we've already emitted an error, so put a dummy span. + let span = if !infer_args || had_count_error { Span::Dummy } else { self.span }; match param { GenericParamDataRef::LifetimeParamData(_) => { - self.ctx.ctx.types.regions.error.into() + self.ctx.ctx.next_region_var(span).into() } GenericParamDataRef::TypeParamData(param) => { if !infer_args @@ -768,7 +792,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { { return default; } - Ty::new_error(self.ctx.ctx.interner, ErrorGuaranteed).into() + self.ctx.ctx.next_ty_var_no_placeholder(span).into() } GenericParamDataRef::ConstParamData(param) => { if !infer_args @@ -780,7 +804,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { let GenericParamId::ConstParamId(_) = param_id else { unreachable!("non-const param ID for const param"); }; - self.ctx.ctx.types.consts.error.into() + self.ctx.ctx.next_const_var(span).into() } } } @@ -835,7 +859,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { lifetime_elision, lowering_assoc_type_generics, explicit_self_ty, - &mut LowererCtx { ctx: self, generics_source }, + &mut LowererCtx { ctx: self, generics_source, span }, ) } @@ -844,8 +868,9 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { resolved: TraitId, explicit_self_ty: Ty<'db>, infer_args: bool, + span: Span, ) -> TraitRef<'db> { - let args = self.trait_ref_substs_from_path(resolved, explicit_self_ty, infer_args); + let args = self.trait_ref_substs_from_path(resolved, explicit_self_ty, infer_args, span); TraitRef::new_from_args(self.ctx.interner, resolved.into(), args) } @@ -854,13 +879,21 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { resolved: TraitId, explicit_self_ty: Ty<'db>, infer_args: bool, + span: Span, ) -> GenericArgs<'db> { - self.substs_from_path_segment(resolved.into(), infer_args, Some(explicit_self_ty), false) + self.substs_from_path_segment( + resolved.into(), + infer_args, + Some(explicit_self_ty), + false, + span, + ) } pub(super) fn assoc_type_bindings_from_type_bound<'c>( mut self, trait_ref: TraitRef<'db>, + span: Span, ) -> Option<impl Iterator<Item = (Clause<'db>, GenericPredicateSource)> + use<'a, 'b, 'c, 'db>> { let interner = self.ctx.interner; @@ -892,6 +925,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { }, false, this.ctx.lifetime_elision, + span, ) }); let args = GenericArgs::new_from_iter( @@ -1011,6 +1045,7 @@ pub(crate) trait GenericArgsLowerer<'db> { param: GenericParamDataRef<'_>, infer_args: bool, preceding_args: &[GenericArg<'db>], + had_count_error: bool, ) -> GenericArg<'db>; fn parent_arg(&mut self, param_idx: u32, param_id: GenericParamId) -> GenericArg<'db>; @@ -1179,7 +1214,14 @@ pub(crate) fn substs_from_args_and_bindings<'db>( ctx.provided_kind(self_param_id, self_param, self_ty) } else { explicit_self_ty.map(|it| it.into()).unwrap_or_else(|| { - ctx.inferred_kind(def, self_param_id, self_param, infer_args, &substs) + ctx.inferred_kind( + def, + self_param_id, + self_param, + infer_args, + &substs, + had_count_error, + ) }) }; params.next(); @@ -1198,7 +1240,14 @@ pub(crate) fn substs_from_args_and_bindings<'db>( { // Do not allow specifying `impl Trait` explicitly. We already err at that, but if we won't handle it here // we will handle it as if it was specified, instead of inferring it. - substs.push(ctx.inferred_kind(def, param_id, param, infer_args, &substs)); + substs.push(ctx.inferred_kind( + def, + param_id, + param, + infer_args, + &substs, + had_count_error, + )); params.next(); } (HirGenericArg::Lifetime(_), GenericParamDataRef::LifetimeParamData(_)) @@ -1214,7 +1263,14 @@ pub(crate) fn substs_from_args_and_bindings<'db>( ) => { // We expected a lifetime argument, but got a type or const // argument. That means we're inferring the lifetime. - substs.push(ctx.inferred_kind(def, param_id, param, infer_args, &substs)); + substs.push(ctx.inferred_kind( + def, + param_id, + param, + infer_args, + &substs, + had_count_error, + )); params.next(); force_infer_lt = Some((arg_idx as u32, param_id)); } @@ -1283,7 +1339,14 @@ pub(crate) fn substs_from_args_and_bindings<'db>( | LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true } | LifetimeElisionKind::AnonymousReportError => { assert!(had_count_error); - ctx.inferred_kind(def, param_id, param, infer_args, &substs) + ctx.inferred_kind( + def, + param_id, + param, + infer_args, + &substs, + had_count_error, + ) } LifetimeElisionKind::StaticIfNoLifetimeInScope { only_lint: _ } => { Region::new_static(interner).into() @@ -1293,11 +1356,18 @@ pub(crate) fn substs_from_args_and_bindings<'db>( | LifetimeElisionKind::Infer => { // FIXME: With `AnonymousCreateParameter`, we need to create a new lifetime parameter here // (but this will probably be done in hir-def lowering instead). - ctx.inferred_kind(def, param_id, param, infer_args, &substs) + ctx.inferred_kind( + def, + param_id, + param, + infer_args, + &substs, + had_count_error, + ) } } } else { - ctx.inferred_kind(def, param_id, param, infer_args, &substs) + ctx.inferred_kind(def, param_id, param, infer_args, &substs, had_count_error) }; substs.push(param); params.next(); |