Skip to content

Commit 5e50c8a

Browse files
committed
cool beans
1 parent 2f320a2 commit 5e50c8a

File tree

60 files changed

+452
-651
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+452
-651
lines changed

compiler/rustc_middle/src/query/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,6 +1412,10 @@ rustc_queries! {
14121412
separate_provide_extern
14131413
}
14141414

1415+
query is_general_impl(def_id: DefId) -> bool {
1416+
desc { |tcx| "looking up whether `{}` is a general impl", tcx.def_path_str(def_id) }
1417+
}
1418+
14151419
query check_well_formed(key: LocalDefId) -> () {
14161420
desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key.to_def_id()) }
14171421
}

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
135135
// candidate which assumes $0 == int, one that assumes `$0 ==
136136
// usize`, etc. This spells an ambiguity.
137137

138-
let mut candidates = self.filter_impls(candidates, stack.obligation);
139-
138+
let candidates = self.filter_impls(candidates, stack.obligation);
139+
let mut candidates = candidates
140+
.into_iter()
141+
.map(|c| match c {
142+
ImplCandidate(impl_def) if self.tcx().is_general_impl(impl_def) => {
143+
match self.evaluate_candidate(stack, &c) {
144+
Ok(eval) if eval.may_apply() => Ok(Some(c)),
145+
Ok(_) => Ok(None),
146+
Err(OverflowError::Canonical) => Err(Overflow(OverflowError::Canonical)),
147+
Err(OverflowError::ErrorReporting) => Err(ErrorReporting),
148+
Err(OverflowError::Error(e)) => Err(Overflow(OverflowError::Error(e))),
149+
}
150+
}
151+
_ => Ok(Some(c)),
152+
})
153+
.flat_map(Result::transpose)
154+
.collect::<Result<Vec<_>, _>>()?;
140155
// If there is more than one candidate, first winnow them down
141156
// by considering extra conditions (nested obligations and so
142157
// forth). We don't winnow if there is exactly one

compiler/rustc_ty_utils/src/ty.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxIndexSet;
22
use rustc_hir as hir;
33
use rustc_hir::def_id::DefId;
44
use rustc_middle::ty::subst::Subst;
5+
use rustc_middle::ty::util::IgnoreRegions;
56
use rustc_middle::ty::{
67
self, Binder, EarlyBinder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt,
78
};
@@ -460,6 +461,13 @@ pub fn conservative_is_privately_uninhabited_raw<'tcx>(
460461
}
461462
}
462463

