Skip to content

Commit c20c569

Browse files
Only prefer param-env candidates if they remain non-global after norm
1 parent a0e34cb commit c20c569

File tree

5 files changed

+50
-47
lines changed

5 files changed

+50
-47
lines changed

compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs

+11-27
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::delegate::SolverDelegate;
1919
use crate::solve::inspect::ProbeKind;
2020
use crate::solve::{
2121
BuiltinImplSource, CandidateSource, CanonicalResponse, Certainty, EvalCtxt, Goal, GoalSource,
22-
MaybeCause, NoSolution, QueryResult,
22+
MaybeCause, NoSolution, ParamEnvSource, QueryResult,
2323
};
2424

2525
enum AliasBoundKind {
@@ -114,7 +114,6 @@ where
114114
ecx: &mut EvalCtxt<'_, D>,
115115
goal: Goal<I, Self>,
116116
assumption: I::Clause,
117-
idx: usize,
118117
) -> Result<Candidate<I>, NoSolution> {
119118
Self::fast_reject_assumption(ecx, goal, assumption)?;
120119

@@ -130,7 +129,7 @@ where
130129
})
131130
.enter(|ecx| {
132131
Self::match_assumption(ecx, goal, assumption)?;
133-
let source = ecx.characterize_param_env_assumption(goal.param_env, assumption, idx)?;
132+
let source = ecx.characterize_param_env_assumption(goal.param_env, assumption)?;
134133
Ok(Candidate {
135134
source,
136135
result: ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)?,
@@ -553,8 +552,8 @@ where
553552
goal: Goal<I, G>,
554553
candidates: &mut Vec<Candidate<I>>,
555554
) {
556-
for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() {
557-
candidates.extend(G::probe_and_consider_param_env_candidate(self, goal, assumption, i));
555+
for assumption in goal.param_env.caller_bounds().iter() {
556+
candidates.extend(G::probe_and_consider_param_env_candidate(self, goal, assumption));
558557
}
559558
}
560559

@@ -934,20 +933,11 @@ where
934933
// See `tests/ui/winnowing/norm-where-bound-gt-alias-bound.rs`.
935934
let mut considered_candidates: Vec<_> = if candidates_from_env_and_bounds
936935
.iter()
937-
.any(|c| {
938-
matches!(
939-
c.source,
940-
CandidateSource::ParamEnv(_) | CandidateSource::GlobalParamEnv(_)
941-
)
942-
}) {
936+
.any(|c| matches!(c.source, CandidateSource::ParamEnv(_)))
937+
{
943938
candidates_from_env_and_bounds
944939
.into_iter()
945-
.filter(|c| {
946-
matches!(
947-
c.source,
948-
CandidateSource::ParamEnv(_) | CandidateSource::GlobalParamEnv(_)
949-
)
950-
})
940+
.filter(|c| matches!(c.source, CandidateSource::ParamEnv(_)))
951941
.map(|c| c.result)
952942
.collect()
953943
} else {
@@ -976,12 +966,7 @@ where
976966
// (for example, and ideally only) when proving item bounds for an impl.
977967
let candidates_from_env: Vec<_> = candidates
978968
.iter()
979-
.filter(|c| {
980-
matches!(
981-
c.source,
982-
CandidateSource::ParamEnv(_) | CandidateSource::GlobalParamEnv(_)
983-
)
984-
})
969+
.filter(|c| matches!(c.source, CandidateSource::ParamEnv(_)))
985970
.map(|c| c.result)
986971
.collect();
987972
if let Some(response) = self.try_merge_responses(&candidates_from_env) {
@@ -1009,17 +994,16 @@ where
1009994
&mut self,
1010995
param_env: I::ParamEnv,
1011996
assumption: I::Clause,
1012-
idx: usize,
1013997
) -> Result<CandidateSource<I>, NoSolution> {
1014998
// FIXME:
1015999
if assumption.has_bound_vars() {
1016-
return Ok(CandidateSource::ParamEnv(idx));
1000+
return Ok(CandidateSource::ParamEnv(ParamEnvSource::NonGlobal));
10171001
}
10181002

10191003
match assumption.visit_with(&mut FindParamInClause { ecx: self, param_env }) {
10201004
ControlFlow::Break(Err(NoSolution)) => Err(NoSolution),
1021-
ControlFlow::Break(Ok(())) => Ok(CandidateSource::ParamEnv(idx)),
1022-
ControlFlow::Continue(()) => Ok(CandidateSource::GlobalParamEnv(idx)),
1005+
ControlFlow::Break(Ok(())) => Ok(CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)),
1006+
ControlFlow::Continue(()) => Ok(CandidateSource::ParamEnv(ParamEnvSource::Global)),
10231007
}
10241008
}
10251009
}

compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

+15-16
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::solve::assembly::{self, AllowInferenceConstraints, AssembleCandidates
1717
use crate::solve::inspect::ProbeKind;
1818
use crate::solve::{
1919
BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause,
20-
NoSolution,
20+
NoSolution, ParamEnvSource,
2121
};
2222

2323
impl<D, I> assembly::GoalKind<D> for TraitPredicate<I>
@@ -1284,17 +1284,13 @@ where
12841284

12851285
// If there are non-global where-bounds, prefer where-bounds
12861286
// (including global ones) over everything else.
1287-
let has_non_global_where_bounds =
1288-
candidates.iter().any(|c| matches!(c.source, CandidateSource::ParamEnv(_)));
1287+
let has_non_global_where_bounds = candidates
1288+
.iter()
1289+
.any(|c| matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)));
12891290
if has_non_global_where_bounds {
12901291
let where_bounds: Vec<_> = candidates
12911292
.iter()
1292-
.filter(|c| {
1293-
matches!(
1294-
c.source,
1295-
CandidateSource::ParamEnv(_) | CandidateSource::GlobalParamEnv(_)
1296-
)
1297-
})
1293+
.filter(|c| matches!(c.source, CandidateSource::ParamEnv(_)))
12981294
.map(|c| c.result)
12991295
.collect();
13001296
return if let Some(response) = self.try_merge_responses(&where_bounds) {
@@ -1323,13 +1319,16 @@ where
13231319
// is still reported as being proven-via the param-env so that rigid projections
13241320
// operate correctly. Otherwise, drop all global where-bounds before merging the
13251321
// remaining candidates.
1326-
let proven_via =
1327-
if candidates.iter().all(|c| matches!(c.source, CandidateSource::GlobalParamEnv(_))) {
1328-
TraitGoalProvenVia::ParamEnv
1329-
} else {
1330-
candidates.retain(|c| !matches!(c.source, CandidateSource::GlobalParamEnv(_)));
1331-
TraitGoalProvenVia::Misc
1332-
};
1322+
let proven_via = if candidates
1323+
.iter()
1324+
.all(|c| matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::Global)))
1325+
{
1326+
TraitGoalProvenVia::ParamEnv
1327+
} else {
1328+
candidates
1329+
.retain(|c| !matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::Global)));
1330+
TraitGoalProvenVia::Misc
1331+
};
13331332

