Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/lower_nextsolver/path.rs')
| -rw-r--r-- | crates/hir-ty/src/lower_nextsolver/path.rs | 102 |
1 files changed, 40 insertions, 62 deletions
diff --git a/crates/hir-ty/src/lower_nextsolver/path.rs b/crates/hir-ty/src/lower_nextsolver/path.rs index 0a9f34c9da..ef2c392f08 100644 --- a/crates/hir-ty/src/lower_nextsolver/path.rs +++ b/crates/hir-ty/src/lower_nextsolver/path.rs @@ -30,7 +30,7 @@ use stdx::never; use crate::{ GenericArgsProhibitedReason, IncorrectGenericsLenKind, PathGenericsSource, PathLoweringDiagnostic, TyDefId, ValueTyDefId, - consteval_nextsolver::{unknown_const, unknown_const_as_generic}, + consteval::{unknown_const, unknown_const_as_generic}, db::HirDatabase, generics::{Generics, generics}, lower::PathDiagnosticCallbackData, @@ -51,15 +51,17 @@ use super::{ const_param_ty_query, ty_query, }; -type CallbackData<'a> = - Either<PathDiagnosticCallbackData, crate::infer::diagnostics::PathDiagnosticCallbackData<'a>>; +type CallbackData<'a, 'db> = Either< + PathDiagnosticCallbackData, + crate::infer::diagnostics::PathDiagnosticCallbackData<'a, 'db>, +>; // We cannot use `&mut dyn FnMut()` because of lifetime issues, and we don't want to use `Box<dyn FnMut()>` // because of the allocation, so we create a lifetime-less callback, tailored for our needs. pub(crate) struct PathDiagnosticCallback<'a, 'db> { - pub(crate) data: CallbackData<'a>, + pub(crate) data: CallbackData<'a, 'db>, pub(crate) callback: - fn(&CallbackData<'_>, &mut TyLoweringContext<'db, '_>, PathLoweringDiagnostic), + fn(&CallbackData<'_, 'db>, &mut TyLoweringContext<'db, '_>, PathLoweringDiagnostic), } pub(crate) struct PathLoweringContext<'a, 'b, 'db> { @@ -155,13 +157,14 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { ty: Ty<'db>, // We need the original resolution to lower `Self::AssocTy` correctly res: Option<TypeNs>, + infer_args: bool, ) -> (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), None) + (self.select_associated_type(res, infer_args), None) } _ => { // FIXME report error (ambiguous associated type) @@ -204,6 +207,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { let trait_ref = self.lower_trait_ref_from_resolved_path( trait_, Ty::new_error(self.ctx.interner, ErrorGuaranteed), + false, ); tracing::debug!(?trait_ref); self.skip_resolved_segment(); @@ -276,8 +280,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { GenericParamDataRef::TypeParamData(p) => p, _ => unreachable!(), }; - Ty::new_param( - self.ctx.interner, + self.ctx.type_param( param_id, idx as u32, p.name @@ -293,7 +296,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { self.ctx.interner, adt.into(), ); - Ty::new_adt(self.ctx.interner, AdtDef::new(adt, self.ctx.interner), args) + Ty::new_adt(self.ctx.interner, adt, args) } TypeNs::AdtId(it) => self.lower_path_inner(it.into(), infer_args), @@ -308,7 +311,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { tracing::debug!(?ty); self.skip_resolved_segment(); - self.lower_ty_relative_path(ty, Some(resolution)) + self.lower_ty_relative_path(ty, Some(resolution), infer_args) } fn handle_type_ns_resolution(&mut self, resolution: &TypeNs) { @@ -480,14 +483,19 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { // and statics can be generic, or just because it was easier for rustc implementors. // That means we'll show the wrong error code. Because of us it's easier to do it // this way :) - ValueNs::GenericParam(_) | ValueNs::ConstId(_) => { + ValueNs::GenericParam(_) => { prohibit_generics_on_resolved(GenericArgsProhibitedReason::Const) } ValueNs::StaticId(_) => { prohibit_generics_on_resolved(GenericArgsProhibitedReason::Static) } - ValueNs::FunctionId(_) | ValueNs::StructId(_) | ValueNs::EnumVariantId(_) => {} - ValueNs::LocalBinding(_) => {} + ValueNs::LocalBinding(_) => { + prohibit_generics_on_resolved(GenericArgsProhibitedReason::LocalVariable) + } + ValueNs::FunctionId(_) + | ValueNs::StructId(_) + | ValueNs::EnumVariantId(_) + | ValueNs::ConstId(_) => {} } } ResolveValueResult::Partial(resolution, _, _) => { @@ -498,7 +506,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { } #[tracing::instrument(skip(self), ret)] - fn select_associated_type(&mut self, res: Option<TypeNs>) -> Ty<'db> { + fn select_associated_type(&mut self, res: Option<TypeNs>, infer_args: bool) -> Ty<'db> { let interner = self.ctx.interner; let Some(res) = res else { return Ty::new_error(self.ctx.interner, ErrorGuaranteed); @@ -516,7 +524,8 @@ 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(associated_ty.into(), false, None, true); + let substs = + self.substs_from_path_segment(associated_ty.into(), infer_args, None, true); let substs = crate::next_solver::GenericArgs::new_from_iter( interner, @@ -541,7 +550,9 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { fn lower_path_inner(&mut self, typeable: TyDefId, infer_args: bool) -> Ty<'db> { let generic_def = match typeable { - TyDefId::BuiltinType(builtinty) => return builtin(self.ctx.interner, builtinty), + TyDefId::BuiltinType(builtinty) => { + return Ty::from_builtin_type(self.ctx.interner, builtinty); + } TyDefId::AdtId(it) => it.into(), TyDefId::TypeAliasId(it) => it.into(), }; @@ -715,12 +726,12 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { param: GenericParamDataRef<'_>, arg: &GenericArg, ) -> crate::next_solver::GenericArg<'db> { - match (param, arg) { + match (param, *arg) { (GenericParamDataRef::LifetimeParamData(_), GenericArg::Lifetime(lifetime)) => { - self.ctx.ctx.lower_lifetime(*lifetime).into() + self.ctx.ctx.lower_lifetime(lifetime).into() } (GenericParamDataRef::TypeParamData(_), GenericArg::Type(type_ref)) => { - self.ctx.ctx.lower_ty(*type_ref).into() + self.ctx.ctx.lower_ty(type_ref).into() } (GenericParamDataRef::ConstParamData(_), GenericArg::Const(konst)) => { let GenericParamId::ConstParamId(const_id) = param_id else { @@ -859,8 +870,9 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { &mut self, resolved: TraitId, explicit_self_ty: Ty<'db>, + infer_args: bool, ) -> TraitRef<'db> { - let args = self.trait_ref_substs_from_path(resolved, explicit_self_ty); + let args = self.trait_ref_substs_from_path(resolved, explicit_self_ty, infer_args); TraitRef::new_from_args(self.ctx.interner, resolved.into(), args) } @@ -868,8 +880,9 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { &mut self, resolved: TraitId, explicit_self_ty: Ty<'db>, + infer_args: bool, ) -> crate::next_solver::GenericArgs<'db> { - self.substs_from_path_segment(resolved.into(), false, Some(explicit_self_ty), false) + self.substs_from_path_segment(resolved.into(), infer_args, Some(explicit_self_ty), false) } pub(super) fn assoc_type_bindings_from_type_bound<'c>( @@ -1039,8 +1052,12 @@ fn check_generic_args_len<'db>( } let lifetime_args_len = def_generics.len_lifetimes_self(); - if provided_lifetimes_count == 0 && lifetime_args_len > 0 && !lowering_assoc_type_generics { - // In generic associated types, we never allow inferring the lifetimes. + if provided_lifetimes_count == 0 + && lifetime_args_len > 0 + && (!lowering_assoc_type_generics || infer_args) + { + // In generic associated types, we never allow inferring the lifetimes, but only in type context, that is + // when `infer_args == false`. In expression/pattern context we always allow inferring them, even for GATs. match lifetime_elision { &LifetimeElisionKind::AnonymousCreateParameter { report_in_path } => { ctx.report_elided_lifetimes_in_path(def, lifetime_args_len as u32, report_in_path); @@ -1335,42 +1352,3 @@ fn unknown_subst<'db>( }), ) } - -pub(crate) fn builtin<'db>(interner: DbInterner<'db>, builtin: BuiltinType) -> Ty<'db> { - match builtin { - BuiltinType::Char => Ty::new(interner, rustc_type_ir::TyKind::Char), - BuiltinType::Bool => Ty::new_bool(interner), - BuiltinType::Str => Ty::new(interner, rustc_type_ir::TyKind::Str), - BuiltinType::Int(t) => { - let int_ty = match primitive::int_ty_from_builtin(t) { - chalk_ir::IntTy::Isize => rustc_type_ir::IntTy::Isize, - chalk_ir::IntTy::I8 => rustc_type_ir::IntTy::I8, - chalk_ir::IntTy::I16 => rustc_type_ir::IntTy::I16, - chalk_ir::IntTy::I32 => rustc_type_ir::IntTy::I32, - chalk_ir::IntTy::I64 => rustc_type_ir::IntTy::I64, - chalk_ir::IntTy::I128 => rustc_type_ir::IntTy::I128, - }; - Ty::new_int(interner, int_ty) - } - BuiltinType::Uint(t) => { - let uint_ty = match primitive::uint_ty_from_builtin(t) { - chalk_ir::UintTy::Usize => rustc_type_ir::UintTy::Usize, - chalk_ir::UintTy::U8 => rustc_type_ir::UintTy::U8, - chalk_ir::UintTy::U16 => rustc_type_ir::UintTy::U16, - chalk_ir::UintTy::U32 => rustc_type_ir::UintTy::U32, - chalk_ir::UintTy::U64 => rustc_type_ir::UintTy::U64, - chalk_ir::UintTy::U128 => rustc_type_ir::UintTy::U128, - }; - Ty::new_uint(interner, uint_ty) - } - BuiltinType::Float(t) => { - let float_ty = match primitive::float_ty_from_builtin(t) { - chalk_ir::FloatTy::F16 => rustc_type_ir::FloatTy::F16, - chalk_ir::FloatTy::F32 => rustc_type_ir::FloatTy::F32, - chalk_ir::FloatTy::F64 => rustc_type_ir::FloatTy::F64, - chalk_ir::FloatTy::F128 => rustc_type_ir::FloatTy::F128, - }; - Ty::new_float(interner, float_ty) - } - } -} |