-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
"Trait bounds were not satisfied" errors when inference is bailing #89418
Comments
They're not, see #89196 (comment). I think there's a diagnostic issue here but I'm not sure I can easily describe it. Actually, looking again at the output, I missed this part:
So IMO the only bug here is that this isn't pointing at the bound in the code, with a span. For that, we can compare calling a method via path vs method call syntax (try in playground): struct Foo;
impl Foo {
fn method<T>(self)
// bound that never holds, `Vec<T>` instead of `T` to bypass `_: Trait`.
where
Vec<T>: Copy // this line doesn't show up in lacks_span error output
{}
}
fn has_span() { Foo::method(Foo) }
fn lacks_span() { Foo.method() }
I'm not sure if this issue should be closed or changed, but I feel like the change is too big to keep it. |
@eddyb I think you're right that the core diagnostic (unable to determine |
At the moment, a very reasonable reaction to this error is "This error is incorrect and a compiler bug", and I think that's a pretty good indicator of a bad diagnostic, regardless of the specifics of it :) |
Note: @eddyb has a more reduced version of the error here, which is pointing to a normalization issue: But it may be possible to fix the diagnostics without fixing that. |
The E0277 without context is a Edit: it's in the call to
Edit 2: damn you two and your nerdsniping reasonable requests There's no change for the original case, though: |
I managed to get the following output for the original report, @Manishearth are there things you would change on it?
Ideally we could point at the specific bound for |
@estebank Seems a bit better and we should land that, but I think the core problem isn't quite solved: The trait is implemented, the compiler just doesn't realize it because it hasn't figured out Ultimately, the solution here was to tell the compiler what Also, why does it say "the implementation of |
In order to turn |
Totally fair |
Be more thorough in using `ItemObligation` and `BindingObligation` when evaluating obligations so that we can point at trait bounds that introduced unfulfilled obligations. We no longer incorrectly point at unrelated trait bounds (`substs-ppaux.verbose.stderr`). In particular, we now point at trait bounds on method calls. We no longer point at "obvious" obligation sources (we no longer have a note pointing at `Trait` saying "required by a bound in `Trait`", like in `associated-types-no-suitable-supertrait*`). Address part of rust-lang#89418.
…=nagisa Point at source of trait bound obligations in more places Be more thorough in using `ItemObligation` and `BindingObligation` when evaluating obligations so that we can point at trait bounds that introduced unfulfilled obligations. We no longer incorrectly point at unrelated trait bounds (`substs-ppaux.verbose.stderr`). In particular, we now point at trait bounds on method calls. We no longer point at "obvious" obligation sources (we no longer have a note pointing at `Trait` saying "required by a bound in `Trait`", like in `associated-types-no-suitable-supertrait*`). We no longer point at associated items (`ImplObligation`), as they didn't add any user actionable information, they just added noise. Address part of rust-lang#89418.
Update: looked a little bit deeper into this and this is what I got to:
Expect a follow up PR for that work, as the current changes improve things here but break others. |
…=nagisa Point at source of trait bound obligations in more places Be more thorough in using `ItemObligation` and `BindingObligation` when evaluating obligations so that we can point at trait bounds that introduced unfulfilled obligations. We no longer incorrectly point at unrelated trait bounds (`substs-ppaux.verbose.stderr`). In particular, we now point at trait bounds on method calls. We no longer point at "obvious" obligation sources (we no longer have a note pointing at `Trait` saying "required by a bound in `Trait`", like in `associated-types-no-suitable-supertrait*`). We no longer point at associated items (`ImplObligation`), as they didn't add any user actionable information, they just added noise. Address part of rust-lang#89418.
…=nagisa Point at source of trait bound obligations in more places Be more thorough in using `ItemObligation` and `BindingObligation` when evaluating obligations so that we can point at trait bounds that introduced unfulfilled obligations. We no longer incorrectly point at unrelated trait bounds (`substs-ppaux.verbose.stderr`). In particular, we now point at trait bounds on method calls. We no longer point at "obvious" obligation sources (we no longer have a note pointing at `Trait` saying "required by a bound in `Trait`", like in `associated-types-no-suitable-supertrait*`). We no longer point at associated items (`ImplObligation`), as they didn't add any user actionable information, they just added noise. Address part of rust-lang#89418.
…=nagisa Point at source of trait bound obligations in more places Be more thorough in using `ItemObligation` and `BindingObligation` when evaluating obligations so that we can point at trait bounds that introduced unfulfilled obligations. We no longer incorrectly point at unrelated trait bounds (`substs-ppaux.verbose.stderr`). In particular, we now point at trait bounds on method calls. We no longer point at "obvious" obligation sources (we no longer have a note pointing at `Trait` saying "required by a bound in `Trait`", like in `associated-types-no-suitable-supertrait*`). We no longer point at associated items (`ImplObligation`), as they didn't add any user actionable information, they just added noise. Address part of rust-lang#89418.
…=nagisa Point at source of trait bound obligations in more places Be more thorough in using `ItemObligation` and `BindingObligation` when evaluating obligations so that we can point at trait bounds that introduced unfulfilled obligations. We no longer incorrectly point at unrelated trait bounds (`substs-ppaux.verbose.stderr`). In particular, we now point at trait bounds on method calls. We no longer point at "obvious" obligation sources (we no longer have a note pointing at `Trait` saying "required by a bound in `Trait`", like in `associated-types-no-suitable-supertrait*`). We no longer point at associated items (`ImplObligation`), as they didn't add any user actionable information, they just added noise. Address part of rust-lang#89418.
…=nagisa Point at source of trait bound obligations in more places Be more thorough in using `ItemObligation` and `BindingObligation` when evaluating obligations so that we can point at trait bounds that introduced unfulfilled obligations. We no longer incorrectly point at unrelated trait bounds (`substs-ppaux.verbose.stderr`). In particular, we now point at trait bounds on method calls. We no longer point at "obvious" obligation sources (we no longer have a note pointing at `Trait` saying "required by a bound in `Trait`", like in `associated-types-no-suitable-supertrait*`). We no longer point at associated items (`ImplObligation`), as they didn't add any user actionable information, they just added noise. Address part of rust-lang#89418.
Be more thorough in using `ItemObligation` and `BindingObligation` when evaluating obligations so that we can point at trait bounds that introduced unfulfilled obligations. We no longer incorrectly point at unrelated trait bounds (`substs-ppaux.verbose.stderr`). In particular, we now point at trait bounds on method calls. We no longer point at "obvious" obligation sources (we no longer have a note pointing at `Trait` saying "required by a bound in `Trait`", like in `associated-types-no-suitable-supertrait*`). Address part of rust-lang#89418.
…agisa Point at source of trait bound obligations in more places Be more thorough in using `ItemObligation` and `BindingObligation` when evaluating obligations so that we can point at trait bounds that introduced unfulfilled obligations. We no longer incorrectly point at unrelated trait bounds (`substs-ppaux.verbose.stderr`). In particular, we now point at trait bounds on method calls. We no longer point at "obvious" obligation sources (we no longer have a note pointing at `Trait` saying "required by a bound in `Trait`", like in `associated-types-no-suitable-supertrait*`). We no longer point at associated items (`ImplObligation`), as they didn't add any user actionable information, they just added noise. Address part of rust-lang#89418.
Instead of probing for all possible impls that could have caused an `ImplObligation`, keep track of its `DefId` and obligation spans for accurate error reporting. Follow up to rust-lang#89580. Addresses rust-lang#89418. Remove some unnecessary clones. Tweak output for auto trait impl obligations.
…=oli-obk Properly track `ImplObligations` Instead of probing for all possible `impl`s that could have caused an `ImplObligation`, keep track of its `DefId` and obligation spans for accurate error reporting. Follow to rust-lang#89580. Addresses rust-lang#89418.
As of tomorrow's nightly, the output for the original report will be almost the same as #89418 (comment). eddyb's case is already handled in stable. |
Taking a quick peek at this again, it feels like we should probably identify bounds like |
@estebank Sounds plausible, but you might want to check with @rust-lang/types with regards to bounds that can be solved independent of generics - I vaguely remember that many years ago there were some plans around them, or at least certain subsets (including at least one feature gate - maybe it involved the word "trivial"?). |
Current output:
|
This is a bug in the old solver with its handling of ambiguous projections containing bound vars. It often treats them as if they were unnormalizable as it cannot eagerly replace them with inference variables. THe underlying issue will be fixed with the new trait solver: https://rust.godbolt.org/z/xGn8sbEE1 the higher ranked obligation |
Spun off of #89196
Code example
(playpen)
This fails to compile (needs beta or nightly to avoid #85636 , fixed by #85499 ) with the following error:
This error is incorrect, the trait bounds were satisfied. What's going on here is that the explicit type of
provider
is not known, and inference is unable to figure it out since there can be multipleM: MiniDataMarker
types for the sameM::Yokeable
value. The fix is to be explicit on line 59 and uselet provider = MiniStructProvider::<SimpleStruct> {
instead, which avoids this issue.Another version of this error can be seen in the code in this comment (playpen), which has a similar error due to inference bailing early (there are "Broken" and "Fixed" versions in the example so that you can see the specific thing inference needs to avoid the error)
cc @estebank
The text was updated successfully, but these errors were encountered: