diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 65fd562a4ebf6..7f68bcec4f639 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1738,28 +1738,25 @@ fn rendered_precise_capturing_args<'tcx>( fn const_param_default<'tcx>( tcx: TyCtxt<'tcx>, - local_def_id: LocalDefId, + param_def_id: LocalDefId, ) -> ty::EarlyBinder<'tcx, Const<'tcx>> { let hir::Node::GenericParam(hir::GenericParam { - kind: hir::GenericParamKind::Const { default: Some(default_ct), .. }, + kind: hir::GenericParamKind::Const { default: Some(ct), .. }, .. - }) = tcx.hir_node_by_def_id(local_def_id) + }) = tcx.hir_node_by_def_id(param_def_id) else { span_bug!( - tcx.def_span(local_def_id), - "`const_param_default` expected a generic parameter with a constant" + tcx.def_span(param_def_id), + "const_param_default: expected a const parameter with a default value" ) }; - let icx = ItemCtxt::new(tcx, local_def_id); + let item_def_id = tcx.local_parent(param_def_id); + let icx = ItemCtxt::new(tcx, item_def_id); - let def_id = local_def_id.to_def_id(); - let identity_args = ty::GenericArgs::identity_for_item(tcx, tcx.parent(def_id)); - - let ct = icx.lowerer().lower_const_arg( - default_ct, - tcx.type_of(def_id).instantiate(tcx, identity_args).skip_norm_wip(), - ); + let ct = icx + .lowerer() + .lower_const_arg(ct, tcx.type_of(param_def_id).instantiate_identity().skip_norm_wip()); ty::EarlyBinder::bind(tcx, ct) } diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 13128a7fe9135..80cea609031c1 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -237,7 +237,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { let opt_self = if let Node::Item(item) = node && let ItemKind::Trait { .. } | ItemKind::TraitAlias(..) = item.kind { - // Something of a hack: We reuse the node ID of the trait for the self type parameter. + // Something of a hack: We reuse the DefId of the trait for the self type parameter. Some(ty::GenericParamDef { index: 0, name: kw::SelfUpper, diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 45254aa23896d..d45f4f79aae9a 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -60,10 +60,6 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ None => {} } - let hir_id = tcx.local_def_id_to_hir_id(def_id); - - let icx = ItemCtxt::new(tcx, def_id); - let new_bound_fn_def = |hir: HirId, did| { let args = ty::GenericArgs::identity_for_item(tcx, def_id); Ty::new_fn_def( @@ -81,7 +77,16 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ ) }; - let output = match tcx.hir_node(hir_id) { + let hir_id = tcx.local_def_id_to_hir_id(def_id); + let hir_node = tcx.hir_node(hir_id); + let def_id = match hir_node { + Node::GenericParam(_) => tcx.local_parent(def_id), + _ => def_id, + }; + + let icx = ItemCtxt::new(tcx, def_id); + + let output = match hir_node { Node::TraitItem(item) => match item.kind { TraitItemKind::Fn(_, _) => new_bound_fn_def(item.hir_id(), def_id.to_def_id()), TraitItemKind::Const(ty, rhs) => rhs @@ -101,7 +106,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ .unwrap_or_else(|| icx.lower_ty(ty)), TraitItemKind::Type(_, Some(ty)) => icx.lower_ty(ty), TraitItemKind::Type(_, None) => { - span_bug!(item.span, "associated type missing default"); + span_bug!(item.span, "type_of: associated type missing default"); } }, @@ -196,7 +201,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ | ItemKind::ExternCrate(..) | ItemKind::Use(..) | ItemKind::TestBinderConstraints { .. } => { - span_bug!(item.span, "compute_type_of_item: unexpected item type: {:?}", item.kind); + span_bug!(item.span, "type_of: unexpected item kind: {:?}", item.kind); } }, @@ -254,12 +259,10 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ lowered_ty } } - x => bug!("unexpected non-type Node::GenericParam: {:?}", x), + _ => bug!("type_of: unexpected node kind {hir_node:?}"), }, - x => { - bug!("unexpected sort of node in type_of(): {:?}", x); - } + node => bug!("type_of: unexpected node kind: {node:?}"), }; if let Err(e) = icx.check_tainted_by_errors() && !output.references_error() diff --git a/tests/ui/associated-types/type-relative-in-const-param-ty.rs b/tests/ui/associated-types/type-relative-in-const-param-ty.rs new file mode 100644 index 0000000000000..d4482e63a3586 --- /dev/null +++ b/tests/ui/associated-types/type-relative-in-const-param-ty.rs @@ -0,0 +1,21 @@ +// Test that we can resolve type-relative associated type paths inside const parameter types +// where the self type is a simple type parameter. + +//@ check-pass +#![feature(generic_const_parameter_types, adt_const_params, const_param_ty_trait)] + +trait Trait { + type Type; +} + +// Below, `T::Type` resolves to `::Type` since the owner features bound `T: Trait`. + +struct Owner0(T) +where + T: Trait; + +struct Owner1(T) +where + T: Trait; + +fn main() {} diff --git a/tests/ui/associated-types/type-relative-in-ty-param-default.rs b/tests/ui/associated-types/type-relative-in-ty-param-default.rs new file mode 100644 index 0000000000000..61c90fea22752 --- /dev/null +++ b/tests/ui/associated-types/type-relative-in-ty-param-default.rs @@ -0,0 +1,20 @@ +// Test that we can resolve type-relative associated type paths inside type parameter defaults +// where the self type is a simple type parameter. +// +// issue: + +//@ check-pass + +trait Trait { + type Type; +} + +// Below, `T::Type` resolves to `::Type` since the owner features bound `T: Trait`. + +struct Owner0(T, U); + +struct Owner1(T, U) +where + T: Trait; + +fn main() {} diff --git a/tests/ui/const-generics/defaults/type-relative-assoc-const.rs b/tests/ui/const-generics/defaults/type-relative-assoc-const.rs new file mode 100644 index 0000000000000..69a26761d120e --- /dev/null +++ b/tests/ui/const-generics/defaults/type-relative-assoc-const.rs @@ -0,0 +1,18 @@ +// Test that we can resolve type-relative associated const paths inside const parameter defaults +// where the self type is a simple type parameter. + +//@ check-pass +#![feature(min_generic_const_args)] + +extern crate core; +use core::direct_const_arg as lift; + +trait Trait { + type const CT: usize; +} + +// Below, `T::CT` resolves to `::CT` since the owner features bound `T: Trait`. + +struct Owner0(T); + +fn main() {}