From d18065d9978fd8c961d3cb58a6b22b9c33ba6dc8 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 26 Nov 2021 09:14:16 -0600 Subject: [PATCH] Only check for errors in predicate when skipping impl assembly Prior to PR #91205, checking for errors in the overall obligation would check checking the `ParamEnv`, due to an incorrect `super_visit_with` impl. With this bug fixed, we will now bail out of impl candidate assembly if the `ParamEnv` contains any error types. In practice, this appears to be overly conservative - when an error occurs early in compilation, we end up giving up early for some predicates that we could have successfully evaluated without overflow. By only checking for errors in the predicate itself, we avoid causing additional spurious 'type annotations needed' errors after a 'real' error has already occurred. With this PR, the diagnostic changes caused by PR #91205 are reverted. --- .../src/traits/select/candidate_assembly.rs | 5 ++++- .../issue-72787.min.stderr | 22 ++++++------------- .../generic_const_exprs/issue-72787.rs | 1 - src/test/ui/issues/issue-77919.rs | 2 +- src/test/ui/issues/issue-77919.stderr | 15 +++++++------ .../clippy/tests/ui/crashes/ice-6252.stderr | 15 +++++++------ 6 files changed, 28 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 0ff3611f8f80d..6e3e3b9b14480 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -536,7 +536,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // This helps us avoid overflow: see issue #72839 // Since compilation is already guaranteed to fail, this is just // to try to show the 'nicest' possible errors to the user. - if obligation.references_error() { + // We don't check for errors in the `ParamEnv` - in practice, + // it seems to cause us to be overly aggressive in deciding + // to give up searching for candidates, leading to spurious errors. + if obligation.predicate.references_error() { return; } diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr index 3a7095789336c..02dce4f7a97e8 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr @@ -1,5 +1,5 @@ error: generic parameters may not be used in const operations - --> $DIR/issue-72787.rs:12:17 + --> $DIR/issue-72787.rs:11:17 | LL | Condition<{ LHS <= RHS }>: True | ^^^ cannot perform const operation using `LHS` @@ -8,7 +8,7 @@ LL | Condition<{ LHS <= RHS }>: True = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/issue-72787.rs:12:24 + --> $DIR/issue-72787.rs:11:24 | LL | Condition<{ LHS <= RHS }>: True | ^^^ cannot perform const operation using `RHS` @@ -17,7 +17,7 @@ LL | Condition<{ LHS <= RHS }>: True = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/issue-72787.rs:26:25 + --> $DIR/issue-72787.rs:25:25 | LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, | ^ cannot perform const operation using `I` @@ -26,7 +26,7 @@ LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/issue-72787.rs:26:36 + --> $DIR/issue-72787.rs:25:36 | LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, | ^ cannot perform const operation using `J` @@ -35,15 +35,7 @@ LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error[E0283]: type annotations needed - --> $DIR/issue-72787.rs:10:38 - | -LL | impl True for IsLessOrEqual where - | ^^^^ cannot infer type for struct `IsLessOrEqual` - | - = note: cannot satisfy `IsLessOrEqual: True` - -error[E0283]: type annotations needed - --> $DIR/issue-72787.rs:22:26 + --> $DIR/issue-72787.rs:21:26 | LL | IsLessOrEqual: True, | ^^^^ cannot infer type for struct `IsLessOrEqual` @@ -51,13 +43,13 @@ LL | IsLessOrEqual: True, = note: cannot satisfy `IsLessOrEqual: True` error[E0283]: type annotations needed - --> $DIR/issue-72787.rs:22:26 + --> $DIR/issue-72787.rs:21:26 | LL | IsLessOrEqual: True, | ^^^^ cannot infer type for struct `IsLessOrEqual` | = note: cannot satisfy `IsLessOrEqual: True` -error: aborting due to 7 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-72787.rs b/src/test/ui/const-generics/generic_const_exprs/issue-72787.rs index 2ea5d634f6ef3..77ad57f0640fa 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-72787.rs +++ b/src/test/ui/const-generics/generic_const_exprs/issue-72787.rs @@ -8,7 +8,6 @@ pub struct Condition; pub trait True {} impl True for IsLessOrEqual where -//[min]~^ ERROR type annotations needed Condition<{ LHS <= RHS }>: True //[min]~^ Error generic parameters may not be used in const operations //[min]~| Error generic parameters may not be used in const operations diff --git a/src/test/ui/issues/issue-77919.rs b/src/test/ui/issues/issue-77919.rs index 6e597b7669abc..966d76d148af3 100644 --- a/src/test/ui/issues/issue-77919.rs +++ b/src/test/ui/issues/issue-77919.rs @@ -10,4 +10,4 @@ struct Multiply { } impl TypeVal for Multiply where N: TypeVal {} //~^ ERROR cannot find type `VAL` in this scope -//~| ERROR type annotations needed +//~| ERROR not all trait items implemented, missing: `VAL` diff --git a/src/test/ui/issues/issue-77919.stderr b/src/test/ui/issues/issue-77919.stderr index f98556bc72f47..97bd5ab36b65d 100644 --- a/src/test/ui/issues/issue-77919.stderr +++ b/src/test/ui/issues/issue-77919.stderr @@ -17,15 +17,16 @@ LL | impl TypeVal for Multiply where N: TypeVal {} | | | help: you might be missing a type parameter: `, VAL` -error[E0283]: type annotations needed - --> $DIR/issue-77919.rs:11:12 +error[E0046]: not all trait items implemented, missing: `VAL` + --> $DIR/issue-77919.rs:11:1 | +LL | const VAL: T; + | ------------- `VAL` from trait +... LL | impl TypeVal for Multiply where N: TypeVal {} - | ^^^^^^^^^^^^^^ cannot infer type for struct `Multiply` - | - = note: cannot satisfy `Multiply: TypeVal` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation error: aborting due to 3 previous errors -Some errors have detailed explanations: E0283, E0412. -For more information about an error, try `rustc --explain E0283`. +Some errors have detailed explanations: E0046, E0412. +For more information about an error, try `rustc --explain E0046`. diff --git a/src/tools/clippy/tests/ui/crashes/ice-6252.stderr b/src/tools/clippy/tests/ui/crashes/ice-6252.stderr index abca7af30a006..c8239897f3abb 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-6252.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-6252.stderr @@ -21,15 +21,16 @@ LL | impl TypeVal for Multiply where N: TypeVal {} | | | help: you might be missing a type parameter: `, VAL` -error[E0283]: type annotations needed - --> $DIR/ice-6252.rs:10:12 +error[E0046]: not all trait items implemented, missing: `VAL` + --> $DIR/ice-6252.rs:10:1 | +LL | const VAL: T; + | ------------- `VAL` from trait +... LL | impl TypeVal for Multiply where N: TypeVal {} - | ^^^^^^^^^^^^^^ cannot infer type for struct `Multiply` - | - = note: cannot satisfy `Multiply: TypeVal` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation error: aborting due to 3 previous errors -Some errors have detailed explanations: E0283, E0412. -For more information about an error, try `rustc --explain E0283`. +Some errors have detailed explanations: E0046, E0412. +For more information about an error, try `rustc --explain E0046`.