diff options
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | 2025-03-19 16:52:57 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-19 16:52:57 +0100 |
| commit | 9ab2a0e353f44eaa1df4246006dbc693f8e24899 (patch) | |
| tree | 86dd5392267171047c4e2a7302e27897a95b28c0 | |
| parent | c3f74bcb39849b10c8b336db18530c79d7cb8701 (diff) | |
| parent | 14cd467001aa5324fb3b067c80debfffda12c527 (diff) | |
| download | rust-9ab2a0e353f44eaa1df4246006dbc693f8e24899.tar.gz rust-9ab2a0e353f44eaa1df4246006dbc693f8e24899.zip | |
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`
| -rw-r--r-- | compiler/rustc_trait_selection/src/infer.rs | 30 | ||||
| -rw-r--r-- | tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.fixed (renamed from tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.fixed) | 9 | ||||
| -rw-r--r-- | tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.stderr (renamed from tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.stderr) | 4 | ||||
| -rw-r--r-- | tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.fixed | 31 | ||||
| -rw-r--r-- | tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.stderr | 25 | ||||
| -rw-r--r-- | tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.rs | 9 |
6 files changed, 86 insertions, 22 deletions
diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 5cf0600ade8..84ac229b743 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -15,7 +15,7 @@ use tracing::instrument; use crate::infer::at::ToTrace; 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>)] impl<'tcx> InferCtxt<'tcx> { @@ -122,9 +122,6 @@ impl<'tcx> InferCtxt<'tcx> { /// - If this returns `Some([errors..])`, then the trait has an impl for /// the self type, but some nested obligations do not hold. /// - 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( &self, trait_def_id: DefId, @@ -132,20 +129,29 @@ impl<'tcx> InferCtxt<'tcx> { param_env: ty::ParamEnv<'tcx>, ) -> Option<Vec<traits::FulfillmentError<'tcx>>> { self.probe(|_snapshot| { - let mut selcx = SelectionContext::new(self); - match selcx.select(&Obligation::new( + let ocx = ObligationCtxt::new_with_diagnostics(self); + ocx.register_obligation(Obligation::new( self.tcx, ObligationCause::dummy(), param_env, ty::TraitRef::new(self.tcx, trait_def_id, [ty]), - )) { - Ok(Some(selection)) => { - let ocx = ObligationCtxt::new_with_diagnostics(self); - ocx.register_obligations(selection.nested_obligations()); - Some(ocx.select_all_or_error()) + )); + let errors = ocx.select_where_possible(); + // Find the original predicate in the list of predicates that could definitely not be fulfilled. + // If it is in that list, then we know this doesn't even shallowly implement the trait. + // 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) }) } } diff --git a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.fixed b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.fixed index 85b1853c23b..922c883f4f7 100644 --- a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.fixed +++ b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.fixed @@ -1,16 +1,17 @@ //@ run-rustfix +//@ revisions: current next +//@[next] compile-flags: -Znext-solver #![allow(unused_variables, dead_code)] -use std::collections::BTreeMap; -use std::collections::HashSet; +use std::collections::{BTreeMap, HashSet}; -#[derive(Debug,Eq,PartialEq,Hash)] +#[derive(Debug, Eq, PartialEq, Hash)] #[derive(Clone)] enum Day { Mon, } struct Class { - days: BTreeMap<u32, HashSet<Day>> + days: BTreeMap<u32, HashSet<Day>>, } impl Class { diff --git a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.stderr b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.stderr index 6a9d76f7998..301f3c3a458 100644 --- a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.stderr +++ b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.stderr @@ -1,5 +1,5 @@ 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(); | ------------ ^^^^^^^^^ expected `HashSet<Day>`, found `&HashSet<Day>` @@ -9,7 +9,7 @@ LL | let mut x: HashSet<Day> = v.clone(); = 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:18:39 + --> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:19:39 | LL | let mut x: HashSet<Day> = v.clone(); | ^ diff --git a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.fixed b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.fixed new file mode 100644 index 00000000000..922c883f4f7 --- /dev/null +++ b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.fixed @@ -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() {} diff --git a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.stderr b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.stderr new file mode 100644 index 00000000000..301f3c3a458 --- /dev/null +++ b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.stderr @@ -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`. diff --git a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.rs b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.rs index 740cda470d9..6f7b55be8bd 100644 --- a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.rs +++ b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.rs @@ -1,15 +1,16 @@ //@ run-rustfix +//@ revisions: current next +//@[next] compile-flags: -Znext-solver #![allow(unused_variables, dead_code)] -use std::collections::BTreeMap; -use std::collections::HashSet; +use std::collections::{BTreeMap, HashSet}; -#[derive(Debug,Eq,PartialEq,Hash)] +#[derive(Debug, Eq, PartialEq, Hash)] enum Day { Mon, } struct Class { - days: BTreeMap<u32, HashSet<Day>> + days: BTreeMap<u32, HashSet<Day>>, } impl Class { |
