Rollup merge of #138594 - oli-obk:no-select, r=lcnr
Fix next solver handling of shallow trait impl check
I'm trying to remove unnecessary direct calls to `select`, and this one seemed like a good place to start 😆
r? `@compiler-errors` or `@lcnr`
This commit is contained in:
commit
9ab2a0e353
6 changed files with 86 additions and 22 deletions
|
@ -15,7 +15,7 @@ use tracing::instrument;
|
||||||
|
|
||||||
use crate::infer::at::ToTrace;
|
use crate::infer::at::ToTrace;
|
||||||
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
|
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||||
use crate::traits::{self, Obligation, ObligationCause, ObligationCtxt, SelectionContext};
|
use crate::traits::{self, Obligation, ObligationCause, ObligationCtxt};
|
||||||
|
|
||||||
#[extension(pub trait InferCtxtExt<'tcx>)]
|
#[extension(pub trait InferCtxtExt<'tcx>)]
|
||||||
impl<'tcx> InferCtxt<'tcx> {
|
impl<'tcx> InferCtxt<'tcx> {
|
||||||
|
@ -122,9 +122,6 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
/// - If this returns `Some([errors..])`, then the trait has an impl for
|
/// - If this returns `Some([errors..])`, then the trait has an impl for
|
||||||
/// the self type, but some nested obligations do not hold.
|
/// the self type, but some nested obligations do not hold.
|
||||||
/// - If this returns `None`, no implementation that applies could be found.
|
/// - If this returns `None`, no implementation that applies could be found.
|
||||||
///
|
|
||||||
/// FIXME(-Znext-solver): Due to the recursive nature of the new solver,
|
|
||||||
/// this will probably only ever return `Some([])` or `None`.
|
|
||||||
fn type_implements_trait_shallow(
|
fn type_implements_trait_shallow(
|
||||||
&self,
|
&self,
|
||||||
trait_def_id: DefId,
|
trait_def_id: DefId,
|
||||||
|
@ -132,20 +129,29 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
) -> Option<Vec<traits::FulfillmentError<'tcx>>> {
|
) -> Option<Vec<traits::FulfillmentError<'tcx>>> {
|
||||||
self.probe(|_snapshot| {
|
self.probe(|_snapshot| {
|
||||||
let mut selcx = SelectionContext::new(self);
|
let ocx = ObligationCtxt::new_with_diagnostics(self);
|
||||||
match selcx.select(&Obligation::new(
|
ocx.register_obligation(Obligation::new(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
ObligationCause::dummy(),
|
ObligationCause::dummy(),
|
||||||
param_env,
|
param_env,
|
||||||
ty::TraitRef::new(self.tcx, trait_def_id, [ty]),
|
ty::TraitRef::new(self.tcx, trait_def_id, [ty]),
|
||||||
)) {
|
));
|
||||||
Ok(Some(selection)) => {
|
let errors = ocx.select_where_possible();
|
||||||
let ocx = ObligationCtxt::new_with_diagnostics(self);
|
// Find the original predicate in the list of predicates that could definitely not be fulfilled.
|
||||||
ocx.register_obligations(selection.nested_obligations());
|
// If it is in that list, then we know this doesn't even shallowly implement the trait.
|
||||||
Some(ocx.select_all_or_error())
|
// If it is not in that list, it was fulfilled, but there may be nested obligations, which we don't care about here.
|
||||||
|
for error in &errors {
|
||||||
|
let Some(trait_clause) = error.obligation.predicate.as_trait_clause() else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let Some(bound_ty) = trait_clause.self_ty().no_bound_vars() else { continue };
|
||||||
|
if trait_clause.def_id() == trait_def_id
|
||||||
|
&& ocx.eq(&ObligationCause::dummy(), param_env, bound_ty, ty).is_ok()
|
||||||
|
{
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
Ok(None) | Err(_) => None,
|
|
||||||
}
|
}
|
||||||
|
Some(errors)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
//@ run-rustfix
|
//@ run-rustfix
|
||||||
|
//@ revisions: current next
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
#![allow(unused_variables, dead_code)]
|
#![allow(unused_variables, dead_code)]
|
||||||
use std::collections::BTreeMap;
|
use std::collections::{BTreeMap, HashSet};
|
||||||
use std::collections::HashSet;
|
|
||||||
|
|
||||||
#[derive(Debug,Eq,PartialEq,Hash)]
|
#[derive(Debug, Eq, PartialEq, Hash)]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
enum Day {
|
enum Day {
|
||||||
Mon,
|
Mon,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Class {
|
struct Class {
|
||||||
days: BTreeMap<u32, HashSet<Day>>
|
days: BTreeMap<u32, HashSet<Day>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Class {
|
impl Class {
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:18:39
|
--> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:19:39
|
||||||
|
|
|
|
||||||
LL | let mut x: HashSet<Day> = v.clone();
|
LL | let mut x: HashSet<Day> = v.clone();
|
||||||
| ------------ ^^^^^^^^^ expected `HashSet<Day>`, found `&HashSet<Day>`
|
| ------------ ^^^^^^^^^ expected `HashSet<Day>`, found `&HashSet<Day>`
|
||||||
|
@ -9,7 +9,7 @@ LL | let mut x: HashSet<Day> = v.clone();
|
||||||
= note: expected struct `HashSet<_>`
|
= note: expected struct `HashSet<_>`
|
||||||
found reference `&HashSet<_>`
|
found reference `&HashSet<_>`
|
||||||
note: `HashSet<Day>` does not implement `Clone`, so `&HashSet<Day>` was cloned instead
|
note: `HashSet<Day>` does not implement `Clone`, so `&HashSet<Day>` was cloned instead
|
||||||
--> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:18:39
|
--> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:19:39
|
||||||
|
|
|
|
||||||
LL | let mut x: HashSet<Day> = v.clone();
|
LL | let mut x: HashSet<Day> = v.clone();
|
||||||
| ^
|
| ^
|
|
@ -0,0 +1,31 @@
|
||||||
|
//@ run-rustfix
|
||||||
|
//@ revisions: current next
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
#![allow(unused_variables, dead_code)]
|
||||||
|
use std::collections::{BTreeMap, HashSet};
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Hash)]
|
||||||
|
#[derive(Clone)]
|
||||||
|
enum Day {
|
||||||
|
Mon,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Class {
|
||||||
|
days: BTreeMap<u32, HashSet<Day>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Class {
|
||||||
|
fn do_stuff(&self) {
|
||||||
|
for (_, v) in &self.days {
|
||||||
|
let mut x: HashSet<Day> = v.clone(); //~ ERROR
|
||||||
|
let y: Vec<Day> = x.drain().collect();
|
||||||
|
println!("{:?}", x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fail() {
|
||||||
|
let c = Class { days: BTreeMap::new() };
|
||||||
|
c.do_stuff();
|
||||||
|
}
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,25 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:19:39
|
||||||
|
|
|
||||||
|
LL | let mut x: HashSet<Day> = v.clone();
|
||||||
|
| ------------ ^^^^^^^^^ expected `HashSet<Day>`, found `&HashSet<Day>`
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
|
||||||
|
= note: expected struct `HashSet<_>`
|
||||||
|
found reference `&HashSet<_>`
|
||||||
|
note: `HashSet<Day>` does not implement `Clone`, so `&HashSet<Day>` was cloned instead
|
||||||
|
--> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:19:39
|
||||||
|
|
|
||||||
|
LL | let mut x: HashSet<Day> = v.clone();
|
||||||
|
| ^
|
||||||
|
= help: `Clone` is not implemented because the trait bound `Day: Clone` is not satisfied
|
||||||
|
help: consider annotating `Day` with `#[derive(Clone)]`
|
||||||
|
|
|
||||||
|
LL + #[derive(Clone)]
|
||||||
|
LL | enum Day {
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
|
@ -1,15 +1,16 @@
|
||||||
//@ run-rustfix
|
//@ run-rustfix
|
||||||
|
//@ revisions: current next
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
#![allow(unused_variables, dead_code)]
|
#![allow(unused_variables, dead_code)]
|
||||||
use std::collections::BTreeMap;
|
use std::collections::{BTreeMap, HashSet};
|
||||||
use std::collections::HashSet;
|
|
||||||
|
|
||||||
#[derive(Debug,Eq,PartialEq,Hash)]
|
#[derive(Debug, Eq, PartialEq, Hash)]
|
||||||
enum Day {
|
enum Day {
|
||||||
Mon,
|
Mon,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Class {
|
struct Class {
|
||||||
days: BTreeMap<u32, HashSet<Day>>
|
days: BTreeMap<u32, HashSet<Day>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Class {
|
impl Class {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue