Rollup merge of #127568 - lcnr:undo-leakcheck, r=oli-obk

instantiate higher ranked goals in candidate selection again

This reverts #119820 as that PR has a significant impact and breaks code which *feels like it should work*. The impact ended up being larger than we expected during the FCP and we've ended up with some ideas for how we can work around this issue in the next solver. This has been discussed in the previous high bandwidth t-types meeting: https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/2024-07-09.20high.20bandwidth.20meeting.

We'll therefore keep this inconsistency between the two solvers for now and will have to deal with it before stabilizating the use of the new solver outside of coherence: https://github.com/rust-lang/trait-system-refactor-initiative/issues/120.

fixes #125194 after a beta-backport.

The pattern which is more widely used than expected and feels like it should work, especially without deep knowledge of the type system is
```rust
trait Trait<'a> {}
impl<'a, T> Trait<'a> for T {}

fn trait_bound<T: for<'a> Trait<'a>>() {}

// A function with a where-bound which is more restrictive than the impl.
fn function1<T: Trait<'static>>() {
    // stable: ok
    // with #119820: error as we prefer the where-bound over the impl
    // with this PR: back to ok
    trait_bound::<T>();
}

```

r? `@rust-lang/types`
This commit is contained in:
Matthias Krüger 2024-07-10 17:54:28 +02:00 committed by GitHub
commit 7faef5d5ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 122 additions and 300 deletions

View File

