Skip to content

Commit cd8a2ae

Browse files
committed
generic_const_args: allow paths to non type consts
1 parent 79cbcec commit cd8a2ae

25 files changed

Lines changed: 307 additions & 85 deletions

File tree

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ fn const_evaluatable_predicates_of<'tcx>(
440440
}
441441

442442
// Skip type consts as mGCA doesn't support evaluatable clauses.
443-
if self.tcx.is_type_const(uv.def) {
443+
if self.tcx.is_type_const(uv.def) || self.tcx.features().generic_const_args() {
444444
return;
445445
}
446446

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3031,7 +3031,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
30313031
span: Span,
30323032
) -> Result<(), ErrorGuaranteed> {
30333033
let tcx = self.tcx();
3034-
if tcx.is_type_const(def_id) {
3034+
// FIXME(gca): Intentionally disallowing paths to inherent associated non-type constants
3035+
// until a refactoring for how generic args for IACs are represented has been landed.
3036+
if tcx.is_type_const(def_id)
3037+
|| tcx.features().generic_const_args()
3038+
&& !(matches!(tcx.def_kind(def_id), DefKind::AssocConst { is_type_const: false })
3039+
&& matches!(
3040+
tcx.def_kind(tcx.parent(def_id)),
3041+
DefKind::Impl { of_trait: false }
3042+
))
3043+
{
30353044
Ok(())
30363045
} else {
30373046
let mut err = self.dcx().struct_span_err(

compiler/rustc_infer/src/infer/relate/generalize.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ impl<'tcx> InferCtxt<'tcx> {
188188
bug!("generalized `{source_term:?} to infer, not an alias");
189189
};
190190
match source_alias.kind(self.tcx) {
191-
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
191+
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst { .. } => {
192192
// FIXME: This does not handle subtyping correctly, we could
193193
// instead create a new inference variable `?normalized_source`, emitting
194194
// `Projection(normalized_source, ?ty_normalized)` and
@@ -204,8 +204,8 @@ impl<'tcx> InferCtxt<'tcx> {
204204
| ty::AliasTermKind::OpaqueTy => {
205205
return Err(TypeError::CyclicTy(source_term.expect_type()));
206206
}
207-
ty::AliasTermKind::InherentConst
208-
| ty::AliasTermKind::FreeConst
207+
ty::AliasTermKind::InherentConst { .. }
208+
| ty::AliasTermKind::FreeConst { .. }
209209
| ty::AliasTermKind::UnevaluatedConst => {
210210
return Err(TypeError::CyclicConst(source_term.expect_const()));
211211
}

compiler/rustc_middle/src/ty/context/impl_interner.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,17 +212,17 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
212212
ty::AliasTermKind::ProjectionTy
213213
}
214214
}
215-
DefKind::AssocConst { .. } => {
215+
DefKind::AssocConst { is_type_const } => {
216216
if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
217217
{
218-
ty::AliasTermKind::InherentConst
218+
ty::AliasTermKind::InherentConst { is_type_const }
219219
} else {
220-
ty::AliasTermKind::ProjectionConst
220+
ty::AliasTermKind::ProjectionConst { is_type_const }
221221
}
222222
}
223223
DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy,
224224
DefKind::TyAlias => ty::AliasTermKind::FreeTy,
225-
DefKind::Const { .. } => ty::AliasTermKind::FreeConst,
225+
DefKind::Const { is_type_const } => ty::AliasTermKind::FreeConst { is_type_const },
226226
DefKind::AnonConst | DefKind::Ctor(_, CtorKind::Const) => {
227227
ty::AliasTermKind::UnevaluatedConst
228228
}

compiler/rustc_middle/src/ty/print/pretty.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3152,7 +3152,7 @@ define_print! {
31523152

31533153
ty::AliasTerm<'tcx> {
31543154
match self.kind(p.tcx()) {
3155-
ty::AliasTermKind::InherentTy | ty::AliasTermKind::InherentConst => p.pretty_print_inherent_projection(*self)?,
3155+
ty::AliasTermKind::InherentTy | ty::AliasTermKind::InherentConst { .. } => p.pretty_print_inherent_projection(*self)?,
31563156
ty::AliasTermKind::ProjectionTy => {
31573157
if !(p.should_print_verbose() || with_reduced_queries())
31583158
&& p.tcx().is_impl_trait_in_trait(self.def_id)
@@ -3163,10 +3163,10 @@ define_print! {
31633163
}
31643164
}
31653165
ty::AliasTermKind::FreeTy
3166-
| ty::AliasTermKind::FreeConst
3166+
| ty::AliasTermKind::FreeConst { .. }
31673167
| ty::AliasTermKind::OpaqueTy
31683168
| ty::AliasTermKind::UnevaluatedConst
3169-
| ty::AliasTermKind::ProjectionConst => {
3169+
| ty::AliasTermKind::ProjectionConst { .. } => {
31703170
p.print_def_path(self.def_id, self.args)?;
31713171
}
31723172
}

compiler/rustc_middle/src/ty/util.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -948,11 +948,11 @@ impl<'tcx> TyCtxt<'tcx> {
948948
}
949949
ty::AliasTermKind::OpaqueTy => Some(self.variances_of(def_id)),
950950
ty::AliasTermKind::InherentTy
951-
| ty::AliasTermKind::InherentConst
951+
| ty::AliasTermKind::InherentConst { .. }
952952
| ty::AliasTermKind::FreeTy
953-
| ty::AliasTermKind::FreeConst
953+
| ty::AliasTermKind::FreeConst { .. }
954954
| ty::AliasTermKind::UnevaluatedConst
955-
| ty::AliasTermKind::ProjectionConst => None,
955+
| ty::AliasTermKind::ProjectionConst { .. } => None,
956956
}
957957
}
958958
}

compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,25 @@ where
2929
.map(|pred| goal.with(cx, pred)),
3030
);
3131

32-
let actual = if free_alias.kind(cx).is_type() {
33-
cx.type_of(free_alias.def_id).instantiate(cx, free_alias.args).into()
34-
} else {
35-
cx.const_of_item(free_alias.def_id).instantiate(cx, free_alias.args).into()
32+
let actual = match free_alias.kind(cx) {
33+
ty::AliasTermKind::FreeTy => {
34+
cx.type_of(free_alias.def_id).instantiate(cx, free_alias.args).into()
35+
}
36+
ty::AliasTermKind::FreeConst { is_type_const: true } => {
37+
cx.const_of_item(free_alias.def_id).instantiate(cx, free_alias.args).into()
38+
}
39+
ty::AliasTermKind::FreeConst { is_type_const: false } => {
40+
self.try_evaluate_added_goals()?;
41+
if let Some(normalized_const) =
42+
self.evaluate_const(goal.param_env, free_alias.expect_ct(cx))
43+
{
44+
normalized_const.into()
45+
} else {
46+
return self
47+
.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
48+
}
49+
}
50+
kind => panic!("expected free alias, found {kind:?}"),
3651
};
3752

3853
self.instantiate_normalizes_to_term(goal, actual);

compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,28 @@ where
5151
.map(|pred| goal.with(cx, pred)),
5252
);
5353

54-
let normalized = if inherent.kind(cx).is_type() {
55-
cx.type_of(inherent.def_id).instantiate(cx, inherent_args).into()
56-
} else {
57-
cx.const_of_item(inherent.def_id).instantiate(cx, inherent_args).into()
54+
let normalized = match inherent.kind(cx) {
55+
ty::AliasTermKind::InherentTy => {
56+
cx.type_of(inherent.def_id).instantiate(cx, inherent_args).into()
57+
}
58+
ty::AliasTermKind::InherentConst { is_type_const: true } => {
59+
cx.const_of_item(inherent.def_id).instantiate(cx, inherent_args).into()
60+
}
61+
ty::AliasTermKind::InherentConst { is_type_const: false } => {
62+
// FIXME(gca): This is dead code at the moment.
63+
// Will self.evaluate_const eventually take the inherent_args or the impl_args form
64+
// of args? It might be either.
65+
self.try_evaluate_added_goals()?;
66+
let uv =
67+
ty::UnevaluatedConst::new(inherent.def_id.try_into().unwrap(), inherent_args);
68+
if let Some(normalized_const) = self.evaluate_const(goal.param_env, uv) {
69+
normalized_const.into()
70+
} else {
71+
return self
72+
.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
73+
}
74+
}
75+
kind => panic!("expected inherent alias, found {kind:?}"),
5876
};
5977
self.instantiate_normalizes_to_term(goal, normalized);
6078
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)

compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ where
3232
debug_assert!(self.term_is_fully_unconstrained(goal));
3333
let cx = self.cx();
3434
match goal.predicate.alias.kind(cx) {
35-
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
35+
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst { .. } => {
3636
let trait_ref = goal.predicate.alias.trait_ref(cx);
3737
let (_, proven_via) =
3838
self.probe(|_| ProbeKind::ShadowedEnvProbing).enter(|ecx| {
@@ -83,11 +83,11 @@ where
8383
},
8484
)
8585
}
86-
ty::AliasTermKind::InherentTy | ty::AliasTermKind::InherentConst => {
86+
ty::AliasTermKind::InherentTy | ty::AliasTermKind::InherentConst { .. } => {
8787
self.normalize_inherent_associated_term(goal)
8888
}
8989
ty::AliasTermKind::OpaqueTy => self.normalize_opaque_type(goal),
90-
ty::AliasTermKind::FreeTy | ty::AliasTermKind::FreeConst => {
90+
ty::AliasTermKind::FreeTy | ty::AliasTermKind::FreeConst { .. } => {
9191
self.normalize_free_alias(goal)
9292
}
9393
ty::AliasTermKind::UnevaluatedConst => self.normalize_anon_const(goal),
@@ -264,7 +264,7 @@ where
264264
let error_response = |ecx: &mut EvalCtxt<'_, D>, guar| {
265265
let error_term = match goal.predicate.alias.kind(cx) {
266266
ty::AliasTermKind::ProjectionTy => Ty::new_error(cx, guar).into(),
267-
ty::AliasTermKind::ProjectionConst => Const::new_error(cx, guar).into(),
267+
ty::AliasTermKind::ProjectionConst { .. } => Const::new_error(cx, guar).into(),
268268
kind => panic!("expected projection, found {kind:?}"),
269269
};
270270
ecx.instantiate_normalizes_to_term(goal, error_term);
@@ -380,15 +380,29 @@ where
380380
// Finally we construct the actual value of the associated type.
381381
let term = match goal.predicate.alias.kind(cx) {
382382
ty::AliasTermKind::ProjectionTy => {
383-
cx.type_of(target_item_def_id).map_bound(|ty| ty.into())
383+
cx.type_of(target_item_def_id).instantiate(cx, target_args).into()
384384
}
385-
ty::AliasTermKind::ProjectionConst => {
386-
cx.const_of_item(target_item_def_id).map_bound(|ct| ct.into())
385+
ty::AliasTermKind::ProjectionConst { is_type_const: true } => {
386+
cx.const_of_item(target_item_def_id).instantiate(cx, target_args).into()
387+
}
388+
ty::AliasTermKind::ProjectionConst { is_type_const: false } => {
389+
ecx.try_evaluate_added_goals()?;
390+
let uv = ty::UnevaluatedConst::new(
391+
target_item_def_id.try_into().unwrap(),
392+
target_args,
393+
);
394+
if let Some(eval) = ecx.evaluate_const(goal.param_env, uv) {
395+
eval.into()
396+
} else {
397+
return ecx.evaluate_added_goals_and_make_canonical_response(
398+
Certainty::AMBIGUOUS,
399+
);
400+
}
387401
}
388402
kind => panic!("expected projection, found {kind:?}"),
389403
};
390404

391-
ecx.instantiate_normalizes_to_term(goal, term.instantiate(cx, target_args));
405+
ecx.instantiate_normalizes_to_term(goal, term);
392406
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
393407
})
394408
}

compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,7 +1588,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
15881588
};
15891589

15901590
if let Some(lhs) = lhs.to_alias_term()
1591-
&& let ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst = lhs.kind(self.tcx)
1591+
&& let ty::AliasTermKind::ProjectionTy
1592+
| ty::AliasTermKind::ProjectionConst { .. } = lhs.kind(self.tcx)
15921593
&& let Some((better_type_err, expected_term)) =
15931594
derive_better_type_error(lhs, rhs)
15941595
{
@@ -1597,7 +1598,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
15971598
better_type_err,
15981599
)
15991600
} else if let Some(rhs) = rhs.to_alias_term()
1600-
&& let ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst = rhs.kind(self.tcx)
1601+
&& let ty::AliasTermKind::ProjectionTy
1602+
| ty::AliasTermKind::ProjectionConst { .. } = rhs.kind(self.tcx)
16011603
&& let Some((better_type_err, expected_term)) =
16021604
derive_better_type_error(rhs, lhs)
16031605
{

0 commit comments

Comments
 (0)