Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 26c0055

Browse files
lcnrcuviper
authored andcommittedJul 11, 2024
instantiate higher ranked goals in candidate selection
reverts rust-lang#119820 (cherry picked from commit f77394f)
1 parent 7ecb7f6 commit 26c0055

21 files changed

+121
-299
lines changed
 

‎compiler/rustc_trait_selection/src/traits/select/mod.rs

+12-54
Original file line numberDiff line numberDiff line change
@@ -63,20 +63,6 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
6363
mod candidate_assembly;
6464
mod confirmation;
6565

66-
/// Whether to consider the binder of higher ranked goals for the `leak_check` when
67-
/// evaluating higher-ranked goals. See #119820 for more info.
68-
///
69-
/// While this is a bit hacky, it is necessary to match the behavior of the new solver:
70-
/// We eagerly instantiate binders in the new solver, outside of candidate selection, so
71-
/// the leak check inside of candidates does not consider any bound vars from the higher
72-
/// ranked goal. However, we do exit the binder once we're completely finished with a goal,
73-
/// so the leak-check can be used in evaluate by causing nested higher-ranked goals to fail.
74-
#[derive(Debug, Copy, Clone)]
75-
enum LeakCheckHigherRankedGoal {
76-
No,
77-
Yes,
78-
}
79-
8066
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
8167
pub enum IntercrateAmbiguityCause<'tcx> {
8268
DownstreamCrate { trait_ref: ty::TraitRef<'tcx>, self_ty: Option<Ty<'tcx>> },
@@ -401,10 +387,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
401387
let mut no_candidates_apply = true;
402388