464+
fn is_general_impl(tcx: TyCtxt<'_>, id: DefId) -> bool {
465+
let Some(trait_ref) = tcx.impl_trait_ref(id) else {
466+
span_bug!(tcx.def_span(id), "expected impl, found `{:?} for `{:?}`", tcx.def_kind(id), id);
467+
};
468+
tcx.uses_unique_generic_params(trait_ref.substs, IgnoreRegions::No).is_ok()
469+
}
470+
463471
pub fn provide(providers: &mut ty::query::Providers) {
464472
*providers = ty::query::Providers {
465473
asyncness,
@@ -469,6 +477,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
469477
instance_def_size_estimate,
470478
issue33140_self_ty,
471479
impl_defaultness,
480+
is_general_impl,
472481
conservative_is_privately_uninhabited: conservative_is_privately_uninhabited_raw,
473482
..*providers
474483
};

library/core/src/future/into_future.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ use crate::future::Future;
9999
/// }
100100
/// ```
101101
#[stable(feature = "into_future", since = "1.64.0")]
102+
#[rustc_on_unimplemented(
103+
label = "`{Self}` cannot be converted to a future",
104+
message = "`{Self}` cannot be converted to a future",
105+
note = "{Self} must be a future or must implement `IntoFuture` to be awaited"
106+
)]
102107
pub trait IntoFuture {
103108
/// The output that the future will produce on completion.
104109
#[stable(feature = "into_future", since = "1.64.0")]

library/core/src/iter/traits/collect.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,35 @@ pub trait FromIterator<A>: Sized {
227227
/// ```
228228
#[rustc_diagnostic_item = "IntoIterator"]
229229
#[rustc_skip_array_during_method_dispatch]
230+
#[rustc_on_unimplemented(
231+
on(
232+
_Self = "std::ops::RangeTo<Idx>",
233+
label = "if you meant to iterate until a value, add a starting value",
234+
note = "`..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a \
235+
bounded `Range`: `0..end`"
236+
),
237+
on(
238+
_Self = "std::ops::RangeToInclusive<Idx>",
239+
label = "if you meant to iterate until a value (including it), add a starting value",
240+
note = "`..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant \
241+
to have a bounded `RangeInclusive`: `0..=end`"
242+
),
243+
on(
244+
_Self = "&str",
245+
label = "cannot implicitly convert `{Self}` to an iterator; try calling `.chars()` or `.bytes()`"
246+
),
247+
on(
248+
_Self = "std::string::String",
249+
label = "cannot implicitly convert `{Self}` to an iterator; try calling `.chars()` or `.bytes()`"
250+
),
251+
on(
252+
_Self = "{integral}",
253+
note = "if you want to iterate between `start` until a value `end`, use the exclusive range \
254+
syntax `start..end` or the inclusive range syntax `start..=end`"
255+
),
256+
label = "`{Self}` cannot be converted to an iterator",
257+
message = "`{Self}` cannot be converted to an iterator"
258+
)]
230259
#[stable(feature = "rust1", since = "1.0.0")]
231260
pub trait IntoIterator {
232261
/// The type of the elements being iterated over.

src/test/ui/associated-types/substs-ppaux.normal.stderr

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,18 +70,11 @@ help: use parentheses to call this function
7070
LL | let x: () = foo::<'static>();
7171
| ++
7272

73-
error[E0277]: the size for values of type `str` cannot be known at compilation time
73+
error[E0277]: the trait bound `str: Foo<'_, '_, u8>` is not satisfied
7474
--> $DIR/substs-ppaux.rs:49:5
7575
|
7676
LL | <str as Foo<u8>>::bar;
77-
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
78-
|
79-
= help: the trait `Sized` is not implemented for `str`
80-
note: required because of the requirements on the impl of `Foo<'_, '_, u8>` for `str`
81-
--> $DIR/substs-ppaux.rs:11:17
82-
|
83-
LL | impl<'a,'b,T,S> Foo<'a, 'b, S> for T {}
84-
| ^^^^^^^^^^^^^^ ^
77+
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo<'_, '_, u8>` is not implemented for `str`
8578

8679
error: aborting due to 5 previous errors
8780

src/test/ui/associated-types/substs-ppaux.verbose.stderr

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,18 +70,11 @@ help: use parentheses to call this function
7070
LL | let x: () = foo::<'static>();
7171
| ++
7272

73-
error[E0277]: the size for values of type `str` cannot be known at compilation time
73+
error[E0277]: the trait bound `str: Foo<'_#0r, '_#1r, u8>` is not satisfied
7474
--> $DIR/substs-ppaux.rs:49:5
7575
|
7676
LL | <str as Foo<u8>>::bar;
77-
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
78-
|
79-
= help: the trait `Sized` is not implemented for `str`
80-
note: required because of the requirements on the impl of `Foo<'_#0r, '_#1r, u8>` for `str`
81-
--> $DIR/substs-ppaux.rs:11:17
82-
|
83-
LL | impl<'a,'b,T,S> Foo<'a, 'b, S> for T {}
84-
| ^^^^^^^^^^^^^^ ^
77+
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo<'_#0r, '_#1r, u8>` is not implemented for `str`
8578

8679
error: aborting due to 5 previous errors
8780

src/test/ui/async-await/issue-70594.stderr

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,14 @@ error[E0744]: `.await` is not allowed in a `const`
1818
LL | [1; ().await];
1919
| ^^^^^^
2020

21-
error[E0277]: `()` is not a future
21+
error[E0277]: `()` cannot be converted to a future
2222
--> $DIR/issue-70594.rs:4:11
2323
|
2424
LL | [1; ().await];
25-
| ^^^^^^ `()` is not a future
25+
| ^^^^^^ `()` cannot be converted to a future
2626
|
27-
= help: the trait `Future` is not implemented for `()`
27+
= help: the trait `IntoFuture` is not implemented for `()`
2828
= note: () must be a future or must implement `IntoFuture` to be awaited
29-
= note: required because of the requirements on the impl of `IntoFuture` for `()`
3029
help: remove the `.await`
3130
|
3231
LL - [1; ().await];

src/test/ui/async-await/issues/issue-62009-1.stderr

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,14 @@ LL | fn main() {
2424
LL | (|_| 2333).await;
2525
| ^^^^^^ only allowed inside `async` functions and blocks
2626

27-
error[E0277]: `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` is not a future
27+
error[E0277]: `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` cannot be converted to a future
2828
--> $DIR/issue-62009-1.rs:12:15
2929
|
3030
LL | (|_| 2333).await;
31-
| ^^^^^^ `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` is not a future
31+
| ^^^^^^ `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` cannot be converted to a future
3232
|
33-
= help: the trait `Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]`
33+
= help: the trait `IntoFuture` is not implemented for `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]`
3434
= note: [closure@$DIR/issue-62009-1.rs:12:6: 12:9] must be a future or must implement `IntoFuture` to be awaited
35-
= note: required because of the requirements on the impl of `IntoFuture` for `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]`
3635
help: remove the `.await`
3736
|
3837
LL - (|_| 2333).await;

src/test/ui/async-await/unnecessary-await.stderr

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
error[E0277]: `()` is not a future
1+
error[E0277]: `()` cannot be converted to a future
22
--> $DIR/unnecessary-await.rs:9:10
33
|
44
LL | boo().await;
5-
| -----^^^^^^ `()` is not a future
5+
| -----^^^^^^ `()` cannot be converted to a future
66
| |
77
| this call returns `()`
88
|
9-
= help: the trait `Future` is not implemented for `()`
9+
= help: the trait `IntoFuture` is not implemented for `()`
1010
= note: () must be a future or must implement `IntoFuture` to be awaited
11-
= note: required because of the requirements on the impl of `IntoFuture` for `()`
1211
help: remove the `.await`
1312
|
1413
LL - boo().await;

0 commit comments

Comments
 (0)