13341333
let all_candidates: Vec<_> = candidates.into_iter().map(|c| c.result).collect();
13351334
if let Some(response) = self.try_merge_responses(&all_candidates) {

compiler/rustc_trait_selection/src/solve/select.rs

-1
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ fn to_selection<'tcx>(
171171
}
172172
CandidateSource::BuiltinImpl(builtin) => ImplSource::Builtin(builtin, nested),
173173
CandidateSource::ParamEnv(_) | CandidateSource::AliasBound => ImplSource::Param(nested),
174-
CandidateSource::GlobalParamEnv(_) => ImplSource::Param(nested),
175174
CandidateSource::CoherenceUnknowable => {
176175
span_bug!(span, "didn't expect to select an unknowable candidate")
177176
}

compiler/rustc_type_ir/src/solve/mod.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,7 @@ pub enum CandidateSource<I: Interner> {
160160
/// (x.clone(), x)
161161
/// }
162162
/// ```
163-
ParamEnv(usize),
164-
/// UWU
165-
GlobalParamEnv(usize),
163+
ParamEnv(ParamEnvSource),
166164
/// If the self type is an alias type, e.g. an opaque type or a projection,
167165
/// we know the bounds on that alias to hold even without knowing its concrete
168166
/// underlying type.
@@ -191,6 +189,14 @@ pub enum CandidateSource<I: Interner> {
191189
CoherenceUnknowable,
192190
}
193191

192+
#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
193+
pub enum ParamEnvSource {
194+
/// Preferred eagerly.
195+
NonGlobal,
196+
// Not considered unless there are non-global param-env candidates too.
197+
Global,
198+
}
199+
194200
#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
195201
#[cfg_attr(
196202
feature = "nightly",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//@ check-pass
2+
//@ compile-flags: -Znext-solver
3+
4+
struct NewSolver;
5+
struct OldSolver;
6+
7+
fn foo<T>()
8+
where
9+
T: Iterator<Item = NewSolver>,
10+
OldSolver: Into<T::Item>,
11+
{
12+
let x: OldSolver = OldSolver.into();
13+
}
14+
15+
fn main() {}

0 commit comments

Comments
 (0)