trait_sel: sizedness goals prefer alias candidates

For sizedness, default and auto trait predicates, now prefer non-param
candidates if any exist. As these traits do not have generic parameters,
it never makes sense to prefer an non-alias candidate, as there can
never be a more permissive candidate.
This commit is contained in:
David Wood 2025-07-17 09:21:51 +00:00
parent efaeacfc96
commit 321a47eb2c
No known key found for this signature in database
19 changed files with 722 additions and 81 deletions

View file

@ -521,6 +521,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
self.is_default_trait(def_id)
}
fn is_sizedness_trait(self, def_id: DefId) -> bool {
self.is_sizedness_trait(def_id)
}
fn as_lang_item(self, def_id: DefId) -> Option<SolverLangItem> {
lang_item_to_solver_lang_item(self.lang_items().from_def_id(def_id)?)
}
@ -1787,6 +1791,10 @@ impl<'tcx> TyCtxt<'tcx> {
.any(|&default_trait| self.lang_items().get(default_trait) == Some(def_id))
}
pub fn is_sizedness_trait(self, def_id: DefId) -> bool {
matches!(self.as_lang_item(def_id), Some(LangItem::Sized | LangItem::MetaSized))
}
/// Returns a range of the start/end indices specified with the
/// `rustc_layout_scalar_valid_range` attribute.
// FIXME(eddyb) this is an awkward spot for this method, maybe move it?

View file

@ -59,7 +59,7 @@ pub use rustc_type_ir::fast_reject::DeepRejectCtxt;
)]
use rustc_type_ir::inherent;
pub use rustc_type_ir::relate::VarianceDiagInfo;
pub use rustc_type_ir::solve::SizedTraitKind;
pub use rustc_type_ir::solve::{CandidatePreferenceMode, SizedTraitKind};
pub use rustc_type_ir::*;
#[allow(hidden_glob_reexports, unused_imports)]
use rustc_type_ir::{InferCtxtLike, Interner};

View file

