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

rustc fails to see a bound that is present, but also requires that the bound not be present #41118

Open
Twey opened this issue Apr 6, 2017 · 2 comments
Labels
A-associated-items Area: Associated items (types, constants & functions) A-lazy-normalization Area: Lazy normalization (tracking issue: #60471) A-trait-system Area: Trait system C-bug Category: This is a bug. fixed-by-next-solver Fixed by the next-generation trait solver, `-Znext-solver`. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Twey
Copy link

Twey commented Apr 6, 2017

In certain cases, rustc will emit an error message on what appears to be valid code, claiming that

  • a bound that is present is not present, and must be present
  • but the bound is present and must not be present

Here is a MWE (or playground):

trait Foo<T> { type Quux; }
trait Bar<B> {
    type Baz;
    fn arthur() where B: Foo<Self::Baz>, B::Quux: Send;
}
impl<B> Bar<B> for () {
    type Baz = ();
    fn arthur() where B: Foo<()>, B::Quux: Send { }
}

This produces the pair of errors:

rustc 1.16.0 (30cf806ef 2017-03-10)
error[E0277]: the trait bound `B: Foo<()>` is not satisfied
 --> <anon>:8:5
  |
8 |     fn arthur() where B: Foo<()>, B::Quux: Send { }
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo<()>` is not implemented for `B`
  |
  = help: consider adding a `where B: Foo<()>` bound

error[E0276]: impl has stricter requirements than trait
 --> <anon>:8:5
  |
4 |     fn arthur() where B: Foo<Self::Baz>, B::Quux: Send;
  |     --------------------------------------------------- definition of `arthur` from trait
...
8 |     fn arthur() where B: Foo<()>, B::Quux: Send { }
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `B: Foo<()>`

error: aborting due to 2 previous errors
@Twey
Copy link
Author

Twey commented Apr 6, 2017

It's interesting to note that the bound B::Quux: Send is an integral part of this MWE: removing it bypasses the error.

@Mark-Simulacrum Mark-Simulacrum added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Jun 20, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 27, 2017
@jyn514 jyn514 added the A-trait-system Area: Trait system label Jul 7, 2021
@compiler-errors compiler-errors added the fixed-by-next-solver Fixed by the next-generation trait solver, `-Znext-solver`. label Sep 27, 2023
@fmease fmease added the A-associated-items Area: Associated items (types, constants & functions) label Oct 19, 2023
@lcnr lcnr added the A-lazy-normalization Area: Lazy normalization (tracking issue: #60471) label Nov 13, 2023
@lcnr
Copy link
Contributor

lcnr commented Nov 13, 2023

afaict this is caused by our current approach to param env normalization, see

// HACK: we are trying to normalize the param-env inside *itself*. The problem is that
// normalization expects its param-env to be already normalized, which means we have
// a circularity.
//
// The way we handle this is by normalizing the param-env inside an unnormalized version
// of the param-env, which means that if the param-env contains unnormalized projections,
// we'll have some normalization failures. This is unfortunate.
//
// Lazy normalization would basically handle this by treating just the
// normalizing-a-trait-ref-requires-itself cycles as evaluation failures.
//
// Inferred outlives bounds can create a lot of `TypeOutlives` predicates for associated
// types, so to make the situation less bad, we normalize all the predicates *but*
// the `TypeOutlives` predicates first inside the unnormalized parameter environment, and
// then we normalize the `TypeOutlives` bounds inside the normalized parameter environment.
//
// This works fairly well because trait matching does not actually care about param-env
// TypeOutlives predicates - these are normally used by regionck.

fixed in the new solver because we defer projection equality there, so the unnormalized B: Foo<Self::Baz> candidate now applies to the B: Foo<()> goal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-associated-items Area: Associated items (types, constants & functions) A-lazy-normalization Area: Lazy normalization (tracking issue: #60471) A-trait-system Area: Trait system C-bug Category: This is a bug. fixed-by-next-solver Fixed by the next-generation trait solver, `-Znext-solver`. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants