Skip to content

Commit c78d147

Browse files
committed
coolio
1 parent d216b37 commit c78d147

File tree

3 files changed

+24
-54
lines changed

3 files changed

+24
-54
lines changed

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

+7-4
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
419419
let mut no_candidates_apply = true;
420420

421421
for c in candidate_set.vec.iter() {
422-
if self.evaluate_candidate(stack, c)?.may_apply() {
422+
if self.evaluate_candidate(stack, c, false)?.may_apply() {
423423
no_candidates_apply = false;
424424
break;
425425
}
@@ -490,7 +490,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
490490
// is needed for specialization. Propagate overflow if it occurs.
491491
let mut candidates = candidates
492492
.into_iter()
493-
.map(|c| match self.evaluate_candidate(stack, &c) {
493+
.map(|c| match self.evaluate_candidate(stack, &c, false) {
494494
Ok(eval) if eval.may_apply() => {
495495
Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval }))
496496
}
@@ -1234,7 +1234,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12341234
}
12351235

12361236
match self.candidate_from_obligation(stack) {
1237-
Ok(Some(c)) => self.evaluate_candidate(stack, &c),
1237+
Ok(Some(c)) => self.evaluate_candidate(stack, &c, true),
12381238
Ok(None) => Ok(EvaluatedToAmbig),
12391239
Err(Overflow(OverflowError::Canonical)) => Err(OverflowError::Canonical),
12401240
Err(..) => Ok(EvaluatedToErr),
@@ -1269,6 +1269,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12691269
&mut self,
12701270
stack: &TraitObligationStack<'o, 'tcx>,
12711271
candidate: &SelectionCandidate<'tcx>,
1272+
leak_check_higher_ranked_goal: bool,
12721273
) -> Result<EvaluationResult, OverflowError> {
12731274
let mut result = self.evaluation_probe(|this, outer_universe| {
12741275
// We eagerly instantiate higher ranked goals to prevent universe errors
@@ -1281,7 +1282,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12811282
// in an overlap error in coherence.
12821283
let p = self.infcx.instantiate_binder_with_placeholders(stack.obligation.predicate);
12831284
let obligation = stack.obligation.with(this.tcx(), ty::Binder::dummy(p));
1284-
*outer_universe = self.infcx.universe();
1285+
if !leak_check_higher_ranked_goal {
1286+
*outer_universe = self.infcx.universe();
1287+
}
12851288
match this.confirm_candidate(&obligation, candidate.clone()) {
12861289
Ok(selection) => {
12871290
debug!(?selection);

tests/ui/higher-ranked/trait-bounds/issue-30786-1.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
22

3-
// rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream<Item=T`
3+
// rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream<Item=T>`
44
// should act as assertion that item does not borrow from its stream;
55
// but an earlier buggy rustc allowed `.map(|x: &_| x)` which does
66
// have such an item.
@@ -113,12 +113,8 @@ fn variant1() {
113113
// we deduce it somehow from a reuqirement that `Map: Stream` I
114114
// guess.
115115
let map = source.mapx(|x: &_| x);
116-
//~^ ERROR implementation of `FnOnce` is not general enough
117116
let filter = map.filterx(|x: &_| true);
118-
//~^ ERROR implementation of `FnOnce` is not general enough
119-
//~| ERROR implementation of `FnOnce` is not general enough
120-
//~| ERROR implementation of `FnOnce` is not general enough
121-
//~| ERROR implementation of `FnOnce` is not general enough
117+
//~^ ERROR the method `filterx` exists for struct
122118
}
123119

124120
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,21 @@
1-
error: implementation of `FnOnce` is not general enough
2-
--> $DIR/issue-30786-1.rs:115:15
3-
|
4-
LL | let map = source.mapx(|x: &_| x);
5-
| ^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
6-
|
7-
= note: closure with signature `fn(&'2 u64) -> &u64` must implement `FnOnce<(&'1 u64,)>`, for any lifetime `'1`...
8-
= note: ...but it actually implements `FnOnce<(&'2 u64,)>`, for some specific lifetime `'2`
9-
10-
error: implementation of `FnOnce` is not general enough
11-
--> $DIR/issue-30786-1.rs:117:18
12-
|
13-
LL | let filter = map.filterx(|x: &_| true);
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
15-
|
16-
= note: closure with signature `fn(&'2 u64) -> &u64` must implement `FnOnce<(&'1 u64,)>`, for any lifetime `'1`...
17-
= note: ...but it actually implements `FnOnce<(&'2 u64,)>`, for some specific lifetime `'2`
18-
19-
error: implementation of `FnOnce` is not general enough
20-
--> $DIR/issue-30786-1.rs:117:18
1+
error[E0599]: the method `filterx` exists for struct `Map<Repeat, {[email protected]:115:27}>`, but its trait bounds were not satisfied
2+
--> $DIR/issue-30786-1.rs:116:22
213
|
4+
LL | pub struct Map<S, F> {
5+
| -------------------- method `filterx` not found for this struct because it doesn't satisfy `_: StreamExt`
6+
...
227
LL | let filter = map.filterx(|x: &_| true);
23-
| ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
8+
| ^^^^^^^ method cannot be called on `Map<Repeat, {[email protected]:115:27}>` due to unsatisfied trait bounds
249
|
25-
= note: closure with signature `fn(&'2 u64) -> &u64` must implement `FnOnce<(&'1 u64,)>`, for any lifetime `'1`...
26-
= note: ...but it actually implements `FnOnce<(&'2 u64,)>`, for some specific lifetime `'2`
27-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
28-
29-
error: implementation of `FnOnce` is not general enough
30-
--> $DIR/issue-30786-1.rs:117:18
31-
|
32-
LL | let filter = map.filterx(|x: &_| true);
33-
| ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
34-
|
35-
= note: closure with signature `fn(&'2 u64) -> &u64` must implement `FnOnce<(&'1 u64,)>`, for any lifetime `'1`...
36-
= note: ...but it actually implements `FnOnce<(&'2 u64,)>`, for some specific lifetime `'2`
37-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
38-
39-
error: implementation of `FnOnce` is not general enough
40-
--> $DIR/issue-30786-1.rs:117:18
41-
|
42-
LL | let filter = map.filterx(|x: &_| true);
43-
| ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
10+
note: the following trait bounds were not satisfied:
11+
`&'a mut &Map<Repeat, {closure@$DIR/issue-30786-1.rs:115:27: 115:34}>: Stream`
12+
`&'a mut &mut Map<Repeat, {closure@$DIR/issue-30786-1.rs:115:27: 115:34}>: Stream`
13+
`&'a mut Map<Repeat, {closure@$DIR/issue-30786-1.rs:115:27: 115:34}>: Stream`
14+
--> $DIR/issue-30786-1.rs:98:50
4415
|
45-
= note: closure with signature `fn(&'2 u64) -> &u64` must implement `FnOnce<(&'1 u64,)>`, for any lifetime `'1`...
46-
= note: ...but it actually implements `FnOnce<(&'2 u64,)>`, for some specific lifetime `'2`
47-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
16+
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
17+
| --------- - ^^^^^^ unsatisfied trait bound introduced here
4818

49-
error: aborting due to 5 previous errors
19+
error: aborting due to 1 previous error
5020

21+
For more information about this error, try `rustc --explain E0599`.

0 commit comments

Comments
 (0)