Skip to content

Commit 5dba596

Browse files
committed
Check type_const type is ConstParamTy_ and that RHS matches it
1 parent f2293ec commit 5dba596

20 files changed

+214
-55
lines changed

compiler/rustc_hir/src/hir.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3065,7 +3065,7 @@ macro_rules! expect_methods_self_kind {
30653065
$(
30663066
#[track_caller]
30673067
pub fn $name(&self) -> $ret_ty {
3068-
let $pat = &self.kind else { expect_failed(stringify!($ident), self) };
3068+
let $pat = &self.kind else { expect_failed(stringify!($name), self) };
30693069
$ret_val
30703070
}
30713071
)*
@@ -3077,7 +3077,7 @@ macro_rules! expect_methods_self {
30773077
$(
30783078
#[track_caller]
30793079
pub fn $name(&self) -> $ret_ty {
3080-
let $pat = self else { expect_failed(stringify!($ident), self) };
3080+
let $pat = self else { expect_failed(stringify!($name), self) };
30813081
$ret_val
30823082
}
30833083
)*
@@ -4790,6 +4790,11 @@ impl<'hir> Node<'hir> {
47904790
ForeignItemKind::Static(ty, ..) => Some(ty),
47914791
_ => None,
47924792
},
4793+
Node::GenericParam(param) => match param.kind{
4794+
GenericParamKind::Lifetime { .. } => None,
4795+
GenericParamKind::Type { default, .. } => default,
4796+
GenericParamKind::Const { ty, .. } => Some(ty),
4797+
}
47934798
_ => None,
47944799
}
47954800
}

compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,10 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
918918
);
919919
check_where_clauses(wfcx, def_id);
920920

921-
wfcheck::check_const_item_rhs(wfcx, def_id)
921+
if find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_)) {
922+
wfcheck::check_type_const(wfcx, def_id, ty, true)?;
923+
}
924+
Ok(())
922925
}));
923926

924927
// Only `Node::Item` and `Node::ForeignItem` still have HIR based

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -951,16 +951,19 @@ pub(crate) fn check_associated_item(
951951
let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), ty);
952952
wfcx.register_wf_obligation(span, loc, ty.into());
953953

954-
if item.defaultness(tcx).has_value() {
954+
let has_value = item.defaultness(tcx).has_value();
955+
if find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_)) {
956+
check_type_const(wfcx, def_id, ty, has_value)?;
957+
}
958+
959+
if has_value {
955960
let code = ObligationCauseCode::SizedConstOrStatic;
956961
wfcx.register_bound(
957962
ObligationCause::new(span, def_id, code),
958963
wfcx.param_env,
959964
ty,
960965
tcx.require_lang_item(LangItem::Sized, span),
961966
);
962-
963-
check_const_item_rhs(wfcx, def_id)?;
964967
}
965968

966969
Ok(())
@@ -1230,16 +1233,33 @@ pub(crate) fn check_static_item<'tcx>(
12301233
}
12311234

12321235
#[instrument(level = "debug", skip(wfcx))]
1233-
pub(super) fn check_const_item_rhs<'tcx>(
1236+
pub(super) fn check_type_const<'tcx>(
12341237
wfcx: &WfCheckingCtxt<'_, 'tcx>,
12351238
def_id: LocalDefId,
1239+
item_ty: Ty<'tcx>,
1240+
has_value: bool,
12361241
) -> Result<(), ErrorGuaranteed> {
12371242
let tcx = wfcx.tcx();
1238-
if find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_)) {
1243+
let span = tcx.def_span(def_id);
1244+
1245+
wfcx.register_bound(
1246+
ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(item_ty)),
1247+
wfcx.param_env,
1248+
item_ty,
1249+
tcx.require_lang_item(LangItem::ConstParamTy, span),
1250+
);
1251+
1252+
if has_value {
12391253
let raw_ct = tcx.const_of_item(def_id).instantiate_identity();
1240-
let span = tcx.def_span(def_id);
12411254
let norm_ct = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), raw_ct);
12421255
wfcx.register_wf_obligation(span, Some(WellFormedLoc::Ty(def_id)), norm_ct.into());
1256+
1257+
wfcx.register_obligation(Obligation::new(
1258+
tcx,
1259+
ObligationCause::new(span, def_id, ObligationCauseCode::WellFormed(None)),
1260+
wfcx.param_env,
1261+
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(norm_ct, item_ty)),
1262+
));
12431263
}
12441264
Ok(())
12451265
}

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,12 +1257,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
12571257
ty: Ty<'tcx>,
12581258
obligation: &PredicateObligation<'tcx>,
12591259
) -> Diag<'a> {
1260-
let param = obligation.cause.body_id;
1261-
let hir::GenericParamKind::Const { ty: &hir::Ty { span, .. }, .. } =
1262-
self.tcx.hir_node_by_def_id(param).expect_generic_param().kind
1263-
else {
1264-
bug!()
1265-
};
1260+
let def_id = obligation.cause.body_id;
1261+
let span = self.tcx.ty_span(def_id);
12661262

