diff options
Diffstat (limited to 'compiler/rustc_hir_analysis/src/astconv/mod.rs')
-rw-r--r-- | compiler/rustc_hir_analysis/src/astconv/mod.rs | 99 |
1 files changed, 63 insertions, 36 deletions
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 668763f9b..56b1fd369 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -268,9 +268,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // (*) -- not late-bound, won't change } - Some(rbv::ResolvedArg::Error(_)) => { - bug!("only ty/ct should resolve as ResolvedArg::Error") - } + Some(rbv::ResolvedArg::Error(guar)) => ty::Region::new_error(tcx, guar), None => { self.re_infer(def, lifetime.ident.span).unwrap_or_else(|| { @@ -291,7 +289,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } /// Given a path `path` that refers to an item `I` with the declared generics `decl_generics`, - /// returns an appropriate set of substitutions for this particular reference to `I`. + /// returns an appropriate set of generic arguments for this particular reference to `I`. pub fn ast_path_args_for_ty( &self, span: Span, @@ -317,7 +315,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { /// Given the type/lifetime/const arguments provided to some path (along with /// an implicit `Self`, if this is a trait reference), returns the complete - /// set of substitutions. This may involve applying defaulted type parameters. + /// set of generic arguments. This may involve applying defaulted type parameters. /// Constraints on associated types are created from `create_assoc_bindings_for_generic_args`. /// /// Example: @@ -523,7 +521,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { Ty::new_misc_error(tcx).into() } } - GenericParamDefKind::Const { has_default } => { + GenericParamDefKind::Const { has_default, .. } => { let ty = tcx .at(self.span) .type_of(param.def_id) @@ -910,19 +908,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) -> Ty<'tcx> { let tcx = self.tcx(); let args = self.ast_path_args_for_ty(span, did, item_segment); - let ty = tcx.at(span).type_of(did); - if let DefKind::TyAlias { lazy } = tcx.def_kind(did) - && (lazy || ty.skip_binder().has_opaque_types()) + if let DefKind::TyAlias = tcx.def_kind(did) + && tcx.type_alias_is_lazy(did) { - // Type aliases referring to types that contain opaque types (but aren't just directly - // referencing a single opaque type) as well as those defined in crates that have the + // Type aliases defined in crates that have the // feature `lazy_type_alias` enabled get encoded as a type alias that normalization will // then actually instantiate the where bounds of. let alias_ty = tcx.mk_alias_ty(did, args); Ty::new_alias(tcx, ty::Weak, alias_ty) } else { - ty.instantiate(tcx, args) + tcx.at(span).type_of(did).instantiate(tcx, args) } } @@ -2161,7 +2157,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } Res::Def( DefKind::Enum - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::Struct | DefKind::Union | DefKind::ForeignTy, @@ -2200,27 +2196,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.span_note(span, format!("type parameter `{name}` defined here")); } }); - - match tcx.named_bound_var(hir_id) { - Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => { - let name = - tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id.expect_local())); - let br = ty::BoundTy { - var: ty::BoundVar::from_u32(index), - kind: ty::BoundTyKind::Param(def_id, name), - }; - Ty::new_bound(tcx, debruijn, br) - } - Some(rbv::ResolvedArg::EarlyBound(_)) => { - let def_id = def_id.expect_local(); - let item_def_id = tcx.hir().ty_param_owner(def_id); - let generics = tcx.generics_of(item_def_id); - let index = generics.param_def_id_to_index[&def_id.to_def_id()]; - Ty::new_param(tcx, index, tcx.hir().ty_param_name(def_id)) - } - Some(rbv::ResolvedArg::Error(guar)) => Ty::new_error(tcx, guar), - arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"), - } + self.hir_id_to_bound_ty(hir_id) } Res::SelfTyParam { .. } => { // `Self` in trait or type alias. @@ -2389,6 +2365,57 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } + // Converts a hir id corresponding to a type parameter to + // a early-bound `ty::Param` or late-bound `ty::Bound`. + pub(crate) fn hir_id_to_bound_ty(&self, hir_id: hir::HirId) -> Ty<'tcx> { + let tcx = self.tcx(); + match tcx.named_bound_var(hir_id) { + Some(rbv::ResolvedArg::LateBound(debruijn, index, def_id)) => { + let name = tcx.item_name(def_id); + let br = ty::BoundTy { + var: ty::BoundVar::from_u32(index), + kind: ty::BoundTyKind::Param(def_id, name), + }; + Ty::new_bound(tcx, debruijn, br) + } + Some(rbv::ResolvedArg::EarlyBound(def_id)) => { + let def_id = def_id.expect_local(); + let item_def_id = tcx.hir().ty_param_owner(def_id); + let generics = tcx.generics_of(item_def_id); + let index = generics.param_def_id_to_index[&def_id.to_def_id()]; + Ty::new_param(tcx, index, tcx.hir().ty_param_name(def_id)) + } + Some(rbv::ResolvedArg::Error(guar)) => Ty::new_error(tcx, guar), + arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"), + } + } + + // Converts a hir id corresponding to a const parameter to + // a early-bound `ConstKind::Param` or late-bound `ConstKind::Bound`. + pub(crate) fn hir_id_to_bound_const( + &self, + hir_id: hir::HirId, + param_ty: Ty<'tcx>, + ) -> Const<'tcx> { + let tcx = self.tcx(); + match tcx.named_bound_var(hir_id) { + Some(rbv::ResolvedArg::EarlyBound(def_id)) => { + // Find the name and index of the const parameter by indexing the generics of + // the parent item and construct a `ParamConst`. + let item_def_id = tcx.parent(def_id); + let generics = tcx.generics_of(item_def_id); + let index = generics.param_def_id_to_index[&def_id]; + let name = tcx.item_name(def_id); + ty::Const::new_param(tcx, ty::ParamConst::new(index, name), param_ty) + } + Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => { + ty::Const::new_bound(tcx, debruijn, ty::BoundVar::from_u32(index), param_ty) + } + Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar, param_ty), + arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", hir_id), + } + } + /// Parses the programmer's textual representation of a type into our /// internal notion of a type. pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> { @@ -2747,7 +2774,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) { for br in referenced_regions.difference(&constrained_regions) { let br_name = match *br { - ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon(..) | ty::BrEnv => { + ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon | ty::BrEnv => { "an anonymous lifetime".to_string() } ty::BrNamed(_, name) => format!("lifetime `{name}`"), @@ -2755,7 +2782,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let mut err = generate_err(&br_name); - if let ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon(..) = *br { + if let ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon = *br { // The only way for an anonymous lifetime to wind up // in the return type but **also** be unconstrained is // if it only appears in "associated types" in the |