Skip to content

Commit 6ecf738

Browse files
committed
upstream: rust-lang#144064
1 parent 6c0a912 commit 6ecf738

File tree

42 files changed

+406
-248
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+406
-248
lines changed

compiler/rustc_middle/src/ty/context.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
495495
self.is_default_trait(def_id)
496496
}
497497

498+
fn is_sizedness_trait(self, def_id: DefId) -> bool {
499+
self.is_sizedness_trait(def_id)
500+
}
501+
498502
fn as_lang_item(self, def_id: DefId) -> Option<TraitSolverLangItem> {
499503
lang_item_to_trait_lang_item(self.lang_items().from_def_id(def_id)?)
500504
}
@@ -1652,6 +1656,10 @@ impl<'tcx> TyCtxt<'tcx> {
16521656
.any(|&default_trait| self.lang_items().get(default_trait) == Some(def_id))
16531657
}
16541658

1659+
pub fn is_sizedness_trait(self, def_id: DefId) -> bool {
1660+
matches!(self.as_lang_item(def_id), Some(LangItem::Sized | LangItem::MetaSized))
1661+
}
1662+
16551663
/// Returns a range of the start/end indices specified with the
16561664
/// `rustc_layout_scalar_valid_range` attribute.
16571665
// FIXME(eddyb) this is an awkward spot for this method, maybe move it?

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ pub use rustc_type_ir::fast_reject::DeepRejectCtxt;
5959
)]
6060
use rustc_type_ir::inherent;
6161
pub use rustc_type_ir::relate::VarianceDiagInfo;
62-
pub use rustc_type_ir::solve::SizedTraitKind;
62+
pub use rustc_type_ir::solve::{CandidatePreferenceMode, SizedTraitKind};
6363
pub use rustc_type_ir::*;
6464
#[allow(hidden_glob_reexports, unused_imports)]
6565
use rustc_type_ir::{InferCtxtLike, Interner};

compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ 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::TraitSolverLangItem;
7-
use rustc_type_ir::solve::{CanonicalResponse, SizedTraitKind};
7+
use rustc_type_ir::solve::{CandidatePreferenceMode, CanonicalResponse, SizedTraitKind};
88
use rustc_type_ir::{
99
self as ty, Interner, Movability, TraitPredicate, TraitRef, TypeVisitableExt as _, TypingMode,
1010
Upcast as _, elaborate,
@@ -1343,6 +1343,7 @@ where
13431343
#[instrument(level = "debug", skip(self), ret)]
13441344
pub(super) fn merge_trait_candidates(
13451345
&mut self,
1346+
candidate_preference_mode: CandidatePreferenceMode,
13461347
mut candidates: Vec<Candidate<I>>,
13471348
) -> Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>), NoSolution> {
13481349
if let TypingMode::Coherence = self.typing_mode() {
@@ -1368,6 +1369,26 @@ where
13681369
return Ok((candidate.result, Some(TraitGoalProvenVia::Misc)));
13691370
}
13701371

1372+
let potential_alias_bound_response =
1373+
candidates.iter().any(|c| matches!(c.source, CandidateSource::AliasBound)).then(|| {
1374+
let alias_bounds: Vec<_> = candidates
1375+
.iter()
1376+
.filter(|c| matches!(c.source, CandidateSource::AliasBound))
1377+
.map(|c| c.result)
1378+
.collect();
1379+
if let Some(response) = self.try_merge_responses(&alias_bounds) {
1380+
(response, Some(TraitGoalProvenVia::AliasBound))
1381+
} else {
1382+
(self.bail_with_ambiguity(&alias_bounds), None)
1383+
}
1384+
});
1385+
1386+
if matches!(candidate_preference_mode, CandidatePreferenceMode::Marker)
1387+
&& let Some(alias_bound_response) = potential_alias_bound_response
1388+
{
1389+
return Ok(alias_bound_response);
1390+
}
1391+
13711392
// If there are non-global where-bounds, prefer where-bounds
13721393
// (including global ones) over everything else.
13731394
let has_non_global_where_bounds = candidates
@@ -1386,17 +1407,8 @@ where
13861407
};
13871408
}
13881409

