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:
commit
57ef8d642d
54 changed files with 558 additions and 304 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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| {
|
||||
|
|
|
|||
|
|
@ -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| {
|
||||
|
|
|
|||
|
|
@ -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>> {
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(());
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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)]
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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)]
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
5
tests/ui/extern/extern-types-size_of_val.rs
vendored
5
tests/ui/extern/extern-types-size_of_val.rs
vendored
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
39
tests/ui/extern/extern-types-size_of_val.stderr
vendored
Normal file
39
tests/ui/extern/extern-types-size_of_val.stderr
vendored
Normal 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`.
|
||||
2
tests/ui/extern/extern-types-unsized.rs
vendored
2
tests/ui/extern/extern-types-unsized.rs
vendored
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
30
tests/ui/extern/extern-types-unsized.stderr
vendored
30
tests/ui/extern/extern-types-unsized.stderr
vendored
|
|
@ -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`.
|
||||
|
|
|
|||
4
tests/ui/extern/unsized-extern-derefmove.rs
vendored
4
tests/ui/extern/unsized-extern-derefmove.rs
vendored
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
52
tests/ui/extern/unsized-extern-derefmove.stderr
vendored
52
tests/ui/extern/unsized-extern-derefmove.stderr
vendored
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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!();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
21
tests/ui/sized-hierarchy/bound-on-assoc-type-projection-1.rs
Normal file
21
tests/ui/sized-hierarchy/bound-on-assoc-type-projection-1.rs
Normal 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>,
|
||||
{
|
||||
}
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
45
tests/ui/sized-hierarchy/overflow.current.stderr
Normal file
45
tests/ui/sized-hierarchy/overflow.current.stderr
Normal 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`.
|
||||
|
|
@ -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 = ();
|
||||
}
|
||||
|
|
|
|||
30
tests/ui/sized-hierarchy/prefer-non-nested-alias-bound.rs
Normal file
30
tests/ui/sized-hierarchy/prefer-non-nested-alias-bound.rs
Normal 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>();
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ use foo::*;
|
|||
|
||||
fn test() -> impl Sized {
|
||||
<() as Callable>::call()
|
||||
//~^ ERROR type annotations needed
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue