Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix incorrect usage of EvaluatedToOk when evaluating TypeOutlives #91329

Merged
merged 1 commit into from
Dec 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
},

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)
Expand Down
55 changes: 55 additions & 0 deletions src/test/ui/traits/project-modulo-regions.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 11 additions & 0 deletions src/test/ui/traits/project-modulo-regions.with_clause.stderr
Original file line number Diff line number Diff line change
@@ -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

11 changes: 11 additions & 0 deletions src/test/ui/traits/project-modulo-regions.without_clause.stderr
Original file line number Diff line number Diff line change
@@ -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