@ -64,20 +64,6 @@
mod candidate_assembly;
mod confirmation;
/// Whether to consider the binder of higher ranked goals for the `leak_check` when
/// evaluating higher-ranked goals. See #119820 for more info.
///
/// While this is a bit hacky, it is necessary to match the behavior of the new solver:
/// We eagerly instantiate binders in the new solver, outside of candidate selection, so
/// the leak check inside of candidates does not consider any bound vars from the higher
/// ranked goal. However, we do exit the binder once we're completely finished with a goal,
/// so the leak-check can be used in evaluate by causing nested higher-ranked goals to fail.
#[derive(Debug, Copy, Clone)]
enum LeakCheckHigherRankedGoal {
No,
Yes,
}
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum IntercrateAmbiguityCause<'tcx> {
DownstreamCrate { trait_ref: ty::TraitRef<'tcx>, self_ty: Option<Ty<'tcx>> },
@ -402,10 +388,7 @@ fn candidate_from_obligation_no_cache<'o>(
let mut no_candidates_apply = true;
for c in candidate_set.vec.iter() {
if self
.evaluate_candidate(stack, c, LeakCheckHigherRankedGoal::No)?
.may_apply()
{
if self.evaluate_candidate(stack, c)?.may_apply() {
no_candidates_apply = false;
break;
}
@ -476,7 +459,7 @@ fn candidate_from_obligation_no_cache<'o>(
// is needed for specialization. Propagate overflow if it occurs.
let mut candidates = candidates
.into_iter()
.map(|c| match self.evaluate_candidate(stack, &c, LeakCheckHigherRankedGoal::No) {
.map(|c| match self.evaluate_candidate(stack, &c) {
Ok(eval) if eval.may_apply() => {
Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval }))
}
@ -566,7 +549,7 @@ pub fn evaluate_root_obligation(
obligation: &PredicateObligation<'tcx>,
) -> Result<EvaluationResult, OverflowError> {
debug_assert!(!self.infcx.next_trait_solver());
self.evaluation_probe(|this, _outer_universe| {
self.evaluation_probe(|this| {
let goal =
this.infcx.resolve_vars_if_possible((obligation.predicate, obligation.param_env));
let mut result = this.evaluate_predicate_recursively(
@ -589,11 +572,11 @@ pub fn evaluate_root_obligation(
/// `op`, but this can be overwritten if necessary.
fn evaluation_probe(
&mut self,
op: impl FnOnce(&mut Self, &mut ty::UniverseIndex) -> Result<EvaluationResult, OverflowError>,
op: impl FnOnce(&mut Self) -> Result<EvaluationResult, OverflowError>,
) -> Result<EvaluationResult, OverflowError> {
self.infcx.probe(|snapshot| -> Result<EvaluationResult, OverflowError> {
let mut outer_universe = self.infcx.universe();
let result = op(self, &mut outer_universe)?;
let outer_universe = self.infcx.universe();
let result = op(self)?;
match self.infcx.leak_check(outer_universe, Some(snapshot)) {
Ok(()) => {}
@ -1254,7 +1237,7 @@ fn evaluate_stack<'o>(
}
match self.candidate_from_obligation(stack) {
Ok(Some(c)) => self.evaluate_candidate(stack, &c, LeakCheckHigherRankedGoal::Yes),
Ok(Some(c)) => self.evaluate_candidate(stack, &c),
Ok(None) => Ok(EvaluatedToAmbig),
Err(Overflow(OverflowError::Canonical)) => Err(OverflowError::Canonical),
Err(..) => Ok(EvaluatedToErr),
@ -1279,10 +1262,6 @@ pub(crate) fn coinductive_match<I>(&mut self, mut cycle: I) -> bool
/// Further evaluates `candidate` to decide whether all type parameters match and whether nested
/// obligations are met. Returns whether `candidate` remains viable after this further
/// scrutiny.
///
/// Depending on the value of [LeakCheckHigherRankedGoal], we may ignore the binder of the goal
/// when eagerly detecting higher ranked region errors via the `leak_check`. See that enum for
/// more info.
#[instrument(
level = "debug",
skip(self, stack),
@ -1293,25 +1272,9 @@ fn evaluate_candidate<'o>(
&mut self,
stack: &TraitObligationStack<'o, 'tcx>,
candidate: &SelectionCandidate<'tcx>,
leak_check_higher_ranked_goal: LeakCheckHigherRankedGoal,
) -> Result<EvaluationResult, OverflowError> {
let mut result = self.evaluation_probe(|this, outer_universe| {
// We eagerly instantiate higher ranked goals to prevent universe errors
// from impacting candidate selection. This matches the behavior of the new
// solver. This slightly weakens type inference.
//
// In case there are no unresolved type or const variables this
// should still not be necessary to select a unique impl as any overlap
// relying on a universe error from higher ranked goals should have resulted
// in an overlap error in coherence.
let p = self.infcx.enter_forall_and_leak_universe(stack.obligation.predicate);
let obligation = stack.obligation.with(this.tcx(), ty::Binder::dummy(p));
match leak_check_higher_ranked_goal {
LeakCheckHigherRankedGoal::No => *outer_universe = self.infcx.universe(),
LeakCheckHigherRankedGoal::Yes => {}
}
match this.confirm_candidate(&obligation, candidate.clone()) {
let mut result = self.evaluation_probe(|this| {
match this.confirm_candidate(stack.obligation, candidate.clone()) {
Ok(selection) => {
debug!(?selection);
this.evaluate_predicates_recursively(
@ -1731,19 +1694,14 @@ fn match_normalize_trait_ref(
})
.map_err(|_| ())
}
fn where_clause_may_apply<'o>(
&mut self,
stack: &TraitObligationStack<'o, 'tcx>,
where_clause_trait_ref: ty::PolyTraitRef<'tcx>,
) -> Result<EvaluationResult, OverflowError> {
self.evaluation_probe(|this, outer_universe| {
// Eagerly instantiate higher ranked goals.
//
// See the comment in `evaluate_candidate` to see why.
let p = self.infcx.enter_forall_and_leak_universe(stack.obligation.predicate);
let obligation = stack.obligation.with(this.tcx(), ty::Binder::dummy(p));
*outer_universe = self.infcx.universe();
match this.match_where_clause_trait_ref(&obligation, where_clause_trait_ref) {
self.evaluation_probe(|this| {
match this.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) {
Ok(obligations) => this.evaluate_predicates_recursively(stack.list(), obligations),
Err(()) => Ok(EvaluatedToErr),
}

View File

@ -0,0 +1,23 @@
error[E0277]: the trait bound `for<'a> &'a &T: Trait` is not satisfied
--> $DIR/candidate-from-env-universe-err-1.rs:27:16
|
LL | hr_bound::<&T>();
| ^^ the trait `for<'a> Trait` is not implemented for `&'a &T`
|
note: required by a bound in `hr_bound`
--> $DIR/candidate-from-env-universe-err-1.rs:14:20
|
LL | fn hr_bound<T>()
| -------- required by a bound in this function
LL | where
LL | for<'a> &'a T: Trait,
| ^^^^^ required by this bound in `hr_bound`
help: consider removing the leading `&`-reference
|
LL - hr_bound::<&T>();
LL + hr_bound::<T>();
|
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View File

@ -1,3 +1,7 @@
//@ revisions: old next
//@[next] compile-flags: -Znext-solver
//@[old] check-pass
// cc #119820
trait Trait {}
@ -21,8 +25,7 @@ fn foo<T>()
// the leak check both candidates may apply and we prefer the
// `param_env` candidate in winnowing.
hr_bound::<&T>();
//~^ ERROR the parameter type `T` may not live long enough
//~| ERROR implementation of `Trait` is not general enough
//[next]~^ ERROR the trait bound `for<'a> &'a &T: Trait` is not satisfied
}
fn main() {}

View File

@ -1,26 +0,0 @@
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/candidate-from-env-universe-err-1.rs:23:5
|
LL | hr_bound::<&T>();
| ^^^^^^^^^^^^^^
| |
| the parameter type `T` must be valid for the static lifetime...
| ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound
|
LL | T: Trait + 'static,
| +++++++++
error: implementation of `Trait` is not general enough
--> $DIR/candidate-from-env-universe-err-1.rs:23:5
|
LL | hr_bound::<&T>();
| ^^^^^^^^^^^^^^ implementation of `Trait` is not general enough
|
= note: `Trait` would have to be implemented for the type `&'0 &T`, for any lifetime `'0`...
= note: ...but `Trait` is actually implemented for the type `&'1 &'1 T`, for some specific lifetime `'1`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0310`.

View File

@ -1,25 +0,0 @@
error: lifetime may not live long enough
--> $DIR/candidate-from-env-universe-err-2.rs:14:5
|
LL | fn not_hr<'a, T: for<'b> Trait<'a, 'b> + OtherTrait<'static>>() {
| -- lifetime `'a` defined here
LL | impl_hr::<T>();
| ^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
note: due to current limitations in the borrow checker, this implies a `'static` lifetime
--> $DIR/candidate-from-env-universe-err-2.rs:11:19
|
LL | fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {}
| ^^^^^^^^^^^^^^^^^^^^^
error: implementation of `Trait` is not general enough
--> $DIR/candidate-from-env-universe-err-2.rs:14:5
|
LL | impl_hr::<T>();
| ^^^^^^^^^^^^ implementation of `Trait` is not general enough
|
= note: `T` must implement `Trait<'0, '_>`, for any lifetime `'0`...
= note: ...but it actually implements `Trait<'1, '_>`, for some specific lifetime `'1`
error: aborting due to 2 previous errors

View File

@ -1,11 +1,11 @@
error[E0277]: the trait bound `for<'a> T: Trait<'a, '_>` is not satisfied
--> $DIR/candidate-from-env-universe-err-2.rs:14:5
--> $DIR/candidate-from-env-universe-err-2.rs:15:5
|
LL | impl_hr::<T>();
| ^^^^^^^^^^^^^^ the trait `for<'a> Trait<'a, '_>` is not implemented for `T`
|
note: required by a bound in `impl_hr`
--> $DIR/candidate-from-env-universe-err-2.rs:11:19
--> $DIR/candidate-from-env-universe-err-2.rs:12:19
|
LL | fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {}
| ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impl_hr`

View File

@ -1,26 +0,0 @@
error: lifetime may not live long enough
--> $DIR/candidate-from-env-universe-err-2.rs:14:5
|
LL | fn not_hr<'a, T: for<'b> Trait<'a, 'b> + OtherTrait<'static>>() {
| -- lifetime `'a` defined here
LL | impl_hr::<T>();
| ^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
note: due to current limitations in the borrow checker, this implies a `'static` lifetime
--> $DIR/candidate-from-env-universe-err-2.rs:11:19
|
LL | fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {}
| ^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> $DIR/candidate-from-env-universe-err-2.rs:14:5
|
LL | impl_hr::<T>();
| ^^^^^^^^^^^^ one type is more general than the other
|
= note: expected trait `for<'a> Trait<'a, '_>`
found trait `for<'b> Trait<'_, 'b>`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@ -1,5 +1,6 @@
//@ revisions: current next
//@[next] compile-flags: -Znext-solver
//@[current] check-pass
// cc #119820
@ -13,8 +14,6 @@ fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {}
fn not_hr<'a, T: for<'b> Trait<'a, 'b> + OtherTrait<'static>>() {
impl_hr::<T>();
//[next]~^ ERROR the trait bound `for<'a> T: Trait<'a, '_>` is not satisfied
//[current]~^^ERROR lifetime may not live long enough
//[current]~| ERROR implementation of `Trait` is not general enough
}
fn main() {}

View File

@ -1,23 +1,5 @@
error: implementation of `Trait` is not general enough
--> $DIR/candidate-from-env-universe-err-project.rs:28:5
|
LL | trait_bound::<T>();
| ^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough
|
= note: `T` must implement `Trait<'0>`, for any lifetime `'0`...
= note: ...but it actually implements `Trait<'static>`
error: implementation of `Trait` is not general enough
--> $DIR/candidate-from-env-universe-err-project.rs:39:5
|
LL | projection_bound::<T>();
| ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough
|
= note: `T` must implement `Trait<'0>`, for any lifetime `'0`...
= note: ...but it actually implements `Trait<'static>`
error[E0308]: mismatched types
--> $DIR/candidate-from-env-universe-err-project.rs:39:5
--> $DIR/candidate-from-env-universe-err-project.rs:38:5
|
LL | projection_bound::<T>();
| ^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
@ -31,7 +13,7 @@ LL | fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
| ^^^^^^^^^^^^^
error[E0308]: mismatched types
--> $DIR/candidate-from-env-universe-err-project.rs:55:30
--> $DIR/candidate-from-env-universe-err-project.rs:53:30
|
LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
@ -40,7 +22,7 @@ LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
found associated type `<T as Trait<'a>>::Assoc`
error[E0308]: mismatched types
--> $DIR/candidate-from-env-universe-err-project.rs:55:30
--> $DIR/candidate-from-env-universe-err-project.rs:53:30
|
LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
@ -49,6 +31,6 @@ LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
found associated type `<T as Trait<'a>>::Assoc`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 5 previous errors
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@ -15,7 +15,7 @@ LL | fn function1<T: Trait<'static> + for<'a> Trait<'a>>() {
| +++++++++++++++++++
error[E0277]: the trait bound `for<'a> T: Trait<'a>` is not satisfied
--> $DIR/candidate-from-env-universe-err-project.rs:39:24
--> $DIR/candidate-from-env-universe-err-project.rs:38:24
|
LL | projection_bound::<T>();
| ^ the trait `for<'a> Trait<'a>` is not implemented for `T`
@ -31,7 +31,7 @@ LL | fn function2<T: Trait<'static, Assoc = usize> + for<'a> Trait<'a>>() {
| +++++++++++++++++++
error[E0271]: type mismatch resolving `<T as Trait<'a>>::Assoc == usize`
--> $DIR/candidate-from-env-universe-err-project.rs:39:24
--> $DIR/candidate-from-env-universe-err-project.rs:38:24
|
LL | projection_bound::<T>();
| ^ type mismatch resolving `<T as Trait<'a>>::Assoc == usize`
@ -48,13 +48,13 @@ LL | fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
| ^^^^^^^^^^^^^ required by this bound in `projection_bound`
error: higher-ranked subtype error
--> $DIR/candidate-from-env-universe-err-project.rs:55:30
--> $DIR/candidate-from-env-universe-err-project.rs:53:30
|
LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: higher-ranked subtype error
--> $DIR/candidate-from-env-universe-err-project.rs:55:30
--> $DIR/candidate-from-env-universe-err-project.rs:53:30
|
LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -1,8 +1,8 @@
//@ revisions: next current
//@[next] compile-flags: -Znext-solver
// cc #119820 the previous behavior here was inconsistent as we discarded
// the where-bound candidate for trait goals due to the leak check, but did
// cc #119820 the behavior is inconsistent as we discard the where-bound
// candidate for trait goals due to the leak check, but did
// not do so for projection candidates and during normalization.
//
// This results in an inconsistency between `Trait` and `Projection` goals as
@ -27,7 +27,6 @@ fn function1<T: Trait<'static>>() {
// We prefer env candidates over impl candidatescausing this to succeed.
trait_bound::<T>();
//[next]~^ ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied
//[current]~^^ ERROR implementation of `Trait` is not general enough
}
fn function2<T: Trait<'static, Assoc = usize>>() {
@ -39,8 +38,7 @@ fn function2<T: Trait<'static, Assoc = usize>>() {
projection_bound::<T>();
//[next]~^ ERROR type mismatch resolving `<T as Trait<'a>>::Assoc == usize`
//[next]~| ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied
//[current]~^^^ ERROR implementation of `Trait` is not general enough
//[current]~| ERROR mismatched types
//[current]~^^^ ERROR mismatched types
}
fn function3<T: Trait<'static, Assoc = usize>>() {

View File

@ -1,11 +1,11 @@
error[E0283]: type annotations needed
--> $DIR/leak-check-in-selection-2.rs:16:5
--> $DIR/leak-check-in-selection-2.rs:17:5
|
LL | impls_trait::<(), _>();
| ^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `impls_trait`
|
note: multiple `impl`s satisfying `for<'a> (): Trait<&'a str, _>` found
--> $DIR/leak-check-in-selection-2.rs:9:1
--> $DIR/leak-check-in-selection-2.rs:10:1
|
LL | impl<'a> Trait<&'a str, &'a str> for () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -13,7 +13,7 @@ LL |
LL | impl<'a> Trait<&'a str, String> for () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `impls_trait`
--> $DIR/leak-check-in-selection-2.rs:13:19
--> $DIR/leak-check-in-selection-2.rs:14:19
|
LL | fn impls_trait<T: for<'a> Trait<&'a str, U>, U>() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impls_trait`

View File

@ -1,23 +0,0 @@
error[E0283]: type annotations needed
--> $DIR/leak-check-in-selection-2.rs:16:5
|
LL | impls_trait::<(), _>();
| ^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `impls_trait`
|
note: multiple `impl`s satisfying `for<'a> (): Trait<&'a str, _>` found
--> $DIR/leak-check-in-selection-2.rs:9:1
|
LL | impl<'a> Trait<&'a str, &'a str> for () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | impl<'a> Trait<&'a str, String> for () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `impls_trait`
--> $DIR/leak-check-in-selection-2.rs:13:19
|
LL | fn impls_trait<T: for<'a> Trait<&'a str, U>, U>() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impls_trait`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0283`.

View File

@ -1,5 +1,6 @@
//@ revisions: old next
//@[next] compile-flags: -Znext-solver
//@[old] check-pass
// cc #119820
@ -14,5 +15,5 @@ fn impls_trait<T: for<'a> Trait<&'a str, U>, U>() {}
fn main() {
impls_trait::<(), _>();
//~^ ERROR type annotations needed
//[next]~^ ERROR type annotations needed
}

View File

@ -1,22 +1,3 @@
error[E0283]: type annotations needed
--> $DIR/leak-check-in-selection-3.rs:18:5
|
LL | impls_leak::<Box<_>>();
| ^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls_leak`
|
note: multiple `impl`s satisfying `for<'a> Box<_>: Leak<'a>` found
--> $DIR/leak-check-in-selection-3.rs:9:1
|
LL | impl Leak<'_> for Box<u32> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | impl Leak<'static> for Box<u16> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `impls_leak`
--> $DIR/leak-check-in-selection-3.rs:12:18
|
LL | fn impls_leak<T: for<'a> Leak<'a>>() {}
| ^^^^^^^^^^^^^^^^ required by this bound in `impls_leak`
error[E0283]: type annotations needed
--> $DIR/leak-check-in-selection-3.rs:35:5
|
@ -43,6 +24,6 @@ note: required by a bound in `impls_indirect_leak`
LL | fn impls_indirect_leak<T: for<'a> IndirectLeak<'a>>() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impls_indirect_leak`
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0283`.

View File

@ -1,9 +1,9 @@
//@ revisions: old next
//@[next] compile-flags: -Znext-solver
// cc #119820, the previous behavior here was inconsistent,
// cc #119820, the behavior here is inconsistent,
// using the leak check to guide inference for `for<'a> Box<_>: Leak<'a>`
// but not for `for<'a> Box<_>: IndirectLeak<'a>`
// but not for `for<'a> Box<_>: IndirectLeak<'a>`.
trait Leak<'a> {}
impl Leak<'_> for Box<u32> {}
@ -16,7 +16,7 @@ fn direct() {
// The `Box<u16>` impls fails the leak check,
// meaning that we apply the `Box<u32>` impl.
impls_leak::<Box<_>>();
//~^ ERROR type annotations needed
//[next]~^ ERROR type annotations needed
}
trait IndirectLeak<'a> {}

View File

@ -1,11 +1,23 @@
error: implementation of `Bar` is not general enough
--> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:5
error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
--> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:26
|
LL | want_bar_for_any_ccx(b);
| ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough
| -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
| |
| required by a bound introduced by this call
|
= note: `B` must implement `Bar<'0>`, for any lifetime `'0`...
= note: ...but it actually implements `Bar<'static>`
note: required by a bound in `want_bar_for_any_ccx`
--> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:32:15
|
LL | fn want_bar_for_any_ccx<B>(b: &B)
| -------------------- required by a bound in this function
LL | where B : for<'ccx> Bar<'ccx>
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx`
help: consider further restricting this bound
|
LL | where B : Qux + for<'ccx> Bar<'ccx>
| +++++++++++++++++++++
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View File

@ -12,8 +12,7 @@ trait Bar<'ccx>: for<'tcx> Foo<'tcx> {
fn want_foo_for_some_tcx<'x, F: Foo<'x>>(f: &'x F) {
want_foo_for_some_tcx(f);
want_foo_for_any_tcx(f);
//~^ ERROR lifetime may not live long enough
//~| ERROR implementation of `Foo` is not general enough
//~^ ERROR the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied
}
fn want_foo_for_any_tcx<F: for<'tcx> Foo<'tcx>>(f: &F) {
@ -27,8 +26,7 @@ fn want_bar_for_some_ccx<'x, B: Bar<'x>>(b: &B) {
want_bar_for_some_ccx(b);
want_bar_for_any_ccx(b);
//~^ ERROR lifetime may not live long enough
//~| ERROR implementation of `Bar` is not general enough
//~^ ERROR the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
}
fn want_bar_for_any_ccx<B: for<'ccx> Bar<'ccx>>(b: &B) {

View File

@ -1,50 +1,39 @@
error: lifetime may not live long enough
--> $DIR/hrtb-higher-ranker-supertraits.rs:14:5
error[E0277]: the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied
--> $DIR/hrtb-higher-ranker-supertraits.rs:14:26
|
LL | fn want_foo_for_some_tcx<'x, F: Foo<'x>>(f: &'x F) {
| -- lifetime `'x` defined here
LL | want_foo_for_some_tcx(f);
LL | want_foo_for_any_tcx(f);
| ^^^^^^^^^^^^^^^^^^^^^^^ requires that `'x` must outlive `'static`
| -------------------- ^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F`
| |
| required by a bound introduced by this call
|
note: due to current limitations in the borrow checker, this implies a `'static` lifetime
--> $DIR/hrtb-higher-ranker-supertraits.rs:19:28
note: required by a bound in `want_foo_for_any_tcx`
--> $DIR/hrtb-higher-ranker-supertraits.rs:18:28
|
LL | fn want_foo_for_any_tcx<F: for<'tcx> Foo<'tcx>>(f: &F) {
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_foo_for_any_tcx`
help: consider further restricting this bound
|
LL | fn want_foo_for_some_tcx<'x, F: Foo<'x> + for<'tcx> Foo<'tcx>>(f: &'x F) {
| +++++++++++++++++++++
error: implementation of `Foo` is not general enough
--> $DIR/hrtb-higher-ranker-supertraits.rs:14:5
error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
--> $DIR/hrtb-higher-ranker-supertraits.rs:28:26
|
LL | want_foo_for_any_tcx(f);
| ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
|
= note: `F` must implement `Foo<'0>`, for any lifetime `'0`...
= note: ...but it actually implements `Foo<'1>`, for some specific lifetime `'1`
error: lifetime may not live long enough
--> $DIR/hrtb-higher-ranker-supertraits.rs:29:5
|
LL | fn want_bar_for_some_ccx<'x, B: Bar<'x>>(b: &B) {
| -- lifetime `'x` defined here
...
LL | want_bar_for_any_ccx(b);
| ^^^^^^^^^^^^^^^^^^^^^^^ requires that `'x` must outlive `'static`
| -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
| |
| required by a bound introduced by this call
|
note: due to current limitations in the borrow checker, this implies a `'static` lifetime
--> $DIR/hrtb-higher-ranker-supertraits.rs:34:28
note: required by a bound in `want_bar_for_any_ccx`
--> $DIR/hrtb-higher-ranker-supertraits.rs:32:28
|
LL | fn want_bar_for_any_ccx<B: for<'ccx> Bar<'ccx>>(b: &B) {
| ^^^^^^^^^^^^^^^^^^^
error: implementation of `Bar` is not general enough
--> $DIR/hrtb-higher-ranker-supertraits.rs:29:5
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx`
help: consider further restricting this bound
|
LL | want_bar_for_any_ccx(b);
| ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough
|
= note: `B` must implement `Bar<'0>`, for any lifetime `'0`...
= note: ...but it actually implements `Bar<'1>`, for some specific lifetime `'1`
LL | fn want_bar_for_some_ccx<'x, B: Bar<'x> + for<'ccx> Bar<'ccx>>(b: &B) {
| +++++++++++++++++++++
error: aborting due to 4 previous errors
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -32,10 +32,7 @@ fn dispatch<F>(&self, f: F) -> Result<(), io::Error>
F: FnOnce(&mut UIView<'a, T>) -> Result<(), io::Error> + Send + 'static,
{
real_dispatch(f)
//~^ ERROR lifetime may not live long enough
//~| ERROR implementation of `FnOnce` is not general enough
//~| ERROR mismatched types
//
//~^ ERROR expected a `FnOnce(&mut UIView<'_, T>)` closure, found `F`
}
}

View File

@ -1,41 +1,22 @@
error: lifetime may not live long enough
--> $DIR/issue-100690.rs:34:9
error[E0277]: expected a `FnOnce(&mut UIView<'_, T>)` closure, found `F`
--> $DIR/issue-100690.rs:34:23
|
LL | impl<'a, T: 'a> Handle<'a, T, UIView<'a, T>, Result<(), io::Error>> for TUIHandle<T> {
| -- lifetime `'a` defined here
...
LL | real_dispatch(f)
| ^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
| ------------- ^ expected an `FnOnce(&mut UIView<'_, T>)` closure, found `F`
| |
| required by a bound introduced by this call
|
note: due to current limitations in the borrow checker, this implies a `'static` lifetime
= note: expected a closure with arguments `(&mut UIView<'a, _>,)`
found a closure with arguments `(&mut UIView<'_, _>,)`
note: required by a bound in `real_dispatch`
--> $DIR/issue-100690.rs:8:8
|
LL | fn real_dispatch<T, F>(f: F) -> Result<(), io::Error>
| ------------- required by a bound in this function
LL | where
LL | F: FnOnce(&mut UIView<T>) -> Result<(), io::Error> + Send + 'static,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `real_dispatch`
error: implementation of `FnOnce` is not general enough
--> $DIR/issue-100690.rs:34:9
|
LL | real_dispatch(f)
| ^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: `F` must implement `FnOnce<(&mut UIView<'0, T>,)>`, for any lifetime `'0`...
= note: ...but it actually implements `FnOnce<(&mut UIView<'1, T>,)>`, for some specific lifetime `'1`
error: aborting due to 1 previous error
error[E0308]: mismatched types
--> $DIR/issue-100690.rs:34:9
|
LL | real_dispatch(f)
| ^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected associated type `<F as FnOnce<(&mut UIView<'_, T>,)>>::Output`
found associated type `<F as FnOnce<(&mut UIView<'_, T>,)>>::Output`
note: the lifetime requirement is introduced here
--> $DIR/issue-100690.rs:8:34
|
LL | F: FnOnce(&mut UIView<T>) -> Result<(), io::Error> + Send + 'static,
| ^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0308`.
For more information about this error, try `rustc --explain E0277`.