Rollup merge of #91329 - Aaron1011:modulo-regions-test, r=jackh726
Fix incorrect usage of `EvaluatedToOk` when evaluating `TypeOutlives` A global predicate is not guarnatenteed to outlive all regions. If the predicate involves late-bound regions, then it may fail to outlive other regions (e.g. `for<'b> &'b bool: 'static` does not hold) We now only produce `EvaluatedToOk` when a global predicate has no late-bound regions - in that case, the ony region that can be present in the type is 'static
This commit is contained in:
commit
fd6e66f423
@ -521,7 +521,11 @@ fn evaluate_predicate_recursively<'o>(
|
||||
},
|
||||
|
||||
ty::PredicateKind::TypeOutlives(pred) => {
|
||||
if pred.0.is_known_global() {
|
||||
// A global type with no late-bound regions can only
|
||||
// contain the "'static" lifetime (any other lifetime
|
||||
// would either be late-bound or local), so it is guaranteed
|
||||
// to outlive any other lifetime
|
||||
if pred.0.is_global(self.infcx.tcx) && !pred.0.has_late_bound_regions() {
|
||||
Ok(EvaluatedToOk)
|
||||
} else {
|
||||
Ok(EvaluatedToOkModuloRegions)
|
||||
|
55
src/test/ui/traits/project-modulo-regions.rs
Normal file
55
src/test/ui/traits/project-modulo-regions.rs
Normal file
@ -0,0 +1,55 @@
|
||||
// revisions: with_clause without_clause
|
||||
// Tests that `EvaluatedToOkModuloRegions` from a projection sub-obligation
|
||||
// is correctly propagated
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
trait MyTrait {
|
||||
type Assoc;
|
||||
}
|
||||
|
||||
struct MyStruct;
|
||||
|
||||
impl MyTrait for MyStruct {
|
||||
// Evaluating this projection will result in `EvaluatedToOkModuloRegions`
|
||||
// (when `with_clause` is enabled)
|
||||
type Assoc = <Bar as MyTrait>::Assoc;
|
||||
}
|
||||
|
||||
struct Bar;
|
||||
|
||||
// The `where` clause on this impl will cause us to produce `EvaluatedToOkModuloRegions`
|
||||
// when evaluating a projection involving this impl
|
||||
#[cfg(with_clause)]
|
||||
impl MyTrait for Bar where for<'b> &'b (): 'b {
|
||||
type Assoc = bool;
|
||||
}
|
||||
|
||||
// This impl tests that the `EvaluatedToOkModuoRegions` result that we get
|
||||
// is really due to the `where` clause on the `with_clause` impl
|
||||
#[cfg(without_clause)]
|
||||
impl MyTrait for Bar {
|
||||
type Assoc = bool;
|
||||
}
|
||||
|
||||
// The implementation of `#[rustc_evaluate_where_clauses]` doesn't perform
|
||||
// normalization, so we need to place the projection predicate behind a normal
|
||||
// trait predicate
|
||||
struct Helper {}
|
||||
trait HelperTrait {}
|
||||
impl HelperTrait for Helper where <MyStruct as MyTrait>::Assoc: Sized {}
|
||||
|
||||
// Evaluating this 'where' clause will (recursively) end up evaluating
|
||||
// `for<'b> &'b (): 'b`, which will produce `EvaluatedToOkModuloRegions`
|
||||
#[rustc_evaluate_where_clauses]
|
||||
fn test(val: MyStruct) where Helper: HelperTrait {
|
||||
panic!()
|
||||
}
|
||||
|
||||
fn foo(val: MyStruct) {
|
||||
test(val);
|
||||
//[with_clause]~^ ERROR evaluate(Binder(TraitPredicate(<Helper as HelperTrait>, polarity:Positive), [])) = Ok(EvaluatedToOkModuloRegions)
|
||||
//[without_clause]~^^ ERROR evaluate(Binder(TraitPredicate(<Helper as HelperTrait>, polarity:Positive), [])) = Ok(EvaluatedToOk)
|
||||
}
|
||||
|
||||
fn main() {}
|
11
src/test/ui/traits/project-modulo-regions.with_clause.stderr
Normal file
11
src/test/ui/traits/project-modulo-regions.with_clause.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error: evaluate(Binder(TraitPredicate(<Helper as HelperTrait>, polarity:Positive), [])) = Ok(EvaluatedToOkModuloRegions)
|
||||
--> $DIR/project-modulo-regions.rs:50:5
|
||||
|
|
||||
LL | fn test(val: MyStruct) where Helper: HelperTrait {
|
||||
| ----------- predicate
|
||||
...
|
||||
LL | test(val);
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -0,0 +1,11 @@
|
||||
error: evaluate(Binder(TraitPredicate(<Helper as HelperTrait>, polarity:Positive), [])) = Ok(EvaluatedToOk)
|
||||
--> $DIR/project-modulo-regions.rs:50:5
|
||||
|
|
||||
LL | fn test(val: MyStruct) where Helper: HelperTrait {
|
||||
| ----------- predicate
|
||||
...
|
||||
LL | test(val);
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Reference in New Issue
Block a user