Skip to content

Commit 5787782

Browse files
committed
Transform args for inherent type_consts in instantiate_value_path
1 parent 9bd7517 commit 5787782

2 files changed

Lines changed: 65 additions & 9 deletions

File tree

  • compiler
    • rustc_borrowck/src/type_check
    • rustc_hir_typeck/src/fn_ctxt

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,14 +1768,25 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
17681768
);
17691769
};
17701770
} else {
1771-
self.ascribe_user_type(
1772-
constant.const_.ty(),
1773-
ty::UserType::new(ty::UserTypeKind::TypeOf(
1774-
uv.def,
1775-
UserArgs { args: uv.args, user_self_ty: None },
1776-
)),
1777-
locations.span(self.body),
1778-
);
1771+
// FIXME: For inherent associated type constants (IACs), we skip
1772+
// user type ascription because the args in MIR use [impl_args...]
1773+
// format while IAC generics expect [Self, own_args...] format.
1774+
// Properly fixing this requires changes to MIR generation or a
1775+
// more sophisticated args transformation.
1776+
let is_inherent_type_const = tcx.is_type_const(uv.def)
1777+
&& tcx.opt_associated_item(uv.def).is_some_and(|assoc| {
1778+
matches!(assoc.container, ty::AssocContainer::InherentImpl)
1779+
});
1780+
if !is_inherent_type_const {
1781+
self.ascribe_user_type(
1782+
constant.const_.ty(),
1783+
ty::UserType::new(ty::UserTypeKind::TypeOf(
1784+
uv.def,
1785+
UserArgs { args: uv.args, user_self_ty: None },
1786+
)),
1787+
locations.span(self.body),
1788+
);
1789+
}
17791790
}
17801791
} else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
17811792
let unnormalized_ty = tcx.type_of(static_def_id).instantiate_identity();

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,38 @@ use crate::method::{self, MethodCallee};
4545
use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LoweredTy};
4646

4747
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
48+
/// Transform generic args for inherent associated type constants (IACs).
49+
///
50+
/// IACs have a different generic parameter structure than regular associated constants:
51+
/// - Regular assoc const: parent (impl) generic params + own generic params
52+
/// - IAC (type_const): Self type + own generic params
53+
pub(crate) fn transform_args_for_inherent_type_const(
54+
&self,
55+
def_id: DefId,
56+
args: GenericArgsRef<'tcx>,
57+
) -> GenericArgsRef<'tcx> {
58+
let tcx = self.tcx;
59+
if !tcx.is_type_const(def_id) {
60+
return args;
61+
}
62+
let Some(assoc_item) = tcx.opt_associated_item(def_id) else {
63+
return args;
64+
};
65+
if !matches!(assoc_item.container, ty::AssocContainer::InherentImpl) {
66+
return args;
67+
}
68+
69+
let impl_def_id = assoc_item.container_id(tcx);
70+
let generics = tcx.generics_of(def_id);
71+
let impl_args = &args[..generics.parent_count];
72+
let self_ty = tcx.type_of(impl_def_id).instantiate(tcx, impl_args);
73+
// Build new args: [Self, own_args...]
74+
let own_args = &args[generics.parent_count..];
75+
tcx.mk_args_from_iter(
76+
std::iter::once(ty::GenericArg::from(self_ty)).chain(own_args.iter().copied()),
77+
)
78+
}
79+
4880
/// Produces warning on the given node, if the current point in the
4981
/// function is unreachable, and there hasn't been another warning.
5082
pub(crate) fn warn_if_unreachable(&self, id: HirId, span: Span, kind: &str) {
@@ -1281,8 +1313,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12811313
)
12821314
});
12831315

1316+
let args_for_user_type = if let Res::Def(DefKind::AssocConst, def_id) = res {
1317+
self.transform_args_for_inherent_type_const(def_id, args_raw)
1318+
} else {
1319+
args_raw
1320+
};
1321+
12841322
// First, store the "user args" for later.
1285-
self.write_user_type_annotation_from_args(hir_id, def_id, args_raw, user_self_ty);
1323+
self.write_user_type_annotation_from_args(hir_id, def_id, args_for_user_type, user_self_ty);
12861324

12871325
// Normalize only after registering type annotations.
12881326
let args = self.normalize(span, args_raw);
@@ -1322,6 +1360,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13221360
}
13231361

13241362
debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_instantiated);
1363+
1364+
let args = if let Res::Def(DefKind::AssocConst, def_id) = res {
1365+
self.transform_args_for_inherent_type_const(def_id, args)
1366+
} else {
1367+
args
1368+
};
1369+
13251370
self.write_args(hir_id, args);
13261371

13271372
(ty_instantiated, res)

0 commit comments

Comments
 (0)