Auto merge of #144064 - davidtwco:prefer-alias-over-env-for-sizedness, r=lcnr

prefer alias candidates for sizedness + auto trait goals

Fixes rust-lang/rust#143992

- abd07dec44437554520453f929c2b12d4eb8b11e: Reverts rust-lang/rust#144016 so that `MetaSized` bounds are checked properly, and updates all the tests accordingly, including making `tests/ui/sized-hierarchy/incomplete-inference-issue-143992.rs` fail when it shouldn't
- 90e61db9745f53d9aef21e3ebce0df19cc1389d7: Prefer alias candidates over parameter environment candidates for sizedness, auto and default traits. `tests/ui/sized-hierarchy/incomplete-inference-issue-143992.rs` passes again, but `tests/ui/generic-associated-types/issue-93262.rs` starts failing when it shouldn't
- e412062171925d0b40fdbeb5765c45087bdf0fe7: No longer require that predicates of aliases hold in well-formedness checking of the alias. `tests/ui/generic-associated-types/issue-93262.rs` passes again

Each commit updates all the tests to their new output so it should be easy enough to see what the impact of each change individually is. After all of the changes, tests that pass when they didn't before or vice versa:

- `tests/ui/extern/extern-types-size_of_val.rs`
    - Previously passing, but only because of rust-lang/rust#144016, now correctly errors
- `tests/ui/sized-hierarchy/incomplete-inference-issue-143992.rs`
    - Previously failing on next solver, only because rust-lang/rust#144016 only applied to the old solver, passing now with 90e61db9745f53d9aef21e3ebce0df19cc1389d7
- `tests/ui/sized-hierarchy/overflow.rs`
    - Previously passing, but only because of rust-lang/rust#144016, now correctly errors
- `tests/ui/generic-associated-types/issue-92096.rs`
    - Previously passing, due to e412062171925d0b40fdbeb5765c45087bdf0fe7
    - Fails to prove `C::Connecting<'placeholder>: Send` which is required when proving that the generator is `Send`. This is an instance of rust-lang/rust#110338.
