Rollup merge of #152146 - zedddie:mgca-improve-const-bindings-wfck, r=BoxyUwU
mGCA: Add associated const type check rust-lang/rust#151642 r? BoxyUwU I didn't bless tests just yet as it only fixes the dyn arm
This commit is contained in:
commit
9a4ce0b5f7
11 changed files with 167 additions and 3 deletions
|
|
@ -1569,11 +1569,40 @@ pub(super) fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, def_id:
|
|||
|
||||
let predicates = predicates.instantiate_identity(tcx);
|
||||
|
||||
let assoc_const_obligations: Vec<_> = predicates
|
||||
.predicates
|
||||
.iter()
|
||||
.copied()
|
||||
.zip(predicates.spans.iter().copied())
|
||||
.filter_map(|(clause, sp)| {
|
||||
let proj = clause.as_projection_clause()?;
|
||||
let pred_binder = proj
|
||||
.map_bound(|pred| {
|
||||
pred.term.as_const().map(|ct| {
|
||||
let assoc_const_ty = tcx
|
||||
.type_of(pred.projection_term.def_id)
|
||||
.instantiate(tcx, pred.projection_term.args);
|
||||
ty::ClauseKind::ConstArgHasType(ct, assoc_const_ty)
|
||||
})
|
||||
})
|
||||
.transpose();
|
||||
pred_binder.map(|pred_binder| {
|
||||
let cause = traits::ObligationCause::new(
|
||||
sp,
|
||||
wfcx.body_def_id,
|
||||
ObligationCauseCode::WhereClause(def_id.to_def_id(), sp),
|
||||
);
|
||||
Obligation::new(tcx, cause, wfcx.param_env, pred_binder)
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
assert_eq!(predicates.predicates.len(), predicates.spans.len());
|
||||
let wf_obligations = predicates.into_iter().flat_map(|(p, sp)| {
|
||||
traits::wf::clause_obligations(infcx, wfcx.param_env, wfcx.body_def_id, p, sp)
|
||||
});
|
||||
let obligations: Vec<_> = wf_obligations.chain(default_obligations).collect();
|
||||
let obligations: Vec<_> =
|
||||
wf_obligations.chain(default_obligations).chain(assoc_const_obligations).collect();
|
||||
wfcx.register_obligations(obligations);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -951,6 +951,34 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
|
|||
ty::Binder::dummy(ty::PredicateKind::DynCompatible(principal)),
|
||||
));
|
||||
}
|
||||
|
||||
if !t.has_escaping_bound_vars() {
|
||||
for projection in data.projection_bounds() {
|
||||
let pred_binder = projection
|
||||
.with_self_ty(tcx, t)
|
||||
.map_bound(|p| {
|
||||
p.term.as_const().map(|ct| {
|
||||
let assoc_const_ty = tcx
|
||||
.type_of(p.projection_term.def_id)
|
||||
.instantiate(tcx, p.projection_term.args);
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(
|
||||
ct,
|
||||
assoc_const_ty,
|
||||
))
|
||||
})
|
||||
})
|
||||
.transpose();
|
||||
if let Some(pred_binder) = pred_binder {
|
||||
self.out.push(traits::Obligation::with_depth(
|
||||
tcx,
|
||||
self.cause(ObligationCauseCode::WellFormed(None)),
|
||||
self.recursion_depth,
|
||||
self.param_env,
|
||||
pred_binder,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Inference variables are the complicated case, since we don't
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ trait Trait {
|
|||
struct Hold<T: ?Sized>(T);
|
||||
|
||||
trait Bound = Trait<Y = { Hold::<Self> }>;
|
||||
//~^ ERROR the constant `Hold::<Self>` is not of type `i32`
|
||||
|
||||
fn main() {
|
||||
let _: dyn Bound; //~ ERROR associated constant binding in trait object type mentions `Self`
|
||||
|
|
|
|||
|
|
@ -1,5 +1,17 @@
|
|||
error: the constant `Hold::<Self>` is not of type `i32`
|
||||
--> $DIR/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs:17:21
|
||||
|
|
||||
LL | trait Bound = Trait<Y = { Hold::<Self> }>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^ expected `i32`, found struct constructor
|
||||
|
|
||||
note: required by a const generic parameter in `Bound`
|
||||
--> $DIR/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs:17:21
|
||||
|
|
||||
LL | trait Bound = Trait<Y = { Hold::<Self> }>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^ required by this const generic parameter in `Bound`
|
||||
|
||||
error: associated constant binding in trait object type mentions `Self`
|
||||
--> $DIR/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs:20:12
|
||||
--> $DIR/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs:21:12
|
||||
|
|
||||
LL | trait Bound = Trait<Y = { Hold::<Self> }>;
|
||||
| -------------------- this binding mentions `Self`
|
||||
|
|
@ -7,5 +19,5 @@ LL | trait Bound = Trait<Y = { Hold::<Self> }>;
|
|||
LL | let _: dyn Bound;
|
||||
| ^^^^^^^^^ contains a mention of `Self`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
//! Check associated const binding with escaping bound vars doesn't cause ICE
|
||||
//! (#151642)
|
||||
//@ check-pass
|
||||
|
||||
#![feature(min_generic_const_args)]
|
||||
#![expect(incomplete_features)]
|
||||
|
||||
trait Trait2<'a> { type const ASSOC: i32; }
|
||||
fn g(_: for<'a> fn(Box<dyn Trait2<'a, ASSOC = 10>>)) {}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
//! Check that we correctly handle associated const bindings
|
||||
//! in `impl Trait` where the RHS is a const param (#151642).
|
||||
|
||||
#![feature(min_generic_const_args)]
|
||||
#![expect(incomplete_features)]
|
||||
|
||||
trait Trait { type const CT: bool; }
|
||||
|
||||
fn f<const N: i32>(_: impl Trait<CT = { N }>) {}
|
||||
//~^ ERROR the constant `N` is not of type `bool`
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
error: the constant `N` is not of type `bool`
|
||||
--> $DIR/wf-mismatch-1.rs:9:34
|
||||
|
|
||||
LL | fn f<const N: i32>(_: impl Trait<CT = { N }>) {}
|
||||
| ^^^^^^^^^^ expected `bool`, found `i32`
|
||||
|
|
||||
note: required by a const generic parameter in `f`
|
||||
--> $DIR/wf-mismatch-1.rs:9:34
|
||||
|
|
||||
LL | fn f<const N: i32>(_: impl Trait<CT = { N }>) {}
|
||||
| ^^^^^^^^^^ required by this const generic parameter in `f`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
//! Check that we correctly handle associated const bindings
|
||||
//! in `dyn Trait` where the RHS is a const param (#151642).
|
||||
|
||||
#![feature(min_generic_const_args)]
|
||||
#![expect(incomplete_features)]
|
||||
|
||||
trait Trait { type const CT: bool; }
|
||||
|
||||
fn f<const N: i32>() {
|
||||
let _: dyn Trait<CT = { N }>;
|
||||
//~^ ERROR the constant `N` is not of type `bool`
|
||||
}
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
error: the constant `N` is not of type `bool`
|
||||
--> $DIR/wf-mismatch-2.rs:10:12
|
||||
|
|
||||
LL | let _: dyn Trait<CT = { N }>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `i32`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
//! Check that we correctly handle associated const bindings
|
||||
//! where the RHS is a normalizable const projection (#151642).
|
||||
|
||||
#![feature(min_generic_const_args)]
|
||||
#![expect(incomplete_features)]
|
||||
|
||||
trait Trait { type const CT: bool; }
|
||||
|
||||
trait Bound { type const N: u32; }
|
||||
impl Bound for () { type const N: u32 = 0; }
|
||||
|
||||
fn f() { let _: dyn Trait<CT = { <() as Bound>::N }>; }
|
||||
//~^ ERROR the constant `0` is not of type `bool`
|
||||
fn g(_: impl Trait<CT = { <() as Bound>::N }>) {}
|
||||
//~^ ERROR the constant `0` is not of type `bool`
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
error: the constant `0` is not of type `bool`
|
||||
--> $DIR/wf-mismatch-3.rs:14:20
|
||||
|
|
||||
LL | fn g(_: impl Trait<CT = { <() as Bound>::N }>) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `u32`
|
||||
|
|
||||
note: required by a const generic parameter in `g`
|
||||
--> $DIR/wf-mismatch-3.rs:14:20
|
||||
|
|
||||
LL | fn g(_: impl Trait<CT = { <() as Bound>::N }>) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this const generic parameter in `g`
|
||||
|
||||
error: the constant `0` is not of type `bool`
|
||||
--> $DIR/wf-mismatch-3.rs:12:17
|
||||
|
|
||||
LL | fn f() { let _: dyn Trait<CT = { <() as Bound>::N }>; }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `u32`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue