Skip to content

Commit

Permalink
Don't bail out of trait selection when predicate references an error
Browse files Browse the repository at this point in the history
Fixes rust-lang#72590

With PR rust-lang#70551, observing a `ty::Error` guarantees that compilation is
going to fail. Therefore, there are no soundness impliciations to
continuing on when we encounter a `ty::Error` - we can only affect
whether or not additional error messags are emitted.

By not bailing out, we avoid incorrectly determining that types are
`!Sized` when a type error is present, which allows us to avoid emitting
additional spurious error messages.

The original comment mentioned this code being shared by coherence -
howver, this change resulted in no diagnostic changes in any of the
existing tests.
  • Loading branch information
Aaron1011 committed May 26, 2020
1 parent aeca4d6 commit 1c30c9e
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 11 deletions.
11 changes: 0 additions & 11 deletions src/librustc_trait_selection/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1040,17 +1040,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut self,
stack: &TraitObligationStack<'o, 'tcx>,
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
if stack.obligation.predicate.references_error() {
// If we encounter a `Error`, we generally prefer the
// most "optimistic" result in response -- that is, the
// one least likely to report downstream errors. But
// because this routine is shared by coherence and by
// trait selection, there isn't an obvious "right" choice
// here in that respect, so we opt to just return
// ambiguity and let the upstream clients sort it out.
return Ok(None);
}

if let Some(conflict) = self.is_knowable(stack) {
debug!("coherence stage: not knowable");
if self.intercrate_ambiguity_causes.is_some() {
Expand Down
22 changes: 22 additions & 0 deletions src/test/ui/async-await/issue-72590-type-error-sized.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Regression test for issue #72590
// Tests that we don't emit a spurious "size cannot be statically determined" error
// edition:2018

struct Foo {
foo: Nonexistent, //~ ERROR cannot find
other: str
}

struct Bar {
test: Missing //~ ERROR cannot find
}

impl Foo {
async fn frob(self) {} //~ ERROR the size
}

impl Bar {
async fn myfn(self) {}
}

fn main() {}
28 changes: 28 additions & 0 deletions src/test/ui/async-await/issue-72590-type-error-sized.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
error[E0412]: cannot find type `Nonexistent` in this scope
--> $DIR/issue-72590-type-error-sized.rs:6:10
|
LL | foo: Nonexistent,
| ^^^^^^^^^^^ not found in this scope

error[E0412]: cannot find type `Missing` in this scope
--> $DIR/issue-72590-type-error-sized.rs:11:11
|
LL | test: Missing
| ^^^^^^^ not found in this scope

error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/issue-72590-type-error-sized.rs:15:19
|
LL | async fn frob(self) {}
| ^^^^ doesn't have a size known at compile-time
|
= help: within `Foo`, the trait `std::marker::Sized` is not implemented for `str`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required because it appears within the type `Foo`
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0277, E0412.
For more information about an error, try `rustc --explain E0277`.

0 comments on commit 1c30c9e

Please sign in to comment.