- `tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs`
    - Previously passing, now failing in the next solver, due to 03e0fdab6196e81b44356f42f03b6a0a224cf451
    - Expected that this test now fails as ambigious, see [Zulip](https://rust-lang.zulipchat.com/#narrow/channel/144729-t-types/topic/sizedness.20bounds.20in.20explicit_implied_predicates_of.20.28.23142712.29/near/526987384)

This had a crater run in https://github.com/rust-lang/rust/pull/142712#issuecomment-3050358772 alongside some other changes.

r? `@lcnr`
cc rust-lang/rust#142712 (this extracts part of that change)
This commit is contained in:
bors 2025-10-15 20:15:46 +00:00
commit 57ef8d642d
54 changed files with 558 additions and 304 deletions

View file

@ -6,6 +6,7 @@ use rustc_errors::ErrorGuaranteed;
use rustc_hir::def_id::DefId;
use rustc_macros::{HashStable, TypeVisitable};
use rustc_query_system::cache::Cache;
use rustc_type_ir::solve::AliasBoundKind;
use self::EvaluationResult::*;
use super::{SelectionError, SelectionResult};
@ -116,8 +117,13 @@ pub enum SelectionCandidate<'tcx> {
/// This is a trait matching with a projected type as `Self`, and we found
/// an applicable bound in the trait definition. The `usize` is an index
/// into the list returned by `tcx.item_bounds`.
ProjectionCandidate(usize),
/// into the list returned by `tcx.item_bounds` and the `AliasBoundKind`
/// is whether this is candidate from recursion on the self type of a
/// projection.
ProjectionCandidate {
idx: usize,
kind: AliasBoundKind,
},
/// Implementation of a `Fn`-family trait by one of the anonymous types
/// generated for an `||` expression.

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

@ -9,7 +9,7 @@ use derive_where::derive_where;
use rustc_type_ir::inherent::*;
use rustc_type_ir::lang_items::SolverTraitLangItem;
use rustc_type_ir::search_graph::CandidateHeadUsages;
use rustc_type_ir::solve::SizedTraitKind;
use rustc_type_ir::solve::{AliasBoundKind, SizedTraitKind};
use rustc_type_ir::{
self as ty, Interner, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable,
TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Upcast,
@ -27,11 +27,6 @@ use crate::solve::{
has_no_inference_or_external_constraints,
};
enum AliasBoundKind {
SelfBounds,
NonSelfBounds,
}
/// A candidate is a possible way to prove a goal.
///
/// It consists of both the `source`, which describes how that goal would be proven,
@ -451,7 +446,7 @@ where
matches!(
c.source,
CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)
| CandidateSource::AliasBound
| CandidateSource::AliasBound(_)
) && has_no_inference_or_external_constraints(c.result)
})
{
@ -711,7 +706,7 @@ where
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
{
candidates.push(Candidate {
source: CandidateSource::AliasBound,
source: CandidateSource::AliasBound(consider_self_bounds),
result,
head_usages: CandidateHeadUsages::default(),
});
@ -735,7 +730,7 @@ where
{
candidates.extend(G::probe_and_consider_implied_clause(
self,
CandidateSource::AliasBound,
CandidateSource::AliasBound(consider_self_bounds),
goal,
assumption,
[],
@ -750,7 +745,7 @@ where
{
candidates.extend(G::probe_and_consider_implied_clause(
self,
CandidateSource::AliasBound,
CandidateSource::AliasBound(consider_self_bounds),
goal,
assumption,
[],
@ -1030,7 +1025,7 @@ where
item_bound.fold_with(&mut ReplaceOpaque { cx: self.cx(), alias_ty, self_ty });
candidates.extend(G::probe_and_match_goal_against_assumption(
self,
CandidateSource::AliasBound,
CandidateSource::AliasBound(AliasBoundKind::SelfBounds),
goal,
assumption,
|ecx| {

View file

@ -4,8 +4,8 @@
use rustc_type_ir::fast_reject::DeepRejectCtxt;
use rustc_type_ir::inherent::*;
use rustc_type_ir::lang_items::SolverTraitLangItem;
use rustc_type_ir::solve::SizedTraitKind;
use rustc_type_ir::solve::inspect::ProbeKind;
use rustc_type_ir::solve::{AliasBoundKind, SizedTraitKind};
use rustc_type_ir::{self as ty, Interner, TypingMode, elaborate};
use tracing::instrument;
@ -96,7 +96,7 @@ where
) {
candidates.extend(Self::probe_and_match_goal_against_assumption(
ecx,
CandidateSource::AliasBound,
CandidateSource::AliasBound(AliasBoundKind::SelfBounds),
goal,
clause,
|ecx| {

View file

@ -4,7 +4,9 @@ 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::{
AliasBoundKind, CandidatePreferenceMode, CanonicalResponse, SizedTraitKind,
};
use rustc_type_ir::{
self as ty, Interner, Movability, PredicatePolarity, TraitPredicate, TraitRef,
TypeVisitableExt as _, TypingMode, Upcast as _, elaborate,
@ -1355,6 +1357,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 +1383,23 @@ where
return Ok((candidate.result, Some(TraitGoalProvenVia::Misc)));
}
// Extract non-nested alias bound candidates, will be preferred over where bounds if
// we're proving an auto-trait, sizedness trait or default trait.
if matches!(candidate_preference_mode, CandidatePreferenceMode::Marker)
&& candidates.iter().any(|c| {
matches!(c.source, CandidateSource::AliasBound(AliasBoundKind::SelfBounds))
})
{
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 there are non-global where-bounds, prefer where-bounds
// (including global ones) over everything else.
let has_non_global_where_bounds = candidates
@ -1427,9 +1447,10 @@ where
};
}
if candidates.iter().any(|c| matches!(c.source, CandidateSource::AliasBound)) {
// Next, prefer any alias bound (nested or otherwise).
if candidates.iter().any(|c| matches!(c.source, CandidateSource::AliasBound(_))) {
let alias_bounds: Vec<_> = candidates
.extract_if(.., |c| matches!(c.source, CandidateSource::AliasBound))
.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)))
@ -1470,7 +1491,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

@ -126,7 +126,9 @@ fn candidate_should_be_dropped_in_favor_of<'tcx>(
// Prefer dyn candidates over non-dyn candidates. This is necessary to
// handle the unsoundness between `impl<T: ?Sized> Any for T` and `dyn Any: Any`.
(
CandidateSource::Impl(_) | CandidateSource::ParamEnv(_) | CandidateSource::AliasBound,
CandidateSource::Impl(_)
| CandidateSource::ParamEnv(_)
| CandidateSource::AliasBound(_),
CandidateSource::BuiltinImpl(BuiltinImplSource::Object { .. }),
) => true,
@ -175,7 +177,9 @@ fn to_selection<'tcx>(
})
}
CandidateSource::BuiltinImpl(builtin) => ImplSource::Builtin(builtin, nested),
CandidateSource::ParamEnv(_) | CandidateSource::AliasBound => ImplSource::Param(nested),
CandidateSource::ParamEnv(_) | CandidateSource::AliasBound(_) => {
ImplSource::Param(nested)
}
CandidateSource::CoherenceUnknowable => {
span_bug!(span, "didn't expect to select an unknowable candidate")
}

View file

@ -741,7 +741,7 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
let mut ambiguous = false;
let _ = selcx.for_each_item_bound(
obligation.predicate.self_ty(),
|selcx, clause, _| {
|selcx, clause, _, _| {
let Some(clause) = clause.as_projection_clause() else {
return ControlFlow::Continue(());
};

View file

@ -208,7 +208,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let mut distinct_normalized_bounds = FxHashSet::default();
let _ = self.for_each_item_bound::<!>(
placeholder_trait_predicate.self_ty(),
|selcx, bound, idx| {
|selcx, bound, idx, alias_bound_kind| {
let Some(bound) = bound.as_trait_clause() else {
return ControlFlow::Continue(());
};
@ -230,12 +230,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
bound.map_bound(|pred| pred.trait_ref),
) {
Ok(None) => {
candidates.vec.push(ProjectionCandidate(idx));
candidates
.vec
.push(ProjectionCandidate { idx, kind: alias_bound_kind });
}
Ok(Some(normalized_trait))
if distinct_normalized_bounds.insert(normalized_trait) =>
{
candidates.vec.push(ProjectionCandidate(idx));
candidates
.vec
.push(ProjectionCandidate { idx, kind: alias_bound_kind });
}
_ => {}
}
@ -825,7 +829,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
ty::Alias(ty::Opaque, alias) => {
if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(_))) {
if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate { .. })) {
// We do not generate an auto impl candidate for `impl Trait`s which already
// reference our auto trait.
//

View file

@ -67,7 +67,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ImplSource::Builtin(BuiltinImplSource::Misc, data)
}
ProjectionCandidate(idx) => {
ProjectionCandidate { idx, .. } => {
let obligations = self.confirm_projection_candidate(obligation, idx)?;
ImplSource::Param(obligations)
}
@ -144,15 +144,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligation: &PolyTraitObligation<'tcx>,
idx: usize,
) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
let tcx = self.tcx();
let placeholder_trait_predicate =
self.infcx.enter_forall_and_leak_universe(obligation.predicate).trait_ref;
let placeholder_self_ty = self.infcx.shallow_resolve(placeholder_trait_predicate.self_ty());
let candidate_predicate = self
.for_each_item_bound(
placeholder_self_ty,
|_, clause, clause_idx| {
|_, clause, clause_idx, _| {
if clause_idx == idx {
ControlFlow::Break(clause)
} else {
@ -194,28 +192,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.map_err(|_| SelectionError::Unimplemented)?,
);
// FIXME(compiler-errors): I don't think this is needed.
if let ty::Alias(ty::Projection, alias_ty) = placeholder_self_ty.kind() {
let predicates = tcx.predicates_of(alias_ty.def_id).instantiate_own(tcx, alias_ty.args);
for (predicate, _) in predicates {
let normalized = normalize_with_depth_to(
self,
obligation.param_env,
obligation.cause.clone(),
obligation.recursion_depth + 1,
predicate,
&mut obligations,
);
obligations.push(Obligation::with_depth(
self.tcx(),
obligation.cause.clone(),
obligation.recursion_depth + 1,
obligation.param_env,
normalized,
));
}
}
Ok(obligations)
}

View file

@ -28,9 +28,11 @@ 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_next_trait_solver::solve::AliasBoundKind;
use rustc_span::{Symbol, sym};
use tracing::{debug, instrument, trace};
@ -474,7 +476,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)
@ -1623,11 +1629,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
pub(super) fn for_each_item_bound<T>(
&mut self,
mut self_ty: Ty<'tcx>,
mut for_each: impl FnMut(&mut Self, ty::Clause<'tcx>, usize) -> ControlFlow<T, ()>,
mut for_each: impl FnMut(
&mut Self,
ty::Clause<'tcx>,
usize,
AliasBoundKind,
) -> ControlFlow<T, ()>,
on_ambiguity: impl FnOnce(),
) -> ControlFlow<T, ()> {
let mut idx = 0;
let mut in_parent_alias_type = false;
let mut alias_bound_kind = AliasBoundKind::SelfBounds;
loop {
let (kind, alias_ty) = match *self_ty.kind() {
@ -1643,14 +1654,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// share the same type as `self_ty`. This is because for truly rigid
// projections, we will never be able to equate, e.g. `<T as Tr>::A`
// with `<<T as Tr>::A as Tr>::A`.
let relevant_bounds = if in_parent_alias_type {
let relevant_bounds = if matches!(alias_bound_kind, AliasBoundKind::NonSelfBounds) {
self.tcx().item_non_self_bounds(alias_ty.def_id)
} else {
self.tcx().item_self_bounds(alias_ty.def_id)
};
for bound in relevant_bounds.instantiate(self.tcx(), alias_ty.args) {
for_each(self, bound, idx)?;
for_each(self, bound, idx, alias_bound_kind)?;
idx += 1;
}
@ -1660,7 +1671,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
return ControlFlow::Continue(());
}
in_parent_alias_type = true;
alias_bound_kind = AliasBoundKind::NonSelfBounds;
}
}
@ -1821,6 +1832,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 +1886,29 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
break;
}
let mut alias_bounds = candidates.iter().filter_map(|c| {
if let ProjectionCandidate { idx, kind } = c.candidate {
Some((idx, kind))
} else {
None
}
});
// Extract non-nested alias bound candidates, will be preferred over where bounds if
// we're proving an auto-trait, sizedness trait or default trait.
if matches!(candidate_preference_mode, CandidatePreferenceMode::Marker) {
match alias_bounds
.clone()
.filter_map(|(idx, kind)| (kind == AliasBoundKind::SelfBounds).then_some(idx))
.try_reduce(|c1, c2| if has_non_region_infer { None } else { Some(c1.min(c2)) })
{
Some(Some(idx)) => {
return Some(ProjectionCandidate { idx, kind: AliasBoundKind::SelfBounds });
}
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,12 +1942,16 @@ 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)),
match alias_bounds.try_reduce(|(c1, k1), (c2, k2)| {
if has_non_region_infer {
None
} else if c1 < c2 {
Some((c1, k1))
} else {
Some((c2, k2))
}
}) {
Some(Some((idx, kind))) => return Some(ProjectionCandidate { idx, kind }),
Some(None) => {}
None => return None,
}
@ -2001,7 +2040,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
// Non-global param candidates have already been handled, global
// where-bounds get ignored.
ParamCandidate(_) | ImplCandidate(_) => true,
ProjectionCandidate(_) | ObjectCandidate(_) => unreachable!(),
ProjectionCandidate { .. } | ObjectCandidate(_) => unreachable!(),
}) {
return Some(ImplCandidate(def_id));
} else {

View file

@ -383,13 +383,6 @@ pub fn sizedness_fast_path<'tcx>(
_ => return false,
};
// FIXME(sized_hierarchy): this temporarily reverts the `sized_hierarchy` feature
// while a proper fix for `tests/ui/sized-hierarchy/incomplete-inference-issue-143992.rs`
// is pending a proper fix
if !tcx.features().sized_hierarchy() && matches!(sizedness, SizedTraitKind::MetaSized) {
return true;
}
if trait_pred.self_ty().has_trivial_sizedness(tcx, sizedness) {
debug!("fast path -- trivial sizedness");
return true;

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> {
@ -165,7 +189,7 @@ pub enum CandidateSource<I: Interner> {
/// let _y = x.clone();
/// }
/// ```
AliasBound,
AliasBound(AliasBoundKind),
/// A candidate that is registered only during coherence to represent some
/// yet-unknown impl that could be produced downstream without violating orphan
/// rules.
@ -183,6 +207,15 @@ pub enum ParamEnvSource {
Global,
}
#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
pub enum AliasBoundKind {
/// Alias bound from the self type of a projection
SelfBounds,
// Alias bound having recursed on the self type of a projection
NonSelfBounds,
}
#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
#[cfg_attr(
feature = "nightly",

View file

@ -1057,7 +1057,7 @@ marker_impls! {
#[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)]
#[rustc_deny_explicit_impl]
#[rustc_do_not_implement_via_object]
pub const trait Destruct {}
pub const trait Destruct: PointeeSized {}
/// A marker for tuple types.
///

View file

@ -1,33 +0,0 @@
error: implementation of `FnOnce` is not general enough
--> $DIR/higher-ranked-auto-trait-14.rs:20:5
|
LL | / async move {
LL | | let xs = unique_x.union(&cached)
LL | | // .copied() // works
LL | | .map(|x| *x) // error
LL | | ;
LL | | let blah = val.blah(xs.into_iter()).await;
LL | | }
| |_____^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'0 u32) -> u32` must implement `FnOnce<(&'1 u32,)>`, for any two lifetimes `'0` and `'1`...
= note: ...but it actually implements `FnOnce<(&u32,)>`
error: implementation of `FnOnce` is not general enough
--> $DIR/higher-ranked-auto-trait-14.rs:20:5
|
LL | / async move {
LL | | let xs = unique_x.union(&cached)
LL | | // .copied() // works
LL | | .map(|x| *x) // error
LL | | ;
LL | | let blah = val.blah(xs.into_iter()).await;
LL | | }
| |_____^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'0 u32) -> u32` must implement `FnOnce<(&'1 u32,)>`, for any two lifetimes `'0` and `'1`...
= note: ...but it actually implements `FnOnce<(&u32,)>`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 2 previous errors

View file

@ -1,9 +1,8 @@
// Repro for <https://github.com/rust-lang/rust/issues/124757#issue-2279603232>.
//@ check-pass
//@ edition: 2021
//@ revisions: assumptions no_assumptions
//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
//@[assumptions] check-pass
//@[no_assumptions] known-bug: #110338
use std::collections::HashSet;
use std::future::Future;

View file

@ -1,49 +0,0 @@
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-2.rs:16:9
|
LL | / async move {
LL | | // asks for an unspecified lifetime to outlive itself? weird diagnostics
LL | | self.run(t).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: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-2.rs:16:9
|
LL | / async move {
LL | | // asks for an unspecified lifetime to outlive itself? weird diagnostics
LL | | self.run(t).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)
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-2.rs:16:9
|
LL | / async move {
LL | | // asks for an unspecified lifetime to outlive itself? weird diagnostics
LL | | self.run(t).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)
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-2.rs:16:9
|
LL | / async move {
LL | | // asks for an unspecified lifetime to outlive itself? weird diagnostics
LL | | self.run(t).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)
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 4 previous errors

View file

@ -1,9 +1,8 @@
// Repro for <https://github.com/rust-lang/rust/issues/111105#issue-1692860759>.
//@ check-pass
//@ edition: 2021
//@ revisions: assumptions no_assumptions
//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
//@[assumptions] check-pass
//@[no_assumptions] known-bug: #110338
use std::future::Future;

View file

@ -1,12 +0,0 @@
error: lifetime bound not satisfied
--> $DIR/higher-ranked-auto-trait-3.rs:66:9
|
LL | / async {
LL | | self.fi_2.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: aborting due to 1 previous error

View file

@ -1,9 +1,8 @@
// Repro for <https://github.com/rust-lang/rust/issues/100013#issue-1323807923>.
//@ check-pass
//@ edition: 2021
//@ revisions: assumptions no_assumptions
//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
//@[assumptions] check-pass
//@[no_assumptions] known-bug: #110338
#![feature(impl_trait_in_assoc_type)]

View file

@ -1,8 +0,0 @@
error: `S` does not live long enough
--> $DIR/higher-ranked-auto-trait-7.rs:26:5
|
LL | future::<'a, S, _>(async move {
| ^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error

View file

@ -1,9 +1,8 @@
// Repro for <https://github.com/rust-lang/rust/issues/90696#issuecomment-963375847>.
//@ check-pass
//@ edition: 2021
//@ revisions: assumptions no_assumptions
//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
//@[assumptions] check-pass
//@[no_assumptions] known-bug: #110338
#![allow(dropping_copy_types)]

View file

@ -8,8 +8,8 @@ extern "C" {
}
const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) };
//~^ ERROR `extern type` does not have known layout
//~^ ERROR: the size for values of type `Opaque` cannot be known
const _ALIGN: usize = unsafe { align_of_val(&4 as *const i32 as *const Opaque) };
//~^ ERROR `extern type` does not have known layout
//~^ ERROR: the size for values of type `Opaque` cannot be known
fn main() {}

View file

@ -1,15 +1,39 @@
error[E0080]: `extern type` does not have known layout
--> $DIR/const-size_of_val-align_of_val-extern-type.rs:10:31
error[E0277]: the size for values of type `Opaque` cannot be known
--> $DIR/const-size_of_val-align_of_val-extern-type.rs:10:43
|
LL | const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_SIZE` failed here
| ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MetaSized` is not implemented for `Opaque`
| |
| required by a bound introduced by this call
|
= note: the trait bound `Opaque: MetaSized` is not satisfied
note: required by a bound in `std::intrinsics::size_of_val`
--> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
help: consider borrowing here
|
LL | const _SIZE: usize = unsafe { size_of_val(&(&4 as *const i32 as *const Opaque)) };
| ++ +
LL | const _SIZE: usize = unsafe { size_of_val(&mut (&4 as *const i32 as *const Opaque)) };
| ++++++ +
error[E0080]: `extern type` does not have known layout
--> $DIR/const-size_of_val-align_of_val-extern-type.rs:12:32
error[E0277]: the size for values of type `Opaque` cannot be known
--> $DIR/const-size_of_val-align_of_val-extern-type.rs:12:45
|
LL | const _ALIGN: usize = unsafe { align_of_val(&4 as *const i32 as *const Opaque) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_ALIGN` failed here
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MetaSized` is not implemented for `Opaque`
| |
| required by a bound introduced by this call
|
= note: the trait bound `Opaque: MetaSized` is not satisfied
note: required by a bound in `std::intrinsics::align_of_val`
--> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
help: consider borrowing here
|
LL | const _ALIGN: usize = unsafe { align_of_val(&(&4 as *const i32 as *const Opaque)) };
| ++ +
LL | const _ALIGN: usize = unsafe { align_of_val(&mut (&4 as *const i32 as *const Opaque)) };
| ++++++ +
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0080`.
For more information about this error, try `rustc --explain E0277`.

View file

@ -9,7 +9,8 @@ trait Bop {
fn bop<T: Bop + ?Sized>() {
let _ = <T as Bop>::Bar::default();
//~^ ERROR: trait bounds were not satisfied
//~^ ERROR: the size for values of type `T` cannot be known at compilation time
//~| ERROR: the size for values of type `T` cannot be known at compilation time
//~| ERROR: the size for values of type `T` cannot be known at compilation time
}

View file

@ -24,21 +24,58 @@ help: consider relaxing the implicit `Sized` restriction
LL | type Bar: Default + ?Sized
| ++++++++
error[E0599]: the function or associated item `default` exists for associated type `<T as Bop>::Bar`, but its trait bounds were not satisfied
--> $DIR/assoc_type_bounds_sized_used.rs:11:30
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> $DIR/assoc_type_bounds_sized_used.rs:11:13
|
LL | fn bop<T: Bop + ?Sized>() {
| - this type parameter needs to be `Sized`
LL | let _ = <T as Bop>::Bar::default();
| ^^^^^^^ function or associated item cannot be called on `<T as Bop>::Bar` due to unsatisfied trait bounds
| ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= note: the following trait bounds were not satisfied:
`T: Sized`
which is required by `<T as Bop>::Bar: Default`
help: consider restricting the type parameter to satisfy the trait bound
note: required by a bound in `Bop::Bar`
--> $DIR/assoc_type_bounds_sized_used.rs:7:15
|
LL | fn bop<T: Bop + ?Sized>() where T: Sized {
| ++++++++++++++
LL | type Bar: Default
| --- required by a bound in this associated type
LL | where
LL | Self: Sized;
| ^^^^^ required by this bound in `Bop::Bar`
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
LL - fn bop<T: Bop + ?Sized>() {
LL + fn bop<T: Bop>() {
|
help: consider relaxing the implicit `Sized` restriction
|
LL | type Bar: Default + ?Sized
| ++++++++
error: aborting due to 2 previous errors
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> $DIR/assoc_type_bounds_sized_used.rs:11:13
|
LL | fn bop<T: Bop + ?Sized>() {
| - this type parameter needs to be `Sized`
LL | let _ = <T as Bop>::Bar::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
note: required by a bound in `Bop::Bar`
--> $DIR/assoc_type_bounds_sized_used.rs:7:15
|
LL | type Bar: Default
| --- required by a bound in this associated type
LL | where
LL | Self: Sized;
| ^^^^^ required by this bound in `Bop::Bar`
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
LL - fn bop<T: Bop + ?Sized>() {
LL + fn bop<T: Bop>() {
|
help: consider relaxing the implicit `Sized` restriction
|
LL | type Bar: Default + ?Sized
| ++++++++
Some errors have detailed explanations: E0277, E0599.
For more information about an error, try `rustc --explain E0277`.
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`.

View file

@ -1,8 +1,9 @@
//@ check-pass
#![feature(extern_types)]
use std::mem::{align_of_val, size_of_val};
// Check that calls to `size_of_val` and `align_of_val` with extern types are not accepted
extern "C" {
type A;
}
@ -11,5 +12,7 @@ fn main() {
let x: &A = unsafe { &*(1usize as *const A) };
size_of_val(x);
//~^ ERROR: the size for values of type `A` cannot be known
align_of_val(x);
//~^ ERROR: the size for values of type `A` cannot be known
}

View file

@ -0,0 +1,39 @@
error[E0277]: the size for values of type `A` cannot be known
--> $DIR/extern-types-size_of_val.rs:14:17
|
LL | size_of_val(x);
| ----------- ^ the trait `MetaSized` is not implemented for `A`
| |
| required by a bound introduced by this call
|
= note: the trait bound `A: MetaSized` is not satisfied
note: required by a bound in `std::mem::size_of_val`
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
help: consider borrowing here
|
LL | size_of_val(&x);
| +
LL | size_of_val(&mut x);
| ++++
error[E0277]: the size for values of type `A` cannot be known
--> $DIR/extern-types-size_of_val.rs:16:18
|
LL | align_of_val(x);
| ------------ ^ the trait `MetaSized` is not implemented for `A`
| |
| required by a bound introduced by this call
|
= note: the trait bound `A: MetaSized` is not satisfied
note: required by a bound in `std::mem::align_of_val`
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
help: consider borrowing here
|
LL | align_of_val(&x);
| +
LL | align_of_val(&mut x);
| ++++
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View file

@ -27,7 +27,9 @@ fn main() {
assert_sized::<Bar<A>>();
//~^ ERROR the size for values of type
//~| ERROR the size for values of type `A` cannot be known
assert_sized::<Bar<Bar<A>>>();
//~^ ERROR the size for values of type
//~| ERROR the size for values of type `A` cannot be known
}

View file

@ -59,8 +59,21 @@ help: consider relaxing the implicit `Sized` restriction
LL | fn assert_sized<T: ?Sized>() {}
| ++++++++
error[E0277]: the size for values of type `A` cannot be known
--> $DIR/extern-types-unsized.rs:28:20
|
LL | assert_sized::<Bar<A>>();
| ^^^^^^ doesn't have a known size
|
= help: the trait `MetaSized` is not implemented for `A`
note: required by a bound in `Bar`
--> $DIR/extern-types-unsized.rs:14:12
|
LL | struct Bar<T: ?Sized> {
| ^ required by this bound in `Bar`
error[E0277]: the size for values of type `A` cannot be known at compilation time
--> $DIR/extern-types-unsized.rs:31:20
--> $DIR/extern-types-unsized.rs:32:20
|
LL | assert_sized::<Bar<Bar<A>>>();
| ^^^^^^^^^^^ doesn't have a size known at compile-time
@ -81,6 +94,19 @@ help: consider relaxing the implicit `Sized` restriction
LL | fn assert_sized<T: ?Sized>() {}
| ++++++++
error: aborting due to 4 previous errors
error[E0277]: the size for values of type `A` cannot be known
--> $DIR/extern-types-unsized.rs:32:20
|
LL | assert_sized::<Bar<Bar<A>>>();
| ^^^^^^^^^^^ doesn't have a known size
|
= help: the trait `MetaSized` is not implemented for `A`
note: required by a bound in `Bar`
--> $DIR/extern-types-unsized.rs:14:12
|
LL | struct Bar<T: ?Sized> {
| ^ required by this bound in `Bar`
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0277`.

View file

@ -7,10 +7,14 @@ extern "C" {
}
unsafe fn make_device() -> Box<Device> {
//~^ ERROR the size for values of type `Device` cannot be known
Box::from_raw(0 as *mut _)
//~^ ERROR the size for values of type `Device` cannot be known
//~| ERROR the size for values of type `Device` cannot be known
}
fn main() {
let d: Device = unsafe { *make_device() };
//~^ ERROR the size for values of type `Device` cannot be known
//~| ERROR the size for values of type `Device` cannot be known
}

View file

@ -1,5 +1,43 @@
error[E0277]: the size for values of type `Device` cannot be known
--> $DIR/unsized-extern-derefmove.rs:9:28
|
LL | unsafe fn make_device() -> Box<Device> {
| ^^^^^^^^^^^ doesn't have a known size
|
= help: the trait `MetaSized` is not implemented for `Device`
note: required by a bound in `Box`
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
error[E0277]: the size for values of type `Device` cannot be known
--> $DIR/unsized-extern-derefmove.rs:11:19
|
LL | Box::from_raw(0 as *mut _)
| ------------- ^^^^^^^^^^^ the trait `MetaSized` is not implemented for `Device`
| |
| required by a bound introduced by this call
|
= note: the trait bound `Device: MetaSized` is not satisfied
note: required by a bound in `Box::<T>::from_raw`
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
help: consider borrowing here
|
LL | Box::from_raw(&(0 as *mut _))
| ++ +
LL | Box::from_raw(&mut (0 as *mut _))
| ++++++ +
error[E0277]: the size for values of type `Device` cannot be known
--> $DIR/unsized-extern-derefmove.rs:11:5
|
LL | Box::from_raw(0 as *mut _)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size
|
= help: the trait `MetaSized` is not implemented for `Device`
note: required by a bound in `Box`
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
error[E0277]: the size for values of type `Device` cannot be known at compilation time
--> $DIR/unsized-extern-derefmove.rs:14:9
--> $DIR/unsized-extern-derefmove.rs:17:9
|
LL | let d: Device = unsafe { *make_device() };
| ^ doesn't have a size known at compile-time
@ -11,6 +49,16 @@ help: consider borrowing here
LL | let d: &Device = unsafe { *make_device() };
| +
error: aborting due to 1 previous error
error[E0277]: the size for values of type `Device` cannot be known
--> $DIR/unsized-extern-derefmove.rs:17:31
|
LL | let d: Device = unsafe { *make_device() };
| ^^^^^^^^^^^^^ doesn't have a known size
|
= help: the trait `MetaSized` is not implemented for `Device`
note: required by a bound in `Box`
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0277`.

View file

@ -1,24 +0,0 @@
error: lifetime bound not satisfied
--> $DIR/higher-ranked-coroutine-param-outlives-2.rs:14:5
|
LL | / async { // a coroutine checked for autotrait impl `Send`
LL | | let x = None::<I::Future<'_, '_>>; // a type referencing GAT
LL | | async {}.await; // a yield point
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: lifetime bound not satisfied
--> $DIR/higher-ranked-coroutine-param-outlives-2.rs:21:5
|
LL | / async { // a coroutine checked for autotrait impl `Send`
LL | | let x = None::<I::Future<'a, 'b>>; // a type referencing GAT
LL | | async {}.await; // a yield point
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 2 previous errors

View file

@ -1,8 +1,7 @@
//@ check-pass
//@ edition: 2021
//@ revisions: assumptions no_assumptions
//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
//@[assumptions] check-pass
//@[no_assumptions] known-bug: #110338
pub trait FutureIterator {
type Future<'s, 'cx>: Send

View file

@ -1,8 +0,0 @@
error: `C` does not live long enough
--> $DIR/higher-ranked-coroutine-param-outlives.rs:21:5
|
LL | async move { c.connect().await }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error

View file

@ -1,8 +1,7 @@
//@ check-pass
//@ edition:2018
//@ revisions: assumptions no_assumptions
//@[assumptions] compile-flags: -Zhigher-ranked-assumptions
//@[assumptions] check-pass
//@[no_assumptions] known-bug: #110338
use std::future::Future;

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

@ -17,3 +17,4 @@ impl<C: ?Sized> A for u8 { //~ ERROR: the type parameter `C` is not constrained
#[rustc_layout(debug)]
struct S([u8; <u8 as A>::B]);
//~^ ERROR: the type has an unknown layout
//~| ERROR: type annotations needed

View file

@ -4,12 +4,19 @@ error[E0207]: the type parameter `C` is not constrained by the impl trait, self
LL | impl<C: ?Sized> A for u8 {
| ^ unconstrained type parameter
error[E0282]: type annotations needed
--> $DIR/unconstrained-param-ice-137308.rs:18:16
|
LL | struct S([u8; <u8 as A>::B]);
| ^^ cannot infer type for type parameter `C`
error: the type has an unknown layout
--> $DIR/unconstrained-param-ice-137308.rs:18:1
|
LL | struct S([u8; <u8 as A>::B]);
| ^^^^^^^^
error: aborting due to 2 previous errors
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0207`.
Some errors have detailed explanations: E0207, E0282.
For more information about an error, try `rustc --explain E0207`.

View file

@ -0,0 +1,21 @@
//@ check-pass
//@ compile-flags: --crate-type=lib
//@ revisions: old next
//@[next] compile-flags: -Znext-solver
use std::marker::PhantomData;
pub trait ZeroMapKV<'a> {
type Container;
}
pub trait ZeroFrom<'zf, C: ?Sized> {}
pub struct ZeroMap<'a, K: ZeroMapKV<'a>>(PhantomData<&'a K>);
impl<'zf, 's, K> ZeroFrom<'zf, ZeroMap<'s, K>> for ZeroMap<'zf, K>
where
K: for<'b> ZeroMapKV<'b>,
<K as ZeroMapKV<'zf>>::Container: ZeroFrom<'zf, <K as ZeroMapKV<'s>>::Container>,
{
}

View file

@ -1,17 +0,0 @@
error[E0308]: mismatched types
--> $DIR/incomplete-inference-issue-143992.rs:30: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:21: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:30: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:21: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,12 +1,8 @@
//@ check-pass
//@ compile-flags: --crate-type=lib
//@ revisions: current next current_sized_hierarchy next_sized_hierarchy
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[current] check-pass
//@[next] check-pass
//@[next] compile-flags: -Znext-solver
//@[next_sized_hierarchy] compile-flags: -Znext-solver
#![cfg_attr(any(current_sized_hierarchy, next_sized_hierarchy), feature(sized_hierarchy))]
// Test that we avoid incomplete inference when normalizing. Without this,
// `Trait`'s implicit `MetaSized` supertrait requires proving `T::Assoc<_>: MetaSized`
@ -28,6 +24,4 @@ where
T::Assoc<[u32; 1]>: Clone,
{
let _x = T::Assoc::new(());
//[next_sized_hierarchy]~^ ERROR mismatched types
//[current_sized_hierarchy]~^^ ERROR mismatched types
}

View file

@ -0,0 +1,45 @@
error[E0275]: overflow evaluating the requirement `Element: MetaSized`
--> $DIR/overflow.rs:17:16
|
LL | struct Element(<Box<Box<Element>> as ParseTokens>::Output);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: required for `Box<Element>` to implement `ParseTokens`
--> $DIR/overflow.rs:13:31
|
LL | impl<T: ParseTokens + ?Sized> ParseTokens for Box<T> {
| - ^^^^^^^^^^^ ^^^^^^
| |
| unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= note: required for `Box<Box<Element>>` to implement `ParseTokens`
error[E0275]: overflow evaluating the requirement `Box<Element>: ParseTokens`
--> $DIR/overflow.rs:19:22
|
LL | impl ParseTokens for Element {
| ^^^^^^^
|
note: required for `Box<Box<Element>>` to implement `ParseTokens`
--> $DIR/overflow.rs:13:31
|
LL | impl<T: ParseTokens + ?Sized> ParseTokens for Box<T> {
| ----------- ^^^^^^^^^^^ ^^^^^^
| |
| unsatisfied trait bound introduced here
note: required because it appears within the type `Element`
--> $DIR/overflow.rs:17:8
|
LL | struct Element(<Box<Box<Element>> as ParseTokens>::Output);
| ^^^^^^^
note: required by a bound in `ParseTokens`
--> $DIR/overflow.rs:10:1
|
LL | / trait ParseTokens {
LL | | type Output;
LL | | }
| |_^ required by this bound in `ParseTokens`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0275`.

View file

@ -1,13 +1,10 @@
//@ compile-flags: --crate-type=lib
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[current] check-pass
//@[current] check-fail
//@[next] check-pass
//@[next] compile-flags: -Znext-solver
// FIXME(sized_hierarchy): this is expected to fail in the old solver when there
// isn't a temporary revert of the `sized_hierarchy` feature
use std::marker::PhantomData;
trait ParseTokens {
@ -18,6 +15,8 @@ impl<T: ParseTokens + ?Sized> ParseTokens for Box<T> {
}
struct Element(<Box<Box<Element>> as ParseTokens>::Output);
//[current]~^ ERROR: overflow
impl ParseTokens for Element {
//[current]~^ ERROR: overflow
type Output = ();
}

View file

@ -0,0 +1,30 @@
//@ check-pass
//@ compile-flags: --crate-type=lib
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
// Since #120752, also get alias-bound candidates from a nested self-type, so prefering
// alias-bound over where-bound candidates can be incorrect. This test checks that case and that
// we prefer non-nested alias-bound candidates over where-bound candidates over nested alias-bound
// candidates.
trait OtherTrait<'a> {
type Assoc: ?Sized;
}
trait Trait
where
<Self::Assoc as OtherTrait<'static>>::Assoc: Sized,
{
type Assoc: for<'a> OtherTrait<'a>;
}
fn impls_sized<T: Sized>() {}
fn foo<'a, T>()
where
T: Trait,
for<'hr> <T::Assoc as OtherTrait<'hr>>::Assoc: Sized,
{
impls_sized::<<T::Assoc as OtherTrait<'a>>::Assoc>();
}

View file

@ -17,6 +17,13 @@ LL | impl<T: Bound, U> Trait<U> for T {
| ----- ^^^^^^^^ ^
| |
| unsatisfied trait bound introduced here
note: required by a bound in `Bound`
--> $DIR/normalizes-to-is-not-productive.rs:8:1
|
LL | / trait Bound {
LL | | fn method();
LL | | }
| |_^ required by this bound in `Bound`
error[E0277]: the trait bound `Foo: Bound` is not satisfied
--> $DIR/normalizes-to-is-not-productive.rs:47:19

View file

@ -19,6 +19,23 @@ error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: A<T>`
LL | Self::Assoc: A<T>,
| ^^^^
error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: MetaSized`
--> $DIR/normalize-param-env-2.rs:24:22
|
LL | Self::Assoc: A<T>,
| ^^^^
|
note: required by a bound in `A`
--> $DIR/normalize-param-env-2.rs:9:1
|
LL | / trait A<T> {
LL | | type Assoc;
LL | |
LL | | fn f()
... |
LL | | }
| |_^ required by this bound in `A`
error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc well-formed`
--> $DIR/normalize-param-env-2.rs:24:22
|
@ -46,6 +63,6 @@ LL | where
LL | Self::Assoc: A<T>,
| ^^^^ required by this bound in `A::f`
error: aborting due to 5 previous errors
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0275`.

View file

@ -4,6 +4,20 @@ error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc: Trait`
LL | <T as Trait>::Assoc: Trait,
| ^^^^^
error: aborting due to 1 previous error
error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc: MetaSized`
--> $DIR/normalize-param-env-4.rs:19:26
|
LL | <T as Trait>::Assoc: Trait,
| ^^^^^
|
note: required by a bound in `Trait`
--> $DIR/normalize-param-env-4.rs:7:1
|
LL | / trait Trait {
LL | | type Assoc;
LL | | }
| |_^ required by this bound in `Trait`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0275`.

View file

@ -15,6 +15,7 @@ use foo::*;
fn test() -> impl Sized {
<() as Callable>::call()
//~^ ERROR type annotations needed
}
fn main() {}

View file

@ -4,6 +4,13 @@ error[E0207]: the type parameter `V` is not constrained by the impl trait, self
LL | impl<V: ?Sized> Callable for () {
| ^ unconstrained type parameter
error: aborting due to 1 previous error
error[E0282]: type annotations needed
--> $DIR/resolve-impl-before-constrain-check.rs:17:6
|
LL | <() as Callable>::call()
| ^^ cannot infer type for type parameter `V`
For more information about this error, try `rustc --explain E0207`.
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0207, E0282.
For more information about an error, try `rustc --explain E0207`.