Skip to content

Commit 4bac69d

Browse files
committed
Auto merge of rust-lang#84996 - Mark-Simulacrum:beta-next, r=Mark-Simulacrum
[beta] backports First-ish round of beta backports: * [beta] backport for rust-lang#84769 rust-lang#84969 * [beta] Bump stage0 to production 1.52.0 rust-lang#84994 * Deduplicate ParamCandidates with the same value except for bound vars rust-lang#84559
2 parents e58c811 + 0013b44 commit 4bac69d

File tree

6 files changed

+63
-6
lines changed

6 files changed

+63
-6
lines changed

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

+11-1
Original file line numberDiff line numberDiff line change
@@ -1361,7 +1361,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13611361
) => false,
13621362

13631363
(ParamCandidate(other), ParamCandidate(victim)) => {
1364-
if other.value == victim.value && victim.constness == Constness::NotConst {
1364+
let value_same_except_bound_vars = other.value.skip_binder()
1365+
== victim.value.skip_binder()
1366+
&& !other.value.skip_binder().has_escaping_bound_vars();
1367+
if value_same_except_bound_vars {
1368+
// See issue #84398. In short, we can generate multiple ParamCandidates which are
1369+
// the same except for unused bound vars. Just pick the one with the fewest bound vars
1370+
// or the current one if tied (they should both evaluate to the same answer). This is
1371+
// probably best characterized as a "hack", since we might prefer to just do our
1372+
// best to *not* create essentially duplicate candidates in the first place.
1373+
other.value.bound_vars().len() <= victim.value.bound_vars().len()
1374+
} else if other.value == victim.value && victim.constness == Constness::NotConst {
13651375
// Drop otherwise equivalent non-const candidates in favor of const candidates.
13661376
true
13671377
} else {

compiler/rustc_typeck/src/check/method/suggest.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
579579
}
580580

581581
let mut restrict_type_params = false;
582+
let mut unsatisfied_bounds = false;
582583
if !unsatisfied_predicates.is_empty() {
583584
let def_span = |def_id| {
584585
self.tcx.sess.source_map().guess_head_span(self.tcx.def_span(def_id))
@@ -739,6 +740,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
739740
err.note(&format!(
740741
"the following trait bounds were not satisfied:\n{bound_list}"
741742
));
743+
unsatisfied_bounds = true;
742744
}
743745
}
744746

@@ -752,6 +754,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
752754
source,
753755
out_of_scope_traits,
754756
&unsatisfied_predicates,
757+
unsatisfied_bounds,
755758
);
756759
}
757760

@@ -984,9 +987,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
984987
source: SelfSource<'tcx>,
985988
valid_out_of_scope_traits: Vec<DefId>,
986989
unsatisfied_predicates: &[(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>)],
990+
unsatisfied_bounds: bool,
987991
) {
988992
let mut alt_rcvr_sugg = false;
989-
if let SelfSource::MethodCall(rcvr) = source {
993+
if let (SelfSource::MethodCall(rcvr), false) = (source, unsatisfied_bounds) {
990994
debug!(?span, ?item_name, ?rcvr_ty, ?rcvr);
991995
let skippable = [
992996
self.tcx.lang_items().clone_trait(),

src/stage0.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# stable release's version number. `date` is the date where the release we're
1313
# bootstrapping off was released.
1414

15-
date: 2021-05-04
15+
date: 2021-05-06
1616
rustc: 1.52.0
1717

1818
# We use a nightly rustfmt to format the source because it solves some
@@ -39,4 +39,4 @@ rustc: 1.52.0
3939
# looking at a beta source tarball and it's uncommented we'll shortly comment it
4040
# out.
4141

42-
dev: 1
42+
#dev: 1

src/test/ui/lifetimes/issue-84398.rs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// check-pass
2+
3+
pub trait Deserialize<'de>: Sized {}
4+
pub trait DeserializeOwned: for<'de> Deserialize<'de> {}
5+
6+
pub trait Extensible {
7+
type Config;
8+
}
9+
10+
// The `C` here generates a `C: Sized` candidate
11+
pub trait Installer<C> {
12+
fn init<B: Extensible<Config = C>>(&mut self) -> ()
13+
where
14+
// This clause generates a `for<'de> C: Sized` candidate
15+
B::Config: DeserializeOwned,
16+
{
17+
}
18+
}
19+
20+
fn main() {}

src/test/ui/suggestions/import-trait-for-method-call.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,11 @@ fn next_u64() -> u64 {
66
h.finish() //~ ERROR no method named `finish` found for struct `DefaultHasher`
77
}
88

9-
fn main() {}
9+
trait Bar {}
10+
impl Bar for String {}
11+
12+
fn main() {
13+
let s = String::from("hey");
14+
let x: &dyn Bar = &s;
15+
x.as_ref(); //~ ERROR the method `as_ref` exists for reference `&dyn Bar`, but its trait bounds
16+
}

src/test/ui/suggestions/import-trait-for-method-call.stderr

+17-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,22 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f
1515
LL | use std::hash::Hasher;
1616
|
1717

18-
error: aborting due to previous error
18+
error[E0599]: the method `as_ref` exists for reference `&dyn Bar`, but its trait bounds were not satisfied
19+
--> $DIR/import-trait-for-method-call.rs:15:7
20+
|
21+
LL | trait Bar {}
22+
| --------- doesn't satisfy `dyn Bar: AsRef<_>`
23+
...
24+
LL | x.as_ref();
25+
| ^^^^^^ method cannot be called on `&dyn Bar` due to unsatisfied trait bounds
26+
|
27+
= note: the following trait bounds were not satisfied:
28+
`dyn Bar: AsRef<_>`
29+
which is required by `&dyn Bar: AsRef<_>`
30+
= help: items from traits can only be used if the trait is implemented and in scope
31+
= note: the following trait defines an item `as_ref`, perhaps you need to implement it:
32+
candidate #1: `AsRef`
33+
34+
error: aborting due to 2 previous errors
1935

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

0 commit comments

Comments
 (0)