diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 3c5c21a7a89c..de2b2e6c64f2 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -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 { 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? diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index ce4de6b95e0b..b6adc606b873 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -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}; diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index e790ecd595be..5edd281acefc 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -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>, failed_candidate_info: FailedCandidateInfo, ) -> Result<(CanonicalResponse, Option), 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, Option), 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, NoSolution>> { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index fb4f28412d42..5af16187e585 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -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>, ) -> Option> { 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) => {} diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 4b6349e2f426..023dbd38d911 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -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; fn as_trait_lang_item(self, def_id: Self::TraitId) -> Option; diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index 9d9a8e498478..f155d45bc0a6 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -109,6 +109,30 @@ pub struct QueryInput { impl Eq for QueryInput {} +/// 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(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 { diff --git a/tests/ui/async-await/higher-ranked-auto-trait-3.assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-3.assumptions.stderr new file mode 100644 index 000000000000..be978f19d7ee --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-3.assumptions.stderr @@ -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 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 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 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 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 IterCaller for UseIter + | ^^^^^^^^^^^^^^^^^ + | +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 for more information) + +error: lifetime bound not satisfied + --> $DIR/higher-ranked-auto-trait-3.rs:46:5 + | +LL | type Future1<'cx> = impl Future + 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 for more information) + +error: lifetime bound not satisfied + --> $DIR/higher-ranked-auto-trait-3.rs:50:5 + | +LL | type Future2<'cx> = impl Future + 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 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 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 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 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 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 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 for more information) + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 17 previous errors + diff --git a/tests/ui/async-await/higher-ranked-auto-trait-3.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-3.no_assumptions.stderr index c5c98ac807ea..1c5aa3af7d1e 100644 --- a/tests/ui/async-await/higher-ranked-auto-trait-3.no_assumptions.stderr +++ b/tests/ui/async-await/higher-ranked-auto-trait-3.no_assumptions.stderr @@ -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 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 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 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 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 IterCaller for UseIter + | ^^^^^^^^^^^^^^^^^ + | +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 for more information) + +error: lifetime bound not satisfied + --> $DIR/higher-ranked-auto-trait-3.rs:46:5 + | +LL | type Future1<'cx> = impl Future + 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 for more information) + +error: lifetime bound not satisfied + --> $DIR/higher-ranked-auto-trait-3.rs:50:5 + | +LL | type Future2<'cx> = impl Future + 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 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 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 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 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 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 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 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 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 for more information) -error: aborting due to 1 previous error +error: aborting due to 19 previous errors diff --git a/tests/ui/async-await/higher-ranked-auto-trait-3.rs b/tests/ui/async-await/higher-ranked-auto-trait-3.rs index d42d42366805..2ab986a097a6 100644 --- a/tests/ui/async-await/higher-ranked-auto-trait-3.rs +++ b/tests/ui/async-await/higher-ranked-auto-trait-3.rs @@ -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)] diff --git a/tests/ui/generic-associated-types/issue-93262.rs b/tests/ui/generic-associated-types/issue-93262.rs index c4a6f0dbaa07..c964606fef0b 100644 --- a/tests/ui/generic-associated-types/issue-93262.rs +++ b/tests/ui/generic-associated-types/issue-93262.rs @@ -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 Foo for Type +impl Foo for Type //~ ERROR: the parameter type `T` may not live long enough where for<'a> T::Assoc<'a>: Clone {} diff --git a/tests/ui/generic-associated-types/issue-93262.stderr b/tests/ui/generic-associated-types/issue-93262.stderr new file mode 100644 index 000000000000..91d3e65f3de8 --- /dev/null +++ b/tests/ui/generic-associated-types/issue-93262.stderr @@ -0,0 +1,19 @@ +error[E0311]: the parameter type `T` may not live long enough + --> $DIR/issue-93262.rs:14:16 + | +LL | impl Foo 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`. diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.next.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.next.stderr new file mode 100644 index 000000000000..723dd097f9b9 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.next.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed for `>::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`. diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr index 79ded34d9cd9..d8b94fd4f7d1 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr @@ -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 `>::Out`, which does not implement the `Copy` trait diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs index f881fcb779fa..55e99171ea63 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs @@ -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> >::Out<()>: Copy, { let x = *x; //[old]~ ERROR: cannot move out of `*x` + //[next]~^ ERROR: type annotations needed todo!(); } diff --git a/tests/ui/nll/issue-50716.rs b/tests/ui/nll/issue-50716.rs index 76c6fc5e7b92..96168ebeaa16 100644 --- a/tests/ui/nll/issue-50716.rs +++ b/tests/ui/nll/issue-50716.rs @@ -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 diff --git a/tests/ui/nll/issue-50716.stderr b/tests/ui/nll/issue-50716.stderr index edd7fd765dad..536f88085ded 100644 --- a/tests/ui/nll/issue-50716.stderr +++ b/tests/ui/nll/issue-50716.stderr @@ -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`. diff --git a/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.current.stderr b/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.current.stderr deleted file mode 100644 index cf56f42afc8a..000000000000 --- a/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.current.stderr +++ /dev/null @@ -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`. diff --git a/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.next.stderr b/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.next.stderr deleted file mode 100644 index cf56f42afc8a..000000000000 --- a/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.next.stderr +++ /dev/null @@ -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`. diff --git a/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.rs b/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.rs index a9c01a83bc37..44453b65e7cd 100644 --- a/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.rs +++ b/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.rs @@ -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 }