1389-
if candidates.iter().any(|c| matches!(c.source, CandidateSource::AliasBound)) {
1390-
let alias_bounds: Vec<_> = candidates
1391-
.iter()
1392-
.filter(|c| matches!(c.source, CandidateSource::AliasBound))
1393-
.map(|c| c.result)
1394-
.collect();
1395-
return if let Some(response) = self.try_merge_responses(&alias_bounds) {
1396-
Ok((response, Some(TraitGoalProvenVia::AliasBound)))
1397-
} else {
1398-
Ok((self.bail_with_ambiguity(&alias_bounds), None))
1399-
};
1410+
if let Some(response) = potential_alias_bound_response {
1411+
return Ok(response);
14001412
}
14011413

14021414
self.filter_specialized_impls(AllowInferenceConstraints::No, &mut candidates);
@@ -1431,7 +1443,10 @@ where
14311443
goal: Goal<I, TraitPredicate<I>>,
14321444
) -> Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>), NoSolution> {
14331445
let candidates = self.assemble_and_evaluate_candidates(goal, AssembleCandidatesFrom::All);
1434-
self.merge_trait_candidates(candidates)
1446+
1447+
let candidate_preference_mode =
1448+
CandidatePreferenceMode::compute(self.cx(), goal.predicate.def_id());
1449+
self.merge_trait_candidates(candidate_preference_mode, candidates)
14351450
}
14361451

14371452
fn try_stall_coroutine_witness(

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

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
144144
obligation: &PolyTraitObligation<'tcx>,
145145
idx: usize,
146146
) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
147-
let tcx = self.tcx();
148-
149147
let placeholder_trait_predicate =
150148
self.infcx.enter_forall_and_leak_universe(obligation.predicate).trait_ref;
151149
let placeholder_self_ty = self.infcx.shallow_resolve(placeholder_trait_predicate.self_ty());
@@ -194,28 +192,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
194192
.map_err(|_| SelectionError::Unimplemented)?,
195193
);
196194

