diff --git a/src/librustc_trait_selection/traits/select/mod.rs b/src/librustc_trait_selection/traits/select/mod.rs index def99a7b5b52..7ebf30f61c09 100644 --- a/src/librustc_trait_selection/traits/select/mod.rs +++ b/src/librustc_trait_selection/traits/select/mod.rs @@ -1104,6 +1104,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // who might care about this case, like coherence, should use // that function). if candidates.is_empty() { + // If there's an error type, 'downgrade' our result from + // `Err(Unimplemented)` to `Ok(None)`. This helps us avoid + // emitting additional spurious errors, since we're guaranteed + // to have emitted at least one. + if stack.obligation.references_error() { + debug!("no results for error type, treating as ambiguous"); + return Ok(None); + } return Err(Unimplemented); } diff --git a/src/test/ui/impl-trait/auto-trait-leak.rs b/src/test/ui/impl-trait/auto-trait-leak.rs index a6012835f441..087f4582b21c 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.rs +++ b/src/test/ui/impl-trait/auto-trait-leak.rs @@ -11,8 +11,6 @@ fn main() { // return type, which can't depend on the obligation. fn cycle1() -> impl Clone { //~^ ERROR cycle detected - //~| ERROR cycle detected - //~| ERROR cycle detected send(cycle2().clone()); //~^ ERROR cannot be sent between threads safely diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr index 64d02f07048e..679b26efe593 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak.stderr @@ -36,37 +36,37 @@ LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... note: ...which requires computing type of `cycle2::{{opaque}}#0`... - --> $DIR/auto-trait-leak.rs:22:16 + --> $DIR/auto-trait-leak.rs:20:16 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^ note: ...which requires borrow-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 + --> $DIR/auto-trait-leak.rs:20:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires processing `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 + --> $DIR/auto-trait-leak.rs:20:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires processing MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 + --> $DIR/auto-trait-leak.rs:20:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires unsafety-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 + --> $DIR/auto-trait-leak.rs:20:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires building MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 + --> $DIR/auto-trait-leak.rs:20:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires type-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 + --> $DIR/auto-trait-leak.rs:20:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -84,178 +84,8 @@ LL | | Rc::new(String::from("foo")) LL | | } | |_^ -error[E0391]: cycle detected when computing type of `cycle1::{{opaque}}#0` - --> $DIR/auto-trait-leak.rs:12:16 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^ - | -note: ...which requires borrow-checking `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing MIR for `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires unsafety-checking `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires building MIR for `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires type-checking `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... -note: ...which requires computing type of `cycle2::{{opaque}}#0`... - --> $DIR/auto-trait-leak.rs:22:16 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^ -note: ...which requires borrow-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires unsafety-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires building MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires type-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires computing type of `cycle1::{{opaque}}#0`, completing the cycle -note: cycle used when checking item types in top-level module - --> $DIR/auto-trait-leak.rs:1:1 - | -LL | / use std::cell::Cell; -LL | | use std::rc::Rc; -LL | | -LL | | fn send(_: T) {} -... | -LL | | Rc::new(String::from("foo")) -LL | | } - | |_^ - -error[E0391]: cycle detected when computing type of `cycle1::{{opaque}}#0` - --> $DIR/auto-trait-leak.rs:12:16 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^ - | -note: ...which requires borrow-checking `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing MIR for `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires unsafety-checking `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires building MIR for `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires type-checking `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... -note: ...which requires computing type of `cycle2::{{opaque}}#0`... - --> $DIR/auto-trait-leak.rs:22:16 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^ -note: ...which requires borrow-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires unsafety-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires building MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires type-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:22:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires computing type of `cycle1::{{opaque}}#0`, completing the cycle -note: cycle used when checking item types in top-level module - --> $DIR/auto-trait-leak.rs:1:1 - | -LL | / use std::cell::Cell; -LL | | use std::rc::Rc; -LL | | -LL | | fn send(_: T) {} -... | -LL | | Rc::new(String::from("foo")) -LL | | } - | |_^ - error[E0277]: `std::rc::Rc` cannot be sent between threads safely - --> $DIR/auto-trait-leak.rs:16:5 + --> $DIR/auto-trait-leak.rs:14:5 | LL | fn send(_: T) {} | ---- required by this bound in `send` @@ -269,7 +99,7 @@ LL | fn cycle2() -> impl Clone { = help: within `impl std::clone::Clone`, the trait `std::marker::Send` is not implemented for `std::rc::Rc` = note: required because it appears within the type `impl std::clone::Clone` -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0277, E0391. For more information about an error, try `rustc --explain E0277`.