Skip to content

Commit 306cf28

Browse files
committed
trait_sel: prefer only nested alias bounds
1 parent 3d55379 commit 306cf28

File tree

12 files changed

+124
-65
lines changed

12 files changed

+124
-65
lines changed

Cargo.lock

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ dependencies = [
590590
"serde_json",
591591
"tempfile",
592592
"termize",
593-
"toml 0.9.7",
593+
"toml 0.9.8",
594594
"ui_test",
595595
"walkdir",
596596
]
@@ -632,7 +632,7 @@ dependencies = [
632632
"regex-syntax 0.8.5",
633633
"semver",
634634
"serde",
635-
"toml 0.9.7",
635+
"toml 0.9.8",
636636
"unicode-normalization",
637637
"unicode-script",
638638
"url",
@@ -1164,7 +1164,7 @@ dependencies = [
11641164
"libc",
11651165
"option-ext",
11661166
"redox_users 0.5.2",
1167-
"windows-sys 0.60.2",
1167+
"windows-sys 0.61.2",
11681168
]
11691169

11701170
[[package]]
@@ -2374,7 +2374,7 @@ version = "0.6.1"
23742374
source = "registry+https://github.com/rust-lang/crates.io-index"
23752375
checksum = "536bfad37a309d62069485248eeaba1e8d9853aaf951caaeaed0585a95346f08"
23762376
dependencies = [
2377-
"windows-sys 0.60.2",
2377+
"windows-sys 0.61.2",
23782378
]
23792379

23802380
[[package]]
@@ -5097,9 +5097,9 @@ dependencies = [
50975097

50985098
[[package]]
50995099
name = "serde_spanned"
5100-
version = "1.0.2"
5100+
version = "1.0.3"
51015101
source = "registry+https://github.com/rust-lang/crates.io-index"
5102-
checksum = "5417783452c2be558477e104686f7de5dae53dba813c28435e0e70f82d9b04ee"
5102+
checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392"
51035103
dependencies = [
51045104
"serde_core",
51055105
]
@@ -5585,14 +5585,14 @@ dependencies = [
55855585

55865586
[[package]]
55875587
name = "toml"
5588-
version = "0.9.7"
5588+
version = "0.9.8"
55895589
source = "registry+https://github.com/rust-lang/crates.io-index"
5590-
checksum = "00e5e5d9bf2475ac9d4f0d9edab68cc573dc2fd644b0dba36b0c30a92dd9eaa0"
5590+
checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8"
55915591
dependencies = [
55925592
"indexmap",
55935593
"serde_core",
5594-
"serde_spanned 1.0.2",
5595-
"toml_datetime 0.7.2",
5594+
"serde_spanned 1.0.3",
5595+
"toml_datetime 0.7.3",
55965596
"toml_parser",
55975597
"toml_writer",
55985598
"winnow 0.7.13",
@@ -5609,9 +5609,9 @@ dependencies = [
56095609

56105610
[[package]]
56115611
name = "toml_datetime"
5612-
version = "0.7.2"
5612+
version = "0.7.3"
56135613
source = "registry+https://github.com/rust-lang/crates.io-index"
5614-
checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1"
5614+
checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533"
56155615
dependencies = [
56165616
"serde_core",
56175617
]
@@ -5645,9 +5645,9 @@ dependencies = [
56455645

56465646
[[package]]
56475647
name = "toml_parser"
5648-
version = "1.0.3"
5648+
version = "1.0.4"
56495649
source = "registry+https://github.com/rust-lang/crates.io-index"
5650-
checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627"
5650+
checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e"
56515651
dependencies = [
56525652
"winnow 0.7.13",
56535653
]
@@ -5660,9 +5660,9 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
56605660

56615661
[[package]]
56625662
name = "toml_writer"
5663-
version = "1.0.3"
5663+
version = "1.0.4"
56645664
source = "registry+https://github.com/rust-lang/crates.io-index"
5665-
checksum = "d163a63c116ce562a22cda521fcc4d79152e7aba014456fb5eb442f6d6a10109"
5665+
checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2"
56665666

56675667
[[package]]
56685668
name = "tracing"

compiler/rustc_middle/src/traits/select.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,9 @@ pub enum SelectionCandidate<'tcx> {
116116

117117
/// This is a trait matching with a projected type as `Self`, and we found
118118
/// an applicable bound in the trait definition. The `usize` is an index
119-
/// into the list returned by `tcx.item_bounds`.
120-
ProjectionCandidate(usize),
119+
/// into the list returned by `tcx.item_bounds` and the `bool` is whether
120+
/// this is candidate from recursion on the self type of a projection.
121+
ProjectionCandidate(usize, bool),
121122

122123
/// Implementation of a `Fn`-family trait by one of the anonymous types
123124
/// generated for an `||` expression.

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use derive_where::derive_where;
99
use rustc_type_ir::inherent::*;
1010
use rustc_type_ir::lang_items::SolverTraitLangItem;
1111
use rustc_type_ir::search_graph::CandidateHeadUsages;
12-
use rustc_type_ir::solve::SizedTraitKind;
12+
use rustc_type_ir::solve::{AliasBoundSource, SizedTraitKind};
1313
use rustc_type_ir::{
1414
self as ty, Interner, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable,
1515
TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Upcast,
@@ -451,7 +451,7 @@ where
451451
matches!(
452452
c.source,
453453
CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)
454-
| CandidateSource::AliasBound
454+
| CandidateSource::AliasBound(_)
455455
) && has_no_inference_or_external_constraints(c.result)
456456
})
457457
{
@@ -651,6 +651,7 @@ where
651651
goal,
652652
candidates,
653653
AliasBoundKind::SelfBounds,
654+
AliasBoundSource::NonNested,
654655
);
655656
});
656657
}
@@ -670,6 +671,7 @@ where
670671
goal: Goal<I, G>,
671672
candidates: &mut Vec<Candidate<I>>,
672673
consider_self_bounds: AliasBoundKind,
674+
source: AliasBoundSource,
673675
) {
674676
let (kind, alias_ty) = match self_ty.kind() {
675677
ty::Bool
@@ -711,7 +713,7 @@ where
711713
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
712714
{
713715
candidates.push(Candidate {
714-
source: CandidateSource::AliasBound,
716+
source: CandidateSource::AliasBound(source),
715717
result,
716718
head_usages: CandidateHeadUsages::default(),
717719
});
@@ -735,7 +737,7 @@ where
735737
{
736738
candidates.extend(G::probe_and_consider_implied_clause(
737739
self,
738-
CandidateSource::AliasBound,
740+
CandidateSource::AliasBound(source),
739741
goal,
740742
assumption,
741743
[],
@@ -750,7 +752,7 @@ where
750752
{
751753
candidates.extend(G::probe_and_consider_implied_clause(
752754
self,
753-
CandidateSource::AliasBound,
755+
CandidateSource::AliasBound(source),
754756
goal,
755757
assumption,
756758
[],
@@ -772,6 +774,7 @@ where
772774
goal,
773775
candidates,
774776
AliasBoundKind::NonSelfBounds,
777+
AliasBoundSource::Nested,
775778
),
776779
Err(NoSolution) => {}
777780
}
@@ -1030,7 +1033,7 @@ where
10301033
item_bound.fold_with(&mut ReplaceOpaque { cx: self.cx(), alias_ty, self_ty });
10311034
candidates.extend(G::probe_and_match_goal_against_assumption(
10321035
self,
1033-
CandidateSource::AliasBound,
1036+
CandidateSource::AliasBound(AliasBoundSource::NonNested),
10341037
goal,
10351038
assumption,
10361039
|ecx| {

compiler/rustc_next_trait_solver/src/solve/effect_goals.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
use rustc_type_ir::fast_reject::DeepRejectCtxt;
55
use rustc_type_ir::inherent::*;
66
use rustc_type_ir::lang_items::SolverTraitLangItem;
7-
use rustc_type_ir::solve::SizedTraitKind;
87
use rustc_type_ir::solve::inspect::ProbeKind;
8+
use rustc_type_ir::solve::{AliasBoundSource, SizedTraitKind};
99
use rustc_type_ir::{self as ty, Interner, TypingMode, elaborate};
1010
use tracing::instrument;
1111

@@ -96,7 +96,7 @@ where
9696
) {
9797
candidates.extend(Self::probe_and_match_goal_against_assumption(
9898
ecx,
99-
CandidateSource::AliasBound,
99+
CandidateSource::AliasBound(AliasBoundSource::NonNested),
100100
goal,
101101
clause,
102102
|ecx| {

compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use rustc_type_ir::data_structures::IndexSet;
44
use rustc_type_ir::fast_reject::DeepRejectCtxt;
55
use rustc_type_ir::inherent::*;
66
use rustc_type_ir::lang_items::SolverTraitLangItem;
7-
use rustc_type_ir::solve::{CandidatePreferenceMode, CanonicalResponse, SizedTraitKind};
7+
use rustc_type_ir::solve::{
8+
AliasBoundSource, CandidatePreferenceMode, CanonicalResponse, SizedTraitKind,
9+
};
810
use rustc_type_ir::{
911
self as ty, Interner, Movability, PredicatePolarity, TraitPredicate, TraitRef,
1012
TypeVisitableExt as _, TypingMode, Upcast as _, elaborate,
@@ -1381,22 +1383,23 @@ where
13811383
return Ok((candidate.result, Some(TraitGoalProvenVia::Misc)));
13821384
}
13831385

1384-
let potential_alias_bound_response =
1385-
candidates.iter().any(|c| matches!(c.source, CandidateSource::AliasBound)).then(|| {
1386-
let alias_bounds: Vec<_> = candidates
1387-
.extract_if(.., |c| matches!(c.source, CandidateSource::AliasBound))
1388-
.collect();
1389-
if let Some((response, _)) = self.try_merge_candidates(&alias_bounds) {
1390-
(response, Some(TraitGoalProvenVia::AliasBound))
1391-
} else {
1392-
(self.bail_with_ambiguity(&alias_bounds), None)
1393-
}
1394-
});
1395-
1386+
// Extract non-nested alias bound candidates, will be preferred over where bounds if
1387+
// `candidate_preference_mode == CandidatePreferenceMode::Marker`.
13961388
if matches!(candidate_preference_mode, CandidatePreferenceMode::Marker)
1397-
&& let Some(alias_bound_response) = potential_alias_bound_response
1389+
&& candidates.iter().any(|c| {
1390+
matches!(c.source, CandidateSource::AliasBound(AliasBoundSource::NonNested))
1391+
})
13981392
{
1399-
return Ok(alias_bound_response);
1393+
let alias_bounds: Vec<_> = candidates
1394+
.extract_if(.., |c| {
1395+
matches!(c.source, CandidateSource::AliasBound(AliasBoundSource::NonNested))
1396+
})
1397+
.collect();
1398+
return if let Some((response, _)) = self.try_merge_candidates(&alias_bounds) {
1399+
Ok((response, Some(TraitGoalProvenVia::AliasBound)))
1400+
} else {
1401+
Ok((self.bail_with_ambiguity(&alias_bounds), None))
1402+
};
14001403
}
14011404

14021405
// If there are non-global where-bounds, prefer where-bounds
@@ -1446,8 +1449,16 @@ where
14461449
};
14471450
}
14481451

1449-
if let Some(response) = potential_alias_bound_response {
1450-
return Ok(response);
1452+
// Next, prefer any alias bound (nested or otherwise)..
1453+
if candidates.iter().any(|c| matches!(c.source, CandidateSource::AliasBound(_))) {
1454+
let alias_bounds: Vec<_> = candidates
1455+
.extract_if(.., |c| matches!(c.source, CandidateSource::AliasBound(_)))
1456+
.collect();
1457+
return if let Some((response, _)) = self.try_merge_candidates(&alias_bounds) {
1458+
Ok((response, Some(TraitGoalProvenVia::AliasBound)))
1459+
} else {
1460+
Ok((self.bail_with_ambiguity(&alias_bounds), None))
1461+
};
14511462
}
14521463

14531464
self.filter_specialized_impls(AllowInferenceConstraints::No, &mut candidates);

compiler/rustc_trait_selection/src/solve/select.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,9 @@ fn candidate_should_be_dropped_in_favor_of<'tcx>(
126126
// Prefer dyn candidates over non-dyn candidates. This is necessary to
127127
// handle the unsoundness between `impl<T: ?Sized> Any for T` and `dyn Any: Any`.
128128
(
129-
CandidateSource::Impl(_) | CandidateSource::ParamEnv(_) | CandidateSource::AliasBound,
129+
CandidateSource::Impl(_)
130+
| CandidateSource::ParamEnv(_)
131+
| CandidateSource::AliasBound(_),
130132
CandidateSource::BuiltinImpl(BuiltinImplSource::Object { .. }),
131133
) => true,
132134

@@ -175,7 +177,9 @@ fn to_selection<'tcx>(
175177
})
176178
}
177179
CandidateSource::BuiltinImpl(builtin) => ImplSource::Builtin(builtin, nested),
178-
CandidateSource::ParamEnv(_) | CandidateSource::AliasBound => ImplSource::Param(nested),
180+
CandidateSource::ParamEnv(_) | CandidateSource::AliasBound(_) => {
181+
ImplSource::Param(nested)
182+
}
179183
CandidateSource::CoherenceUnknowable => {
180184
span_bug!(span, "didn't expect to select an unknowable candidate")
181185
}

compiler/rustc_trait_selection/src/traits/project.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,7 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
741741
let mut ambiguous = false;
742742
let _ = selcx.for_each_item_bound(
743743
obligation.predicate.self_ty(),
744-
|selcx, clause, _| {
744+
|selcx, clause, _, _| {
745745
let Some(clause) = clause.as_projection_clause() else {
746746
return ControlFlow::Continue(());
747747
};

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
208208
let mut distinct_normalized_bounds = FxHashSet::default();
209209
let _ = self.for_each_item_bound::<!>(
210210
placeholder_trait_predicate.self_ty(),
211-
|selcx, bound, idx| {
211+
|selcx, bound, idx, nested| {
212212
let Some(bound) = bound.as_trait_clause() else {
213213
return ControlFlow::Continue(());
214214
};
@@ -224,18 +224,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
224224
);
225225

226226
// We checked the polarity already
227+
debug!(?idx, ?nested, ?bound);
227228
match selcx.match_normalize_trait_ref(
228229
obligation,
229230
placeholder_trait_predicate.trait_ref,
230231
bound.map_bound(|pred| pred.trait_ref),
231232
) {
232233
Ok(None) => {
233-
candidates.vec.push(ProjectionCandidate(idx));
234+
candidates.vec.push(ProjectionCandidate(idx, nested));
234235
}
235236
Ok(Some(normalized_trait))
236237
if distinct_normalized_bounds.insert(normalized_trait) =>
237238
{
238-
candidates.vec.push(ProjectionCandidate(idx));
239+
candidates.vec.push(ProjectionCandidate(idx, nested));
239240
}
240241
_ => {}
241242
}
@@ -825,7 +826,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
825826
}
826827

827828
ty::Alias(ty::Opaque, alias) => {
828-
if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(_))) {
829+
if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(..))) {
829830
// We do not generate an auto impl candidate for `impl Trait`s which already
830831
// reference our auto trait.
831832
//

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
6767
ImplSource::Builtin(BuiltinImplSource::Misc, data)
6868
}
6969

70-
ProjectionCandidate(idx) => {
70+
ProjectionCandidate(idx, _) => {
7171
let obligations = self.confirm_projection_candidate(obligation, idx)?;
7272
ImplSource::Param(obligations)
7373
}
@@ -150,7 +150,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
150150
let candidate_predicate = self
151151
.for_each_item_bound(
152152
placeholder_self_ty,
153-
|_, clause, clause_idx| {
153+
|_, clause, clause_idx, _| {
154154
if clause_idx == idx {
155155
ControlFlow::Break(clause)
156156
} else {

0 commit comments

Comments
 (0)