Skip to content

Commit

Permalink
Auto merge of rust-lang#84996 - Mark-Simulacrum:beta-next, r=Mark-Sim…
Browse files Browse the repository at this point in the history
…ulacrum

[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
  • Loading branch information
bors committed May 7, 2021
2 parents e58c811 + 0013b44 commit 4bac69d
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 6 deletions.
12 changes: 11 additions & 1 deletion compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1361,7 +1361,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
) => false,

(ParamCandidate(other), ParamCandidate(victim)) => {
if other.value == victim.value && victim.constness == Constness::NotConst {
let value_same_except_bound_vars = other.value.skip_binder()
== victim.value.skip_binder()
&& !other.value.skip_binder().has_escaping_bound_vars();
if value_same_except_bound_vars {
// See issue #84398. In short, we can generate multiple ParamCandidates which are
// the same except for unused bound vars. Just pick the one with the fewest bound vars
// or the current one if tied (they should both evaluate to the same answer). This is
// probably best characterized as a "hack", since we might prefer to just do our
// best to *not* create essentially duplicate candidates in the first place.
other.value.bound_vars().len() <= victim.value.bound_vars().len()
} else if other.value == victim.value && victim.constness == Constness::NotConst {
// Drop otherwise equivalent non-const candidates in favor of const candidates.
true
} else {
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_typeck/src/check/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}

let mut restrict_type_params = false;
let mut unsatisfied_bounds = false;
if !unsatisfied_predicates.is_empty() {
let def_span = |def_id| {
self.tcx.sess.source_map().guess_head_span(self.tcx.def_span(def_id))
Expand Down Expand Up @@ -739,6 +740,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err.note(&format!(
"the following trait bounds were not satisfied:\n{bound_list}"
));
unsatisfied_bounds = true;
}
}

Expand All @@ -752,6 +754,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
source,
out_of_scope_traits,
&unsatisfied_predicates,
unsatisfied_bounds,
);
}

Expand Down Expand Up @@ -984,9 +987,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
source: SelfSource<'tcx>,
valid_out_of_scope_traits: Vec<DefId>,
unsatisfied_predicates: &[(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>)],
unsatisfied_bounds: bool,
) {
let mut alt_rcvr_sugg = false;
if let SelfSource::MethodCall(rcvr) = source {
if let (SelfSource::MethodCall(rcvr), false) = (source, unsatisfied_bounds) {
debug!(?span, ?item_name, ?rcvr_ty, ?rcvr);
let skippable = [
self.tcx.lang_items().clone_trait(),
Expand Down
4 changes: 2 additions & 2 deletions src/stage0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# stable release's version number. `date` is the date where the release we're
# bootstrapping off was released.

date: 2021-05-04
date: 2021-05-06
rustc: 1.52.0

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

dev: 1
#dev: 1
20 changes: 20 additions & 0 deletions src/test/ui/lifetimes/issue-84398.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// check-pass

pub trait Deserialize<'de>: Sized {}
pub trait DeserializeOwned: for<'de> Deserialize<'de> {}

pub trait Extensible {
type Config;
}

// The `C` here generates a `C: Sized` candidate
pub trait Installer<C> {
fn init<B: Extensible<Config = C>>(&mut self) -> ()
where
// This clause generates a `for<'de> C: Sized` candidate
B::Config: DeserializeOwned,
{
}
}

fn main() {}
9 changes: 8 additions & 1 deletion src/test/ui/suggestions/import-trait-for-method-call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,11 @@ fn next_u64() -> u64 {
h.finish() //~ ERROR no method named `finish` found for struct `DefaultHasher`
}

fn main() {}
trait Bar {}
impl Bar for String {}

fn main() {
let s = String::from("hey");
let x: &dyn Bar = &s;
x.as_ref(); //~ ERROR the method `as_ref` exists for reference `&dyn Bar`, but its trait bounds
}
18 changes: 17 additions & 1 deletion src/test/ui/suggestions/import-trait-for-method-call.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,22 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f
LL | use std::hash::Hasher;
|

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

error: aborting due to 2 previous errors

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

0 comments on commit 4bac69d

Please sign in to comment.