12671263
let mut file = None;
12681264
let ty_str = self.tcx.short_string(ty, &mut file);

tests/ui/associated-consts/assoc-const-eq-ambiguity.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// We used to say "ambiguous associated type" on ambiguous associated consts.
22
// Ensure that we now use the correct label.
33

4-
#![feature(associated_const_equality, min_generic_const_args)]
4+
#![feature(associated_const_equality, min_generic_const_args, unsized_const_params)]
55
#![allow(incomplete_features)]
66

77
trait Trait0: Parent0<i32> + Parent0<u32> {}

tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
// Check that we eventually catch types of assoc const bounds
22
// (containing late-bound vars) that are ill-formed.
3-
#![feature(associated_const_equality, min_generic_const_args)]
3+
#![feature(associated_const_equality, min_generic_const_args, adt_const_params, unsized_const_params)]
44
#![allow(incomplete_features)]
55

6-
trait Trait<T> {
6+
use std::marker::ConstParamTy_;
7+
8+
trait Trait<T: ConstParamTy_> {
79
#[type_const]
810
const K: T;
911
}

tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
error: higher-ranked subtype error
2-
--> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:14:13
2+
--> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:16:13
33
|
44
LL | K = { () }
55
| ^^^^^^
66

77
error: higher-ranked subtype error
8-
--> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:14:13
8+
--> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:16:13
99
|
1010
LL | K = { () }
1111
| ^^^^^^
1212
|
1313
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
1414

1515
error: implementation of `Project` is not general enough
16-
--> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:12:13
16+
--> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:14:13
1717
|
1818
LL | _: impl Trait<
1919
| _____________^

tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
//
44
//@ check-pass
55

6-
#![feature(associated_const_equality, min_generic_const_args)]
6+
#![feature(associated_const_equality, min_generic_const_args, adt_const_params, unsized_const_params)]
77
#![allow(incomplete_features)]
88

9-
trait Trait<T> {
9+
use std::marker::ConstParamTy_;
10+
11+
trait Trait<T: ConstParamTy_> {
1012
#[type_const]
1113
const K: T;
1214
}

tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Detect and reject escaping late-bound generic params in
22
// the type of assoc consts used in an equality bound.
3-
#![feature(associated_const_equality, min_generic_const_args)]
3+
#![feature(associated_const_equality, min_generic_const_args, unsized_const_params)]
44
#![allow(incomplete_features)]
55

66
trait Trait<'a> {

tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
// Regression test for issue #108271.
22
// Detect and reject generic params in the type of assoc consts used in an equality bound.
3-
#![feature(associated_const_equality, min_generic_const_args)]
3+
#![feature(associated_const_equality, min_generic_const_args, adt_const_params, unsized_const_params)]
44
#![allow(incomplete_features)]
55

6-
trait Trait<'a, T: 'a, const N: usize> {
6+
use std::marker::ConstParamTy_;
7+
8+
trait Trait<'a, T: 'a + ConstParamTy_, const N: usize> {
79
#[type_const]
810
const K: &'a [T; N];
911
}
1012

11-
fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {}
13+
fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {}
1214
//~^ ERROR the type of the associated constant `K` must not depend on generic parameters
1315
//~| NOTE its type must not depend on the lifetime parameter `'r`
1416
//~| NOTE the lifetime parameter `'r` is defined here
@@ -22,7 +24,7 @@ fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {}
2224
//~| NOTE the const parameter `Q` is defined here
2325
//~| NOTE `K` has type `&'r [A; Q]`
2426

25-
trait Project {
27+
trait Project: ConstParamTy_ {
2628
#[type_const]
2729
const SELF: Self;
2830
}
@@ -38,7 +40,7 @@ fn take2<P: Project<SELF = {}>>(_: P) {}
3840
//~| NOTE the type parameter `P` is defined here
3941
//~| NOTE `SELF` has type `P`
4042

41-
trait Iface<'r> {
43+
trait Iface<'r>: ConstParamTy_ {
4244
//~^ NOTE the lifetime parameter `'r` is defined here
4345
//~| NOTE the lifetime parameter `'r` is defined here
4446
type Assoc<const Q: usize>: Trait<'r, Self, Q, K = { loop {} }>

0 commit comments

Comments
 (0)