@ -4,7 +4,7 @@ use rustc_type_ir::data_structures::IndexSet;
use rustc_type_ir::fast_reject::DeepRejectCtxt;
use rustc_type_ir::inherent::*;
use rustc_type_ir::lang_items::SolverTraitLangItem;
use rustc_type_ir::solve::{CanonicalResponse, SizedTraitKind};
use rustc_type_ir::solve::{CandidatePreferenceMode, CanonicalResponse, SizedTraitKind};
use rustc_type_ir::{
self as ty, Interner, Movability, PredicatePolarity, TraitPredicate, TraitRef,
TypeVisitableExt as _, TypingMode, Upcast as _, elaborate,
@ -1355,6 +1355,7 @@ where
#[instrument(level = "debug", skip(self), ret)]
pub(super) fn merge_trait_candidates(
&mut self,
candidate_preference_mode: CandidatePreferenceMode,
mut candidates: Vec<Candidate<I>>,
failed_candidate_info: FailedCandidateInfo,
) -> Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>), NoSolution> {
@ -1380,6 +1381,24 @@ where
return Ok((candidate.result, Some(TraitGoalProvenVia::Misc)));
}
let potential_alias_bound_response =
candidates.iter().any(|c| matches!(c.source, CandidateSource::AliasBound)).then(|| {
let alias_bounds: Vec<_> = candidates
.extract_if(.., |c| matches!(c.source, CandidateSource::AliasBound))
.collect();
if let Some((response, _)) = self.try_merge_candidates(&alias_bounds) {
(response, Some(TraitGoalProvenVia::AliasBound))
} else {
(self.bail_with_ambiguity(&alias_bounds), None)
}
});
if matches!(candidate_preference_mode, CandidatePreferenceMode::Marker)
&& let Some(alias_bound_response) = potential_alias_bound_response
{
return Ok(alias_bound_response);
}
// If there are non-global where-bounds, prefer where-bounds
// (including global ones) over everything else.
let has_non_global_where_bounds = candidates
@ -1427,15 +1446,8 @@ where
};
}
if candidates.iter().any(|c| matches!(c.source, CandidateSource::AliasBound)) {
let alias_bounds: Vec<_> = candidates
.extract_if(.., |c| matches!(c.source, CandidateSource::AliasBound))
.collect();
return if let Some((response, _)) = self.try_merge_candidates(&alias_bounds) {
Ok((response, Some(TraitGoalProvenVia::AliasBound)))
} else {
Ok((self.bail_with_ambiguity(&alias_bounds), None))
};
if let Some(response) = potential_alias_bound_response {
return Ok(response);
}
self.filter_specialized_impls(AllowInferenceConstraints::No, &mut candidates);
@ -1470,7 +1482,9 @@ where
) -> Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>), NoSolution> {
let (candidates, failed_candidate_info) =
self.assemble_and_evaluate_candidates(goal, AssembleCandidatesFrom::All);
self.merge_trait_candidates(candidates, failed_candidate_info)
let candidate_preference_mode =
CandidatePreferenceMode::compute(self.cx(), goal.predicate.def_id());
self.merge_trait_candidates(candidate_preference_mode, candidates, failed_candidate_info)
}
fn try_stall_coroutine(&mut self, self_ty: I::Ty) -> Option<Result<Candidate<I>, NoSolution>> {

View file

@ -28,8 +28,9 @@ use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::error::TypeErrorToStringExt;
use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths};
use rustc_middle::ty::{
self, DeepRejectCtxt, GenericArgsRef, PolyProjectionPredicate, SizedTraitKind, Ty, TyCtxt,
TypeFoldable, TypeVisitableExt, TypingMode, Upcast, elaborate, may_use_unstable_feature,
self, CandidatePreferenceMode, DeepRejectCtxt, GenericArgsRef, PolyProjectionPredicate,
SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, TypingMode, Upcast, elaborate,
may_use_unstable_feature,
};
use rustc_span::{Symbol, sym};
use tracing::{debug, instrument, trace};
@ -474,7 +475,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
} else {
let has_non_region_infer = stack.obligation.predicate.has_non_region_infer();
if let Some(candidate) = self.winnow_candidates(has_non_region_infer, candidates) {
let candidate_preference_mode =
CandidatePreferenceMode::compute(self.tcx(), stack.obligation.predicate.def_id());
if let Some(candidate) =
self.winnow_candidates(has_non_region_infer, candidate_preference_mode, candidates)
{
self.filter_reservation_impls(candidate)
} else {
Ok(None)
@ -1821,6 +1826,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
fn winnow_candidates(
&mut self,
has_non_region_infer: bool,
candidate_preference_mode: CandidatePreferenceMode,
mut candidates: Vec<EvaluatedCandidate<'tcx>>,
) -> Option<SelectionCandidate<'tcx>> {
if candidates.len() == 1 {
@ -1874,6 +1880,19 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
break;
}
let alias_bound = candidates
.iter()
.filter_map(|c| if let ProjectionCandidate(i) = c.candidate { Some(i) } else { None })
.try_reduce(|c1, c2| if has_non_region_infer { None } else { Some(c1.min(c2)) });
if matches!(candidate_preference_mode, CandidatePreferenceMode::Marker) {
match alias_bound {
Some(Some(index)) => return Some(ProjectionCandidate(index)),
Some(None) => {}
None => return None,
}
}
// The next highest priority is for non-global where-bounds. However, while we don't
// prefer global where-clauses here, we do bail with ambiguity when encountering both
// a global and a non-global where-clause.
@ -1907,10 +1926,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
// fairly arbitrary but once again necessary for backwards compatibility.
// If there are multiple applicable candidates which don't affect type inference,
// choose the one with the lowest index.
let alias_bound = candidates
.iter()
.filter_map(|c| if let ProjectionCandidate(i) = c.candidate { Some(i) } else { None })
.try_reduce(|c1, c2| if has_non_region_infer { None } else { Some(c1.min(c2)) });
match alias_bound {
Some(Some(index)) => return Some(ProjectionCandidate(index)),
Some(None) => {}

View file

@ -333,6 +333,8 @@ pub trait Interner:
fn is_default_trait(self, def_id: Self::TraitId) -> bool;
fn is_sizedness_trait(self, def_id: Self::TraitId) -> bool;
fn as_lang_item(self, def_id: Self::DefId) -> Option<SolverLangItem>;
fn as_trait_lang_item(self, def_id: Self::TraitId) -> Option<SolverTraitLangItem>;

View file

@ -109,6 +109,30 @@ pub struct QueryInput<I: Interner, P> {
impl<I: Interner, P: Eq> Eq for QueryInput<I, P> {}
/// Which trait candidates should be preferred over other candidates? By default, prefer where
/// bounds over alias bounds. For marker traits, prefer alias bounds over where bounds.
#[derive(Clone, Copy, Debug)]
pub enum CandidatePreferenceMode {
/// Prefers where bounds over alias bounds
Default,
/// Prefers alias bounds over where bounds
Marker,
}
impl CandidatePreferenceMode {
/// Given `trait_def_id`, which candidate preference mode should be used?
pub fn compute<I: Interner>(cx: I, trait_id: I::TraitId) -> CandidatePreferenceMode {
let is_sizedness_or_auto_or_default_goal = cx.is_sizedness_trait(trait_id)
|| cx.trait_is_auto(trait_id)
|| cx.is_default_trait(trait_id);
if is_sizedness_or_auto_or_default_goal {
CandidatePreferenceMode::Marker
} else {
CandidatePreferenceMode::Default
}
}
}
/// Possible ways the given goal can be proven.
#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
pub enum CandidateSource<I: Interner> {

View file

@ -0,0 +1,292 @@
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:54:5
|
LL | / fn call_1<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future1<'cx>
LL | | where
LL | | 's: 'cx,
| |________________^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:54:5
|
LL | / fn call_1<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future1<'cx>
LL | | where
LL | | 's: 'cx,
| |________________^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:63:5
|
LL | / fn call_2<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future2<'cx>
LL | | where
LL | | 's: 'cx,
| |________________^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:63:5
|
LL | / fn call_2<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future2<'cx>
LL | | where
LL | | 's: 'cx,
| |________________^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:40:31
|
LL | impl<FI1, FI2> IterCaller for UseIter<FI1, FI2>
| ^^^^^^^^^^^^^^^^^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:46:5
|
LL | type Future1<'cx> = impl Future<Output = ()> + Send + 'cx
| ^^^^^^^^^^^^^^^^^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:50:5
|
LL | type Future2<'cx> = impl Future<Output = ()> + Send + 'cx
| ^^^^^^^^^^^^^^^^^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:54:50
|
LL | fn call_1<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future1<'cx>
| ^^^^^^^^^^^^^^^^^^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:63:50
|
LL | fn call_2<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future2<'cx>
| ^^^^^^^^^^^^^^^^^^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
error: higher-ranked subtype error
--> $DIR/higher-ranked-auto-trait-3.rs:54:5
|
LL | / fn call_1<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future1<'cx>
LL | | where
LL | | 's: 'cx,
| |________________^
error: higher-ranked subtype error
--> $DIR/higher-ranked-auto-trait-3.rs:54:5
|
LL | / fn call_1<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future1<'cx>
LL | | where
LL | | 's: 'cx,
| |________________^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:58:9
|
LL | / async {
LL | | self.fi_1.get_iter(cx).await;
LL | | }
| |_________^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:58:9
|
LL | / async {
LL | | self.fi_1.get_iter(cx).await;
LL | | }
| |_________^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: higher-ranked subtype error
--> $DIR/higher-ranked-auto-trait-3.rs:63:5
|
LL | / fn call_2<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future2<'cx>
LL | | where
LL | | 's: 'cx,
| |________________^
error: higher-ranked subtype error
--> $DIR/higher-ranked-auto-trait-3.rs:63:5
|
LL | / fn call_2<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future2<'cx>
LL | | where
LL | | 's: 'cx,
| |________________^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:67:9
|
LL | / async {
LL | | self.fi_2.get_iter(cx).await;
LL | | }
| |_________^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:67:9
|
LL | / async {
LL | | self.fi_2.get_iter(cx).await;
LL | | }
| |_________^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 17 previous errors

View file

@ -1,5 +1,305 @@
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:66:9
--> $DIR/higher-ranked-auto-trait-3.rs:54:5
|
LL | / fn call_1<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future1<'cx>
LL | | where
LL | | 's: 'cx,
| |________________^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:54:5
|
LL | / fn call_1<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future1<'cx>
LL | | where
LL | | 's: 'cx,
| |________________^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:63:5
|
LL | / fn call_2<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future2<'cx>
LL | | where
LL | | 's: 'cx,
| |________________^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:63:5
|
LL | / fn call_2<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future2<'cx>
LL | | where
LL | | 's: 'cx,
| |________________^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:40:31
|
LL | impl<FI1, FI2> IterCaller for UseIter<FI1, FI2>
| ^^^^^^^^^^^^^^^^^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:46:5
|
LL | type Future1<'cx> = impl Future<Output = ()> + Send + 'cx
| ^^^^^^^^^^^^^^^^^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:50:5
|
LL | type Future2<'cx> = impl Future<Output = ()> + Send + 'cx
| ^^^^^^^^^^^^^^^^^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:54:50
|
LL | fn call_1<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future1<'cx>
| ^^^^^^^^^^^^^^^^^^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:63:50
|
LL | fn call_2<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future2<'cx>
| ^^^^^^^^^^^^^^^^^^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
error: higher-ranked subtype error
--> $DIR/higher-ranked-auto-trait-3.rs:54:5
|
LL | / fn call_1<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future1<'cx>
LL | | where
LL | | 's: 'cx,
| |________________^
error: higher-ranked subtype error
--> $DIR/higher-ranked-auto-trait-3.rs:54:5
|
LL | / fn call_1<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future1<'cx>
LL | | where
LL | | 's: 'cx,
| |________________^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:58:9
|
LL | / async {
LL | | self.fi_1.get_iter(cx).await;
LL | | }
| |_________^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:58:9
|
LL | / async {
LL | | self.fi_1.get_iter(cx).await;
LL | | }
| |_________^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:58:9
|
LL | / async {
LL | | self.fi_1.get_iter(cx).await;
LL | | }
| |_________^
|
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
error: higher-ranked subtype error
--> $DIR/higher-ranked-auto-trait-3.rs:63:5
|
LL | / fn call_2<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future2<'cx>
LL | | where
LL | | 's: 'cx,
| |________________^
error: higher-ranked subtype error
--> $DIR/higher-ranked-auto-trait-3.rs:63:5
|
LL | / fn call_2<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future2<'cx>
LL | | where
LL | | 's: 'cx,
| |________________^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:67:9
|
LL | / async {
LL | | self.fi_2.get_iter(cx).await;
LL | | }
| |_________^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:67:9
|
LL | / async {
LL | | self.fi_2.get_iter(cx).await;
LL | | }
| |_________^
|
note: the lifetime `'cx` defined here...
--> $DIR/higher-ranked-auto-trait-3.rs:43:13
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^^
note: ...must outlive the lifetime `'s` defined here
--> $DIR/higher-ranked-auto-trait-3.rs:43:9
|
LL | for<'s, 'cx> FI1::Future<'s, 'cx>: Send,
| ^^
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:67:9
|
LL | / async {
LL | | self.fi_2.get_iter(cx).await;
@ -8,5 +308,5 @@ LL | | }
|
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
error: aborting due to 1 previous error
error: aborting due to 19 previous errors

View file

@ -2,7 +2,8 @@
//@ edition: 2021
//@ revisions: assumptions no_assumptions
//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
//@[assumptions] check-pass
//@[assumptions] check-fail
//@[assumptions] known-bug: #110338
//@[no_assumptions] known-bug: #110338
#![feature(impl_trait_in_assoc_type)]

View file

@ -1,4 +1,4 @@
//@ check-pass
//@ check-fail
pub trait Trait {
type Assoc<'a> where Self: 'a;
@ -11,7 +11,7 @@ where
pub struct Type;
impl<T: Trait> Foo<T> for Type
impl<T: Trait> Foo<T> for Type //~ ERROR: the parameter type `T` may not live long enough
where
for<'a> T::Assoc<'a>: Clone
{}

View file

@ -0,0 +1,19 @@
error[E0311]: the parameter type `T` may not live long enough
--> $DIR/issue-93262.rs:14:16
|
LL | impl<T: Trait> Foo<T> for Type
| ^^^^^^
| |
| the parameter type `T` must be valid for lifetime `'a`...
| ...so that the type `T` will meet its required lifetime bounds...
|
note: ...that is required by this bound
--> $DIR/issue-93262.rs:9:27
|
LL | for<'a> T::Assoc<'a>: Clone
| ^^^^^
= help: consider adding an explicit lifetime bound `T: 'a`...
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0311`.

View file

@ -0,0 +1,14 @@
error[E0282]: type annotations needed for `<X as Trait<'static>>::Out<_>`
--> $DIR/norm-before-method-resolution-opaque-type.rs:25:9
|
LL | let x = *x;
| ^
|
help: consider giving `x` an explicit type, where the placeholders `_` are specified
|
LL | let x: <_ as Trait<'static>>::Out<_> = *x;
| +++++++++++++++++++++++++++++++
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0282`.

View file

@ -1,5 +1,5 @@
error[E0507]: cannot move out of `*x` which is behind a shared reference
--> $DIR/norm-before-method-resolution-opaque-type.rs:22:13
--> $DIR/norm-before-method-resolution-opaque-type.rs:25:13
|
LL | let x = *x;
| ^^ move occurs because `*x` has type `<X as Trait<'_>>::Out<Foo>`, which does not implement the `Copy` trait

View file

@ -1,6 +1,9 @@
//@ revisions: old next
//@[next] compile-flags: -Znext-solver
//@[next] check-pass
// In the next solver, the opaque was previously defined by using the where-bound when checking
// whether the alias is `Sized`, constraining the opaque. Instead, the alias-bound is now used,
// which means the opaque is never constrained.
#![feature(type_alias_impl_trait)]
trait Trait<'a> {
@ -20,6 +23,7 @@ where
for<'a> <X as Trait<'a>>::Out<()>: Copy,
{
let x = *x; //[old]~ ERROR: cannot move out of `*x`
//[next]~^ ERROR: type annotations needed
todo!();
}

View file

@ -5,7 +5,7 @@ trait A {
type X: ?Sized;
}
fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) //~ ERROR
fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>)
where
for<'b> &'b T: A,
<&'static T as A>::X: Sized

View file

@ -1,18 +1,3 @@
error[E0308]: mismatched types
--> $DIR/issue-50716.rs:8:27
|
LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>)
| ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
= note: expected trait `<<&'a T as A>::X as MetaSized>`
found trait `<<&'static T as A>::X as MetaSized>`
note: the lifetime `'a` as defined here...
--> $DIR/issue-50716.rs:8:8
|
LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>)
| ^^
= note: ...does not necessarily outlive the static lifetime
error: lifetime may not live long enough
--> $DIR/issue-50716.rs:13:14
|
@ -22,6 +7,5 @@ LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>)
LL | let _x = *s;
| ^^ proving this value is `Sized` requires that `'a` must outlive `'static`
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`.

View file

@ -1,17 +0,0 @@
error[E0308]: mismatched types
--> $DIR/incomplete-inference-issue-143992.rs:27:28
|
LL | let _x = T::Assoc::new(());
| ------------- ^^ expected `[u32; 1]`, found `()`
| |
| arguments to this function are incorrect
|
note: associated function defined here
--> $DIR/incomplete-inference-issue-143992.rs:18:8
|
LL | fn new(r: R) -> R {
| ^^^ ----
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`.

View file

@ -1,17 +0,0 @@
error[E0308]: mismatched types
--> $DIR/incomplete-inference-issue-143992.rs:27:28
|
LL | let _x = T::Assoc::new(());
| ------------- ^^ expected `[u32; 1]`, found `()`
| |
| arguments to this function are incorrect
|
note: associated function defined here
--> $DIR/incomplete-inference-issue-143992.rs:18:8
|
LL | fn new(r: R) -> R {
| ^^^ ----
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`.

View file

@ -1,8 +1,7 @@
//@ check-pass
//@ compile-flags: --crate-type=lib
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[current] check-fail
//@[next] check-fail
//@[next] compile-flags: -Znext-solver
// Test that we avoid incomplete inference when normalizing. Without this,
@ -25,5 +24,4 @@ where
T::Assoc<[u32; 1]>: Clone,
{
let _x = T::Assoc::new(());
//~^ ERROR: mismatched types
}