Skip to content

Commit

Permalink
coolio
Browse files Browse the repository at this point in the history
  • Loading branch information
lcnr committed Feb 5, 2024
1 parent d216b37 commit c78d147
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 54 deletions.
11 changes: 7 additions & 4 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let mut no_candidates_apply = true;

for c in candidate_set.vec.iter() {
if self.evaluate_candidate(stack, c)?.may_apply() {
if self.evaluate_candidate(stack, c, false)?.may_apply() {
no_candidates_apply = false;
break;
}
Expand Down Expand Up @@ -490,7 +490,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// is needed for specialization. Propagate overflow if it occurs.
let mut candidates = candidates
.into_iter()
.map(|c| match self.evaluate_candidate(stack, &c) {
.map(|c| match self.evaluate_candidate(stack, &c, false) {
Ok(eval) if eval.may_apply() => {
Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval }))
}
Expand Down Expand Up @@ -1234,7 +1234,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}

match self.candidate_from_obligation(stack) {
Ok(Some(c)) => self.evaluate_candidate(stack, &c),
Ok(Some(c)) => self.evaluate_candidate(stack, &c, true),
Ok(None) => Ok(EvaluatedToAmbig),
Err(Overflow(OverflowError::Canonical)) => Err(OverflowError::Canonical),
Err(..) => Ok(EvaluatedToErr),
Expand Down Expand Up @@ -1269,6 +1269,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut self,
stack: &TraitObligationStack<'o, 'tcx>,
candidate: &SelectionCandidate<'tcx>,
leak_check_higher_ranked_goal: bool,
) -> Result<EvaluationResult, OverflowError> {
let mut result = self.evaluation_probe(|this, outer_universe| {
// We eagerly instantiate higher ranked goals to prevent universe errors
Expand All @@ -1281,7 +1282,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// in an overlap error in coherence.
let p = self.infcx.instantiate_binder_with_placeholders(stack.obligation.predicate);
let obligation = stack.obligation.with(this.tcx(), ty::Binder::dummy(p));
*outer_universe = self.infcx.universe();
if !leak_check_higher_ranked_goal {
*outer_universe = self.infcx.universe();
}
match this.confirm_candidate(&obligation, candidate.clone()) {
Ok(selection) => {
debug!(?selection);
Expand Down
8 changes: 2 additions & 6 deletions tests/ui/higher-ranked/trait-bounds/issue-30786-1.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"

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

fn main() {}
59 changes: 15 additions & 44 deletions tests/ui/higher-ranked/trait-bounds/issue-30786-1.stderr
Original file line number Diff line number Diff line change
@@ -1,50 +1,21 @@
error: implementation of `FnOnce` is not general enough
--> $DIR/issue-30786-1.rs:115:15
|
LL | let map = source.mapx(|x: &_| x);
| ^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'2 u64) -> &u64` must implement `FnOnce<(&'1 u64,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 u64,)>`, for some specific lifetime `'2`

error: implementation of `FnOnce` is not general enough
--> $DIR/issue-30786-1.rs:117:18
|
LL | let filter = map.filterx(|x: &_| true);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'2 u64) -> &u64` must implement `FnOnce<(&'1 u64,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 u64,)>`, for some specific lifetime `'2`

error: implementation of `FnOnce` is not general enough
--> $DIR/issue-30786-1.rs:117:18
error[E0599]: the method `filterx` exists for struct `Map<Repeat, {closure@issue-30786-1.rs:115:27}>`, but its trait bounds were not satisfied
--> $DIR/issue-30786-1.rs:116:22
|
LL | pub struct Map<S, F> {
| -------------------- method `filterx` not found for this struct because it doesn't satisfy `_: StreamExt`
...
LL | let filter = map.filterx(|x: &_| true);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
| ^^^^^^^ method cannot be called on `Map<Repeat, {closure@issue-30786-1.rs:115:27}>` due to unsatisfied trait bounds
|
= note: closure with signature `fn(&'2 u64) -> &u64` must implement `FnOnce<(&'1 u64,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 u64,)>`, for some specific lifetime `'2`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: implementation of `FnOnce` is not general enough
--> $DIR/issue-30786-1.rs:117:18
|
LL | let filter = map.filterx(|x: &_| true);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'2 u64) -> &u64` must implement `FnOnce<(&'1 u64,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 u64,)>`, for some specific lifetime `'2`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: implementation of `FnOnce` is not general enough
--> $DIR/issue-30786-1.rs:117:18
|
LL | let filter = map.filterx(|x: &_| true);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
note: the following trait bounds were not satisfied:
`&'a mut &Map<Repeat, {closure@$DIR/issue-30786-1.rs:115:27: 115:34}>: Stream`
`&'a mut &mut Map<Repeat, {closure@$DIR/issue-30786-1.rs:115:27: 115:34}>: Stream`
`&'a mut Map<Repeat, {closure@$DIR/issue-30786-1.rs:115:27: 115:34}>: Stream`
--> $DIR/issue-30786-1.rs:98:50
|
= note: closure with signature `fn(&'2 u64) -> &u64` must implement `FnOnce<(&'1 u64,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 u64,)>`, for some specific lifetime `'2`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
| --------- - ^^^^^^ unsatisfied trait bound introduced here

error: aborting due to 5 previous errors
error: aborting due to 1 previous error

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

0 comments on commit c78d147

Please sign in to comment.