197-
// FIXME(compiler-errors): I don't think this is needed.
198-
if let ty::Alias(ty::Projection, alias_ty) = placeholder_self_ty.kind() {
199-
let predicates = tcx.predicates_of(alias_ty.def_id).instantiate_own(tcx, alias_ty.args);
200-
for (predicate, _) in predicates {
201-
let normalized = normalize_with_depth_to(
202-
self,
203-
obligation.param_env,
204-
obligation.cause.clone(),
205-
obligation.recursion_depth + 1,
206-
predicate,
207-
&mut obligations,
208-
);
209-
obligations.push(Obligation::with_depth(
210-
self.tcx(),
211-
obligation.cause.clone(),
212-
obligation.recursion_depth + 1,
213-
obligation.param_env,
214-
normalized,
215-
));
216-
}
217-
}
218-
219195
Ok(obligations)
220196
}
221197

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

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ use rustc_middle::ty::abstract_const::NotConstEvaluatable;
2828
use rustc_middle::ty::error::TypeErrorToStringExt;
2929
use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths};
3030
use rustc_middle::ty::{
31-
self, DeepRejectCtxt, GenericArgsRef, PolyProjectionPredicate, SizedTraitKind, Ty, TyCtxt,
32-
TypeFoldable, TypeVisitableExt, TypingMode, Upcast, elaborate, may_use_unstable_feature,
31+
self, CandidatePreferenceMode, DeepRejectCtxt, GenericArgsRef, PolyProjectionPredicate,
32+
SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, TypingMode, Upcast, elaborate,
33+
may_use_unstable_feature,
3334
};
3435
use rustc_span::{Symbol, sym};
3536
use tracing::{debug, instrument, trace};
@@ -474,7 +475,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
474475
}
475476
} else {
476477
let has_non_region_infer = stack.obligation.predicate.has_non_region_infer();
477-
if let Some(candidate) = self.winnow_candidates(has_non_region_infer, candidates) {
478+
let candidate_preference_mode =
479+
CandidatePreferenceMode::compute(self.tcx(), stack.obligation.predicate.def_id());
480+
if let Some(candidate) =
481+
self.winnow_candidates(has_non_region_infer, candidate_preference_mode, candidates)
482+
{
478483
self.filter_reservation_impls(candidate)
479484
} else {
480485
Ok(None)
@@ -1824,6 +1829,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
18241829
fn winnow_candidates(
18251830
&mut self,
18261831
has_non_region_infer: bool,
1832+
candidate_preference_mode: CandidatePreferenceMode,
18271833
mut candidates: Vec<EvaluatedCandidate<'tcx>>,
18281834
) -> Option<SelectionCandidate<'tcx>> {
18291835
if candidates.len() == 1 {
@@ -1877,6 +1883,19 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
18771883
break;
18781884
}
18791885

1886+
let alias_bound = candidates
1887+
.iter()
1888+
.filter_map(|c| if let ProjectionCandidate(i) = c.candidate { Some(i) } else { None })
1889+
.try_reduce(|c1, c2| if has_non_region_infer { None } else { Some(c1.min(c2)) });
1890+
1891+
if matches!(candidate_preference_mode, CandidatePreferenceMode::Marker) {
1892+
match alias_bound {
1893+
Some(Some(index)) => return Some(ProjectionCandidate(index)),
1894+
Some(None) => {}
1895+
None => return None,
1896+
}
1897+
}
1898+
18801899
// The next highest priority is for non-global where-bounds. However, while we don't
18811900
// prefer global where-clauses here, we do bail with ambiguity when encountering both
18821901
// a global and a non-global where-clause.
@@ -1910,10 +1929,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
19101929
// fairly arbitrary but once again necessary for backwards compatibility.
19111930
// If there are multiple applicable candidates which don't affect type inference,
19121931
// choose the one with the lowest index.
1913-
let alias_bound = candidates
1914-
.iter()
1915-
.filter_map(|c| if let ProjectionCandidate(i) = c.candidate { Some(i) } else { None })
1916-
.try_reduce(|c1, c2| if has_non_region_infer { None } else { Some(c1.min(c2)) });
19171932
match alias_bound {
19181933
Some(Some(index)) => return Some(ProjectionCandidate(index)),
19191934
Some(None) => {}

compiler/rustc_trait_selection/src/traits/util.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -379,13 +379,6 @@ pub fn sizedness_fast_path<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
379379
_ => return false,
380380
};
381381

382-
// FIXME(sized_hierarchy): this temporarily reverts the `sized_hierarchy` feature
383-
// while a proper fix for `tests/ui/sized-hierarchy/incomplete-inference-issue-143992.rs`
384-
// is pending a proper fix
385-
if !tcx.features().sized_hierarchy() && matches!(sizedness, SizedTraitKind::MetaSized) {
386-
return true;
387-
}
388-
389382
if trait_pred.self_ty().has_trivial_sizedness(tcx, sizedness) {
390383
debug!("fast path -- trivial sizedness");
391384
return true;

compiler/rustc_type_ir/src/interner.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,8 @@ pub trait Interner:
308308

309309
fn is_default_trait(self, def_id: Self::DefId) -> bool;
310310

311+
fn is_sizedness_trait(self, def_id: Self::DefId) -> bool;
312+
311313
fn as_lang_item(self, def_id: Self::DefId) -> Option<TraitSolverLangItem>;
312314

313315
fn associated_type_def_ids(self, def_id: Self::DefId) -> impl IntoIterator<Item = Self::DefId>;

compiler/rustc_type_ir/src/solve/mod.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,30 @@ pub struct PredefinedOpaquesData<I: Interner> {
125125
pub opaque_types: Vec<(ty::OpaqueTypeKey<I>, I::Ty)>,
126126
}
127127

128+
/// Which trait candidates should be preferred over other candidates? By default, prefer where
129+
/// bounds over alias bounds. For marker traits, prefer alias bounds over where bounds.
130+
#[derive(Clone, Copy, Debug)]
131+
pub enum CandidatePreferenceMode {
132+
/// Prefers where bounds over alias bounds
133+
Default,
134+
/// Prefers alias bounds over where bounds
135+
Marker,
136+
}
137+
138+
impl CandidatePreferenceMode {
139+
/// Given `trait_def_id`, which candidate preference mode should be used?
140+
pub fn compute<I: Interner>(cx: I, trait_def_id: I::DefId) -> CandidatePreferenceMode {
141+
let is_sizedness_or_auto_or_default_goal = cx.is_sizedness_trait(trait_def_id)
142+
|| cx.trait_is_auto(trait_def_id)
143+
|| cx.is_default_trait(trait_def_id);
144+
if is_sizedness_or_auto_or_default_goal {
145+
CandidatePreferenceMode::Marker
146+
} else {
147+
CandidatePreferenceMode::Default
148+
}
149+
}
150+
}
151+
128152
/// Possible ways the given goal can be proven.
129153
#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
130154
pub enum CandidateSource<I: Interner> {

tests/ui/async-await/higher-ranked-auto-trait-14.no_assumptions.stderr

Lines changed: 0 additions & 33 deletions
This file was deleted.

tests/ui/async-await/higher-ranked-auto-trait-14.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//@ revisions: assumptions no_assumptions
44
//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
55
//@[assumptions] check-pass
6-
//@[no_assumptions] known-bug: #110338
6+
//@[no_assumptions] check-pass
77

88
use std::collections::HashSet;
99
use std::future::Future;

0 commit comments

Comments
 (0)