403389
for c in candidate_set.vec.iter() {
404-
if self
405-
.evaluate_candidate(stack, c, LeakCheckHigherRankedGoal::No)?
406-
.may_apply()
407-
{
390+
if self.evaluate_candidate(stack, c)?.may_apply() {
408391
no_candidates_apply = false;
409392
break;
410393
}
@@ -475,7 +458,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
475458
// is needed for specialization. Propagate overflow if it occurs.
476459
let mut candidates = candidates
477460
.into_iter()
478-
.map(|c| match self.evaluate_candidate(stack, &c, LeakCheckHigherRankedGoal::No) {
461+
.map(|c| match self.evaluate_candidate(stack, &c) {
479462
Ok(eval) if eval.may_apply() => {
480463
Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval }))
481464
}
@@ -565,7 +548,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
565548
obligation: &PredicateObligation<'tcx>,
566549
) -> Result<EvaluationResult, OverflowError> {
567550
debug_assert!(!self.infcx.next_trait_solver());
568-
self.evaluation_probe(|this, _outer_universe| {
551+
self.evaluation_probe(|this| {
569552
let goal =
570553
this.infcx.resolve_vars_if_possible((obligation.predicate, obligation.param_env));
571554
let mut result = this.evaluate_predicate_recursively(
@@ -588,11 +571,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
588571
/// `op`, but this can be overwritten if necessary.
589572
fn evaluation_probe(
590573
&mut self,
591-
op: impl FnOnce(&mut Self, &mut ty::UniverseIndex) -> Result<EvaluationResult, OverflowError>,
574+
op: impl FnOnce(&mut Self) -> Result<EvaluationResult, OverflowError>,
592575
) -> Result<EvaluationResult, OverflowError> {
593576
self.infcx.probe(|snapshot| -> Result<EvaluationResult, OverflowError> {
594-
let mut outer_universe = self.infcx.universe();
595-
let result = op(self, &mut outer_universe)?;
577+
let outer_universe = self.infcx.universe();
578+
let result = op(self)?;
596579

597580
match self.infcx.leak_check(outer_universe, Some(snapshot)) {
598581
Ok(()) => {}
@@ -1253,7 +1236,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12531236
}
12541237

12551238
match self.candidate_from_obligation(stack) {
1256-
Ok(Some(c)) => self.evaluate_candidate(stack, &c, LeakCheckHigherRankedGoal::Yes),
1239+
Ok(Some(c)) => self.evaluate_candidate(stack, &c),
12571240
Ok(None) => Ok(EvaluatedToAmbig),
12581241
Err(Overflow(OverflowError::Canonical)) => Err(OverflowError::Canonical),
12591242
Err(..) => Ok(EvaluatedToErr),
@@ -1278,10 +1261,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12781261
/// Further evaluates `candidate` to decide whether all type parameters match and whether nested
12791262
/// obligations are met. Returns whether `candidate` remains viable after this further
12801263
/// scrutiny.
1281-
///
1282-
/// Depending on the value of [LeakCheckHigherRankedGoal], we may ignore the binder of the goal
1283-
/// when eagerly detecting higher ranked region errors via the `leak_check`. See that enum for
1284-
/// more info.
12851264
#[instrument(
12861265
level = "debug",
12871266
skip(self, stack),
@@ -1292,25 +1271,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12921271
&mut self,
12931272
stack: &TraitObligationStack<'o, 'tcx>,
12941273
candidate: &SelectionCandidate<'tcx>,
1295-
leak_check_higher_ranked_goal: LeakCheckHigherRankedGoal,
12961274
) -> Result<EvaluationResult, OverflowError> {
1297-
let mut result = self.evaluation_probe(|this, outer_universe| {
1298-
// We eagerly instantiate higher ranked goals to prevent universe errors
1299-
// from impacting candidate selection. This matches the behavior of the new
1300-
// solver. This slightly weakens type inference.
1301-
//
1302-
// In case there are no unresolved type or const variables this
1303-
// should still not be necessary to select a unique impl as any overlap
1304-
// relying on a universe error from higher ranked goals should have resulted
1305-
// in an overlap error in coherence.
1306-
let p = self.infcx.enter_forall_and_leak_universe(stack.obligation.predicate);
1307-
let obligation = stack.obligation.with(this.tcx(), ty::Binder::dummy(p));
1308-
match leak_check_higher_ranked_goal {
1309-
LeakCheckHigherRankedGoal::No => *outer_universe = self.infcx.universe(),
1310-
LeakCheckHigherRankedGoal::Yes => {}
1311-
}
1312-
1313-
match this.confirm_candidate(&obligation, candidate.clone()) {
1275+
let mut result = self.evaluation_probe(|this| {
1276+
match this.confirm_candidate(stack.obligation, candidate.clone()) {
13141277
Ok(selection) => {
13151278
debug!(?selection);
13161279
this.evaluate_predicates_recursively(
@@ -1730,19 +1693,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
17301693
})
17311694
.map_err(|_| ())
17321695
}
1696+
17331697
fn where_clause_may_apply<'o>(
17341698
&mut self,
17351699
stack: &TraitObligationStack<'o, 'tcx>,
17361700
where_clause_trait_ref: ty::PolyTraitRef<'tcx>,
17371701
) -> Result<EvaluationResult, OverflowError> {
1738-
self.evaluation_probe(|this, outer_universe| {
1739-
// Eagerly instantiate higher ranked goals.
1740-
//
1741-
// See the comment in `evaluate_candidate` to see why.
1742-
let p = self.infcx.enter_forall_and_leak_universe(stack.obligation.predicate);
1743-
let obligation = stack.obligation.with(this.tcx(), ty::Binder::dummy(p));
1744-
*outer_universe = self.infcx.universe();
1745-
match this.match_where_clause_trait_ref(&obligation, where_clause_trait_ref) {
1702+
self.evaluation_probe(|this| {
1703+
match this.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) {
17461704
Ok(obligations) => this.evaluate_predicates_recursively(stack.list(), obligations),
17471705
Err(()) => Ok(EvaluatedToErr),
17481706
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
error[E0277]: the trait bound `for<'a> &'a &T: Trait` is not satisfied
2+
--> $DIR/candidate-from-env-universe-err-1.rs:27:16
3+
|
4+
LL | hr_bound::<&T>();
5+
| ^^ the trait `for<'a> Trait` is not implemented for `&'a &T`
6+
|
7+
note: required by a bound in `hr_bound`
8+
--> $DIR/candidate-from-env-universe-err-1.rs:14:20
9+
|
10+
LL | fn hr_bound<T>()
11+
| -------- required by a bound in this function
12+
LL | where
13+
LL | for<'a> &'a T: Trait,
14+
| ^^^^^ required by this bound in `hr_bound`
15+
help: consider removing the leading `&`-reference
16+
|
17+
LL - hr_bound::<&T>();
18+
LL + hr_bound::<T>();
19+
|
20+
21+
error: aborting due to 1 previous error
22+
23+
For more information about this error, try `rustc --explain E0277`.

‎tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
//@ revisions: old next
2+
//@[next] compile-flags: -Znext-solver
3+
//@[old] check-pass
4+
15
// cc #119820
26

37
trait Trait {}
@@ -21,8 +25,7 @@ where
2125
// the leak check both candidates may apply and we prefer the
2226
// `param_env` candidate in winnowing.
2327
hr_bound::<&T>();
24-
//~^ ERROR the parameter type `T` may not live long enough
25-
//~| ERROR implementation of `Trait` is not general enough
28+
//[next]~^ ERROR the trait bound `for<'a> &'a &T: Trait` is not satisfied
2629
}
2730

2831
fn main() {}

‎tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.stderr

-26
This file was deleted.

‎tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.current.stderr

-25
This file was deleted.

‎tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr

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

‎tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.old.stderr

-26
This file was deleted.

‎tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//@ revisions: current next
22
//@[next] compile-flags: -Znext-solver
3+
//@[current] check-pass
34

45
// cc #119820
56

@@ -13,8 +14,6 @@ fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {}
1314
fn not_hr<'a, T: for<'b> Trait<'a, 'b> + OtherTrait<'static>>() {
1415
impl_hr::<T>();
1516
//[next]~^ ERROR the trait bound `for<'a> T: Trait<'a, '_>` is not satisfied
16-
//[current]~^^ERROR lifetime may not live long enough
17-
//[current]~| ERROR implementation of `Trait` is not general enough
1817
}
1918

2019
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,5 @@
1-
error: implementation of `Trait` is not general enough
2-
--> $DIR/candidate-from-env-universe-err-project.rs:28:5
3-
|
4-
LL | trait_bound::<T>();
5-
| ^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough
6-
|
7-
= note: `T` must implement `Trait<'0>`, for any lifetime `'0`...
8-
= note: ...but it actually implements `Trait<'static>`
9-
10-
error: implementation of `Trait` is not general enough
11-
--> $DIR/candidate-from-env-universe-err-project.rs:39:5
12-
|
13-
LL | projection_bound::<T>();
14-
| ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough
15-
|
16-
= note: `T` must implement `Trait<'0>`, for any lifetime `'0`...
17-
= note: ...but it actually implements `Trait<'static>`
18-
191
error[E0308]: mismatched types
20-
--> $DIR/candidate-from-env-universe-err-project.rs:39:5
2+
--> $DIR/candidate-from-env-universe-err-project.rs:38:5
213
|
224
LL | projection_bound::<T>();
235
| ^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
@@ -31,7 +13,7 @@ LL | fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
3113
| ^^^^^^^^^^^^^
3214

3315
error[E0308]: mismatched types
34-
--> $DIR/candidate-from-env-universe-err-project.rs:55:30
16+
--> $DIR/candidate-from-env-universe-err-project.rs:53:30
3517
|
3618
LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
3719
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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) = |_| ();
4022
found associated type `<T as Trait<'a>>::Assoc`
4123

4224
error[E0308]: mismatched types
43-
--> $DIR/candidate-from-env-universe-err-project.rs:55:30
25+
--> $DIR/candidate-from-env-universe-err-project.rs:53:30
4426
|
4527
LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
4628
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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) = |_| ();
4931
found associated type `<T as Trait<'a>>::Assoc`
5032
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
5133

52-
error: aborting due to 5 previous errors
34+
error: aborting due to 3 previous errors
5335

5436
For more information about this error, try `rustc --explain E0308`.

‎tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ LL | fn function1<T: Trait<'static> + for<'a> Trait<'a>>() {
1515
| +++++++++++++++++++
1616

1717
error[E0277]: the trait bound `for<'a> T: Trait<'a>` is not satisfied
18-
--> $DIR/candidate-from-env-universe-err-project.rs:39:24
18+
--> $DIR/candidate-from-env-universe-err-project.rs:38:24
1919
|
2020
LL | projection_bound::<T>();
2121
| ^ 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>>() {
3131
| +++++++++++++++++++
3232

3333
error[E0271]: type mismatch resolving `<T as Trait<'a>>::Assoc == usize`
34-
--> $DIR/candidate-from-env-universe-err-project.rs:39:24
34+
--> $DIR/candidate-from-env-universe-err-project.rs:38:24
3535
|
3636
LL | projection_bound::<T>();
3737
| ^ type mismatch resolving `<T as Trait<'a>>::Assoc == usize`
@@ -48,13 +48,13 @@ LL | fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
4848
| ^^^^^^^^^^^^^ required by this bound in `projection_bound`
4949

5050
error: higher-ranked subtype error
51-
--> $DIR/candidate-from-env-universe-err-project.rs:55:30
51+
--> $DIR/candidate-from-env-universe-err-project.rs:53:30
5252
|
5353
LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
5454
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5555

5656
error: higher-ranked subtype error
57-
--> $DIR/candidate-from-env-universe-err-project.rs:55:30
57+
--> $DIR/candidate-from-env-universe-err-project.rs:53:30
5858
|
5959
LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
6060
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

‎tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//@ revisions: next current
22
//@[next] compile-flags: -Znext-solver
33

4-
// cc #119820 the previous behavior here was inconsistent as we discarded
5-
// the where-bound candidate for trait goals due to the leak check, but did
4+
// cc #119820 the behavior is inconsistent as we discard the where-bound
5+
// candidate for trait goals due to the leak check, but did
66
// not do so for projection candidates and during normalization.
77
//
88
// This results in an inconsistency between `Trait` and `Projection` goals as
@@ -27,7 +27,6 @@ fn function1<T: Trait<'static>>() {
2727
// We prefer env candidates over impl candidatescausing this to succeed.
2828
trait_bound::<T>();
2929
//[next]~^ ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied
30-
//[current]~^^ ERROR implementation of `Trait` is not general enough
3130
}
3231

3332
fn function2<T: Trait<'static, Assoc = usize>>() {
@@ -39,8 +38,7 @@ fn function2<T: Trait<'static, Assoc = usize>>() {
3938
projection_bound::<T>();
4039
//[next]~^ ERROR type mismatch resolving `<T as Trait<'a>>::Assoc == usize`
4140
//[next]~| ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied
42-
//[current]~^^^ ERROR implementation of `Trait` is not general enough
43-
//[current]~| ERROR mismatched types
41+
//[current]~^^^ ERROR mismatched types
4442
}
4543

4644
fn function3<T: Trait<'static, Assoc = usize>>() {

‎tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.next.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
error[E0283]: type annotations needed
2-
--> $DIR/leak-check-in-selection-2.rs:16:5
2+
--> $DIR/leak-check-in-selection-2.rs:17:5
33
|
44
LL | impls_trait::<(), _>();
55
| ^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `impls_trait`
66
|
77
note: multiple `impl`s satisfying `for<'a> (): Trait<&'a str, _>` found
8-
--> $DIR/leak-check-in-selection-2.rs:9:1
8+
--> $DIR/leak-check-in-selection-2.rs:10:1
99
|
1010
LL | impl<'a> Trait<&'a str, &'a str> for () {}
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1212
LL |
1313
LL | impl<'a> Trait<&'a str, String> for () {}
1414
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1515
note: required by a bound in `impls_trait`
16-
--> $DIR/leak-check-in-selection-2.rs:13:19
16+
--> $DIR/leak-check-in-selection-2.rs:14:19
1717
|
1818
LL | fn impls_trait<T: for<'a> Trait<&'a str, U>, U>() {}
1919
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impls_trait`

‎tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.old.stderr

-23
This file was deleted.

‎tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//@ revisions: old next
22
//@[next] compile-flags: -Znext-solver
3+
//@[old] check-pass
34

45
// cc #119820
56

@@ -14,5 +15,5 @@ fn impls_trait<T: for<'a> Trait<&'a str, U>, U>() {}
1415

1516
fn main() {
1617
impls_trait::<(), _>();
17-
//~^ ERROR type annotations needed
18+
//[next]~^ ERROR type annotations needed
1819
}
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,3 @@
1-
error[E0283]: type annotations needed
2-
--> $DIR/leak-check-in-selection-3.rs:18:5
3-
|
4-
LL | impls_leak::<Box<_>>();
5-
| ^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls_leak`
6-
|
7-
note: multiple `impl`s satisfying `for<'a> Box<_>: Leak<'a>` found
8-
--> $DIR/leak-check-in-selection-3.rs:9:1
9-
|
10-
LL | impl Leak<'_> for Box<u32> {}
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
12-
LL | impl Leak<'static> for Box<u16> {}
13-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14-
note: required by a bound in `impls_leak`
15-
--> $DIR/leak-check-in-selection-3.rs:12:18
16-
|
17-
LL | fn impls_leak<T: for<'a> Leak<'a>>() {}
18-
| ^^^^^^^^^^^^^^^^ required by this bound in `impls_leak`
19-
201
error[E0283]: type annotations needed
212
--> $DIR/leak-check-in-selection-3.rs:35:5
223
|
@@ -43,6 +24,6 @@ note: required by a bound in `impls_indirect_leak`
4324
LL | fn impls_indirect_leak<T: for<'a> IndirectLeak<'a>>() {}
4425
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impls_indirect_leak`
4526

46-
error: aborting due to 2 previous errors
27+
error: aborting due to 1 previous error
4728

4829
For more information about this error, try `rustc --explain E0283`.

‎tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
//@ revisions: old next
22
//@[next] compile-flags: -Znext-solver
33

4-
// cc #119820, the previous behavior here was inconsistent,
4+
// cc #119820, the behavior here is inconsistent,
55
// using the leak check to guide inference for `for<'a> Box<_>: Leak<'a>`
6-
// but not for `for<'a> Box<_>: IndirectLeak<'a>`
6+
// but not for `for<'a> Box<_>: IndirectLeak<'a>`.
77

88
trait Leak<'a> {}
99
impl Leak<'_> for Box<u32> {}
@@ -16,7 +16,7 @@ fn direct() {
1616
// The `Box<u16>` impls fails the leak check,
1717
// meaning that we apply the `Box<u32>` impl.
1818
impls_leak::<Box<_>>();
19-
//~^ ERROR type annotations needed
19+
//[next]~^ ERROR type annotations needed
2020
}
2121

2222
trait IndirectLeak<'a> {}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
1-
error: implementation of `Bar` is not general enough
2-
--> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:5
1+
error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
2+
--> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:26
33
|
44
LL | want_bar_for_any_ccx(b);
5-
| ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough
5+
| -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
6+
| |
7+
| required by a bound introduced by this call
68
|
7-
= note: `B` must implement `Bar<'0>`, for any lifetime `'0`...
8-
= note: ...but it actually implements `Bar<'static>`
9+
note: required by a bound in `want_bar_for_any_ccx`
10+
--> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:32:15
11+
|
12+
LL | fn want_bar_for_any_ccx<B>(b: &B)
13+
| -------------------- required by a bound in this function
14+
LL | where B : for<'ccx> Bar<'ccx>
15+
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx`
16+
help: consider further restricting this bound
17+
|
18+
LL | where B : Qux + for<'ccx> Bar<'ccx>
19+
| +++++++++++++++++++++
920

1021
error: aborting due to 1 previous error
1122

23+
For more information about this error, try `rustc --explain E0277`.

‎tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ trait Bar<'ccx>: for<'tcx> Foo<'tcx> {
1212
fn want_foo_for_some_tcx<'x, F: Foo<'x>>(f: &'x F) {
1313
want_foo_for_some_tcx(f);
1414
want_foo_for_any_tcx(f);
15-
//~^ ERROR lifetime may not live long enough
16-
//~| ERROR implementation of `Foo` is not general enough
15+
//~^ ERROR the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied
1716
}
1817

1918
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) {
2726

2827
want_bar_for_some_ccx(b);
2928
want_bar_for_any_ccx(b);
30-
//~^ ERROR lifetime may not live long enough
31-
//~| ERROR implementation of `Bar` is not general enough
29+
//~^ ERROR the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
3230
}
3331

3432
fn want_bar_for_any_ccx<B: for<'ccx> Bar<'ccx>>(b: &B) {
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,39 @@
1-
error: lifetime may not live long enough
2-
--> $DIR/hrtb-higher-ranker-supertraits.rs:14:5
1+
error[E0277]: the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied
2+
--> $DIR/hrtb-higher-ranker-supertraits.rs:14:26
33
|
4-
LL | fn want_foo_for_some_tcx<'x, F: Foo<'x>>(f: &'x F) {
5-
| -- lifetime `'x` defined here
6-
LL | want_foo_for_some_tcx(f);
74
LL | want_foo_for_any_tcx(f);
8-
| ^^^^^^^^^^^^^^^^^^^^^^^ requires that `'x` must outlive `'static`
5+
| -------------------- ^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F`
6+
| |
7+
| required by a bound introduced by this call
98
|
10-
note: due to current limitations in the borrow checker, this implies a `'static` lifetime
11-
--> $DIR/hrtb-higher-ranker-supertraits.rs:19:28
9+
note: required by a bound in `want_foo_for_any_tcx`
10+
--> $DIR/hrtb-higher-ranker-supertraits.rs:18:28
1211
|
1312
LL | fn want_foo_for_any_tcx<F: for<'tcx> Foo<'tcx>>(f: &F) {
14-
| ^^^^^^^^^^^^^^^^^^^
15-
16-
error: implementation of `Foo` is not general enough
17-
--> $DIR/hrtb-higher-ranker-supertraits.rs:14:5
18-
|
19-
LL | want_foo_for_any_tcx(f);
20-
| ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
13+
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_foo_for_any_tcx`
14+
help: consider further restricting this bound
2115
|
22-
= note: `F` must implement `Foo<'0>`, for any lifetime `'0`...
23-
= note: ...but it actually implements `Foo<'1>`, for some specific lifetime `'1`
16+
LL | fn want_foo_for_some_tcx<'x, F: Foo<'x> + for<'tcx> Foo<'tcx>>(f: &'x F) {
17+
| +++++++++++++++++++++
2418

25-
error: lifetime may not live long enough
26-
--> $DIR/hrtb-higher-ranker-supertraits.rs:29:5
19+
error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
20+
--> $DIR/hrtb-higher-ranker-supertraits.rs:28:26
2721
|
28-
LL | fn want_bar_for_some_ccx<'x, B: Bar<'x>>(b: &B) {
29-
| -- lifetime `'x` defined here
30-
...
3122
LL | want_bar_for_any_ccx(b);
32-
| ^^^^^^^^^^^^^^^^^^^^^^^ requires that `'x` must outlive `'static`
23+
| -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
24+
| |
25+
| required by a bound introduced by this call
3326
|
34-
note: due to current limitations in the borrow checker, this implies a `'static` lifetime
35-
--> $DIR/hrtb-higher-ranker-supertraits.rs:34:28
27+
note: required by a bound in `want_bar_for_any_ccx`
28+
--> $DIR/hrtb-higher-ranker-supertraits.rs:32:28
3629
|
3730
LL | fn want_bar_for_any_ccx<B: for<'ccx> Bar<'ccx>>(b: &B) {
38-
| ^^^^^^^^^^^^^^^^^^^
39-
40-
error: implementation of `Bar` is not general enough
41-
--> $DIR/hrtb-higher-ranker-supertraits.rs:29:5
42-
|
43-
LL | want_bar_for_any_ccx(b);
44-
| ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough
31+
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx`
32+
help: consider further restricting this bound
4533
|
46-
= note: `B` must implement `Bar<'0>`, for any lifetime `'0`...
47-
= note: ...but it actually implements `Bar<'1>`, for some specific lifetime `'1`
34+
LL | fn want_bar_for_some_ccx<'x, B: Bar<'x> + for<'ccx> Bar<'ccx>>(b: &B) {
35+
| +++++++++++++++++++++
4836

49-
error: aborting due to 4 previous errors
37+
error: aborting due to 2 previous errors
5038

39+
For more information about this error, try `rustc --explain E0277`.

‎tests/ui/implied-bounds/issue-100690.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,7 @@ impl<'a, T: 'a> Handle<'a, T, UIView<'a, T>, Result<(), io::Error>> for TUIHandl
3232
F: FnOnce(&mut UIView<'a, T>) -> Result<(), io::Error> + Send + 'static,
3333
{
3434
real_dispatch(f)
35-
//~^ ERROR lifetime may not live long enough
36-
//~| ERROR implementation of `FnOnce` is not general enough
37-
//~| ERROR mismatched types
38-
//
35+
//~^ ERROR expected a `FnOnce(&mut UIView<'_, T>)` closure, found `F`
3936
}
4037
}
4138

+14-33
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,22 @@
1-
error: lifetime may not live long enough
2-
--> $DIR/issue-100690.rs:34:9
1+
error[E0277]: expected a `FnOnce(&mut UIView<'_, T>)` closure, found `F`
2+
--> $DIR/issue-100690.rs:34:23
33
|
4-
LL | impl<'a, T: 'a> Handle<'a, T, UIView<'a, T>, Result<(), io::Error>> for TUIHandle<T> {
5-
| -- lifetime `'a` defined here
6-
...
74
LL | real_dispatch(f)
8-
| ^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
5+
| ------------- ^ expected an `FnOnce(&mut UIView<'_, T>)` closure, found `F`
6+
| |
7+
| required by a bound introduced by this call
98
|
10-
note: due to current limitations in the borrow checker, this implies a `'static` lifetime
9+
= note: expected a closure with arguments `(&mut UIView<'a, _>,)`
10+
found a closure with arguments `(&mut UIView<'_, _>,)`
11+
note: required by a bound in `real_dispatch`
1112
--> $DIR/issue-100690.rs:8:8
1213
|
14+
LL | fn real_dispatch<T, F>(f: F) -> Result<(), io::Error>
15+
| ------------- required by a bound in this function
16+
LL | where
1317
LL | F: FnOnce(&mut UIView<T>) -> Result<(), io::Error> + Send + 'static,
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
18+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `real_dispatch`
1519

16-
error: implementation of `FnOnce` is not general enough
17-
--> $DIR/issue-100690.rs:34:9
18-
|
19-
LL | real_dispatch(f)
20-
| ^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
21-
|
22-
= note: `F` must implement `FnOnce<(&mut UIView<'0, T>,)>`, for any lifetime `'0`...
23-
= note: ...but it actually implements `FnOnce<(&mut UIView<'1, T>,)>`, for some specific lifetime `'1`
24-
25-
error[E0308]: mismatched types
26-
--> $DIR/issue-100690.rs:34:9
27-
|
28-
LL | real_dispatch(f)
29-
| ^^^^^^^^^^^^^^^^ one type is more general than the other
30-
|
31-
= note: expected associated type `<F as FnOnce<(&mut UIView<'_, T>,)>>::Output`
32-
found associated type `<F as FnOnce<(&mut UIView<'_, T>,)>>::Output`
33-
note: the lifetime requirement is introduced here
34-
--> $DIR/issue-100690.rs:8:34
35-
|
36-
LL | F: FnOnce(&mut UIView<T>) -> Result<(), io::Error> + Send + 'static,
37-
| ^^^^^^^^^^^^^^^^^^^^^
38-
39-
error: aborting due to 3 previous errors
20+
error: aborting due to 1 previous error
4021

41-
For more information about this error, try `rustc --explain E0308`.
22+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)
Please sign in to comment.