Add derived causes for host effect predicates
This commit is contained in:
parent
243d2ca4db
commit
2be9ffc1af
15 changed files with 278 additions and 39 deletions
|
@ -125,6 +125,15 @@ impl<'tcx> ObligationCause<'tcx> {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn derived_host_cause(
|
||||
mut self,
|
||||
parent_host_pred: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>,
|
||||
variant: impl FnOnce(DerivedHostCause<'tcx>) -> ObligationCauseCode<'tcx>,
|
||||
) -> ObligationCause<'tcx> {
|
||||
self.code = variant(DerivedHostCause { parent_host_pred, parent_code: self.code }).into();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn to_constraint_category(&self) -> ConstraintCategory<'tcx> {
|
||||
match self.code() {
|
||||
ObligationCauseCode::MatchImpl(cause, _) => cause.to_constraint_category(),
|
||||
|
@ -278,6 +287,14 @@ pub enum ObligationCauseCode<'tcx> {
|
|||
/// Derived obligation for WF goals.
|
||||
WellFormedDerived(DerivedCause<'tcx>),
|
||||
|
||||
/// Derived obligation (i.e. `where` clause) on an user-provided impl
|
||||
/// or a trait alias.
|
||||
ImplDerivedHost(Box<ImplDerivedHostCause<'tcx>>),
|
||||
|
||||
/// Derived obligation (i.e. `where` clause) on an user-provided impl
|
||||
/// or a trait alias.
|
||||
BuiltinDerivedHost(DerivedHostCause<'tcx>),
|
||||
|
||||
/// Derived obligation refined to point at a specific argument in
|
||||
/// a call or method expression.
|
||||
FunctionArg {
|
||||
|
@ -437,36 +454,38 @@ pub enum WellFormedLoc {
|
|||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
|
||||
#[derive(TypeVisitable, TypeFoldable)]
|
||||
pub struct ImplDerivedCause<'tcx> {
|
||||
pub derived: DerivedCause<'tcx>,
|
||||
/// The `DefId` of the `impl` that gave rise to the `derived` obligation.
|
||||
/// If the `derived` obligation arose from a trait alias, which conceptually has a synthetic impl,
|
||||
/// then this will be the `DefId` of that trait alias. Care should therefore be taken to handle
|
||||
/// that exceptional case where appropriate.
|
||||
pub impl_or_alias_def_id: DefId,
|
||||
/// The index of the derived predicate in the parent impl's predicates.
|
||||
pub impl_def_predicate_index: Option<usize>,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl<'tcx> ObligationCauseCode<'tcx> {
|
||||
/// Returns the base obligation, ignoring derived obligations.
|
||||
pub fn peel_derives(&self) -> &Self {
|
||||
let mut base_cause = self;
|
||||
while let Some((parent_code, _)) = base_cause.parent() {
|
||||
while let Some(parent_code) = base_cause.parent() {
|
||||
base_cause = parent_code;
|
||||
}
|
||||
base_cause
|
||||
}
|
||||
|
||||
pub fn parent(&self) -> Option<&Self> {
|
||||
match self {
|
||||
ObligationCauseCode::FunctionArg { parent_code, .. } => Some(parent_code),
|
||||
ObligationCauseCode::BuiltinDerived(derived)
|
||||
| ObligationCauseCode::WellFormedDerived(derived)
|
||||
| ObligationCauseCode::ImplDerived(box ImplDerivedCause { derived, .. }) => {
|
||||
Some(&derived.parent_code)
|
||||
}
|
||||
ObligationCauseCode::BuiltinDerivedHost(derived)
|
||||
| ObligationCauseCode::ImplDerivedHost(box ImplDerivedHostCause { derived, .. }) => {
|
||||
Some(&derived.parent_code)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the base obligation and the base trait predicate, if any, ignoring
|
||||
/// derived obligations.
|
||||
pub fn peel_derives_with_predicate(&self) -> (&Self, Option<ty::PolyTraitPredicate<'tcx>>) {
|
||||
let mut base_cause = self;
|
||||
let mut base_trait_pred = None;
|
||||
while let Some((parent_code, parent_pred)) = base_cause.parent() {
|
||||
while let Some((parent_code, parent_pred)) = base_cause.parent_with_predicate() {
|
||||
base_cause = parent_code;
|
||||
if let Some(parent_pred) = parent_pred {
|
||||
base_trait_pred = Some(parent_pred);
|
||||
|
@ -476,7 +495,7 @@ impl<'tcx> ObligationCauseCode<'tcx> {
|
|||
(base_cause, base_trait_pred)
|
||||
}
|
||||
|
||||
pub fn parent(&self) -> Option<(&Self, Option<ty::PolyTraitPredicate<'tcx>>)> {
|
||||
pub fn parent_with_predicate(&self) -> Option<(&Self, Option<ty::PolyTraitPredicate<'tcx>>)> {
|
||||
match self {
|
||||
ObligationCauseCode::FunctionArg { parent_code, .. } => Some((parent_code, None)),
|
||||
ObligationCauseCode::BuiltinDerived(derived)
|
||||
|
@ -573,6 +592,42 @@ pub struct DerivedCause<'tcx> {
|
|||
pub parent_code: InternedObligationCauseCode<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
|
||||
#[derive(TypeVisitable, TypeFoldable)]
|
||||
pub struct ImplDerivedCause<'tcx> {
|
||||
pub derived: DerivedCause<'tcx>,
|
||||
/// The `DefId` of the `impl` that gave rise to the `derived` obligation.
|
||||
/// If the `derived` obligation arose from a trait alias, which conceptually has a synthetic impl,
|
||||
/// then this will be the `DefId` of that trait alias. Care should therefore be taken to handle
|
||||
/// that exceptional case where appropriate.
|
||||
pub impl_or_alias_def_id: DefId,
|
||||
/// The index of the derived predicate in the parent impl's predicates.
|
||||
pub impl_def_predicate_index: Option<usize>,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
|
||||
#[derive(TypeVisitable, TypeFoldable)]
|
||||
pub struct DerivedHostCause<'tcx> {
|
||||
/// The trait predicate of the parent obligation that led to the
|
||||
/// current obligation. Note that only trait obligations lead to
|
||||
/// derived obligations, so we just store the trait predicate here
|
||||
/// directly.
|
||||
pub parent_host_pred: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>,
|
||||
|
||||
/// The parent trait had this cause.
|
||||
pub parent_code: InternedObligationCauseCode<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
|
||||
#[derive(TypeVisitable, TypeFoldable)]
|
||||
pub struct ImplDerivedHostCause<'tcx> {
|
||||
pub derived: DerivedHostCause<'tcx>,
|
||||
/// The `DefId` of the `impl` that gave rise to the `derived` obligation.
|
||||
pub impl_def_id: DefId,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, TypeVisitable)]
|
||||
pub enum SelectionError<'tcx> {
|
||||
/// The trait is not implemented.
|
||||
|
|
|
@ -634,6 +634,28 @@ impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyProjectionPredicate<'tcx>> for Clause<'t
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>>
|
||||
for Predicate<'tcx>
|
||||
{
|
||||
fn upcast_from(
|
||||
from: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> Self {
|
||||
from.map_bound(ty::ClauseKind::HostEffect).upcast(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>>
|
||||
for Clause<'tcx>
|
||||
{
|
||||
fn upcast_from(
|
||||
from: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> Self {
|
||||
from.map_bound(ty::ClauseKind::HostEffect).upcast(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> UpcastFrom<TyCtxt<'tcx>, NormalizesTo<'tcx>> for Predicate<'tcx> {
|
||||
fn upcast_from(from: NormalizesTo<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
|
||||
PredicateKind::NormalizesTo(from).upcast(tcx)
|
||||
|
|
|
@ -353,7 +353,7 @@ where
|
|||
|
||||
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
|
||||
ecx.add_goals(
|
||||
GoalSource::Misc,
|
||||
GoalSource::ImplWhereBound,
|
||||
const_conditions.into_iter().map(|trait_ref| {
|
||||
goal.with(
|
||||
cx,
|
||||
|
|
|
@ -753,7 +753,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
applied_do_not_recommend = true;
|
||||
}
|
||||
}
|
||||
if let Some((parent_cause, _parent_pred)) = base_cause.parent() {
|
||||
if let Some(parent_cause) = base_cause.parent() {
|
||||
base_cause = parent_cause.clone();
|
||||
} else {
|
||||
break;
|
||||
|
@ -778,7 +778,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
trait_ref.skip_binder().args.type_at(1).to_opt_closure_kind()
|
||||
&& !found_kind.extends(expected_kind)
|
||||
{
|
||||
if let Some((_, Some(parent))) = obligation.cause.code().parent() {
|
||||
if let Some((_, Some(parent))) = obligation.cause.code().parent_with_predicate() {
|
||||
// If we have a derived obligation, then the parent will be a `AsyncFn*` goal.
|
||||
trait_ref = parent.to_poly_trait_ref();
|
||||
} else if let &ObligationCauseCode::FunctionArg { arg_hir_id, .. } =
|
||||
|
@ -926,7 +926,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
let Some(typeck) = &self.typeck_results else {
|
||||
return false;
|
||||
};
|
||||
let Some((ObligationCauseCode::QuestionMark, Some(y))) = obligation.cause.code().parent()
|
||||
let Some((ObligationCauseCode::QuestionMark, Some(y))) =
|
||||
obligation.cause.code().parent_with_predicate()
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
|
@ -1179,7 +1180,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
|
||||
let mut code = obligation.cause.code();
|
||||
let mut pred = obligation.predicate.as_trait_clause();
|
||||
while let Some((next_code, next_pred)) = code.parent() {
|
||||
while let Some((next_code, next_pred)) = code.parent_with_predicate() {
|
||||
if let Some(pred) = pred {
|
||||
self.enter_forall(pred, |pred| {
|
||||
diag.note(format!(
|
||||
|
@ -2095,7 +2096,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
let mut code = obligation.cause.code();
|
||||
let mut trait_pred = trait_predicate;
|
||||
let mut peeled = false;
|
||||
while let Some((parent_code, parent_trait_pred)) = code.parent() {
|
||||
while let Some((parent_code, parent_trait_pred)) = code.parent_with_predicate() {
|
||||
code = parent_code;
|
||||
if let Some(parent_trait_pred) = parent_trait_pred {
|
||||
trait_pred = parent_trait_pred;
|
||||
|
|
|
@ -464,7 +464,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
|
||||
// Get the root obligation, since the leaf obligation we have may be unhelpful (#87437)
|
||||
let mut real_trait_pred = trait_pred;
|
||||
while let Some((parent_code, parent_trait_pred)) = code.parent() {
|
||||
while let Some((parent_code, parent_trait_pred)) = code.parent_with_predicate() {
|
||||
code = parent_code;
|
||||
if let Some(parent_trait_pred) = parent_trait_pred {
|
||||
real_trait_pred = parent_trait_pred;
|
||||
|
@ -1447,7 +1447,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
let mut span = obligation.cause.span;
|
||||
let mut trait_pred = trait_pred;
|
||||
let mut code = obligation.cause.code();
|
||||
while let Some((c, Some(parent_trait_pred))) = code.parent() {
|
||||
while let Some((c, Some(parent_trait_pred))) = code.parent_with_predicate() {
|
||||
// We want the root obligation, in order to detect properly handle
|
||||
// `for _ in &mut &mut vec![] {}`.
|
||||
code = c;
|
||||
|
@ -3470,6 +3470,59 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
)
|
||||
});
|
||||
}
|
||||
ObligationCauseCode::ImplDerivedHost(ref data) => {
|
||||
let self_ty =
|
||||
self.resolve_vars_if_possible(data.derived.parent_host_pred.self_ty());
|
||||
let msg = format!(
|
||||
"required for `{self_ty}` to implement `{} {}`",
|
||||
data.derived.parent_host_pred.skip_binder().constness,
|
||||
data.derived
|
||||
.parent_host_pred
|
||||
.map_bound(|pred| pred.trait_ref)
|
||||
.print_only_trait_path(),
|
||||
);
|
||||
match tcx.hir().get_if_local(data.impl_def_id) {
|
||||
Some(Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
|
||||
..
|
||||
})) => {
|
||||
let mut spans = vec![self_ty.span];
|
||||
spans.extend(of_trait.as_ref().map(|t| t.path.span));
|
||||
let mut spans: MultiSpan = spans.into();
|
||||
spans.push_span_label(data.span, "unsatisfied trait bound introduced here");
|
||||
err.span_note(spans, msg);
|
||||
}
|
||||
_ => {
|
||||
err.note(msg);
|
||||
}
|
||||
}
|
||||
ensure_sufficient_stack(|| {
|
||||
self.note_obligation_cause_code(
|
||||
body_id,
|
||||
err,
|
||||
data.derived.parent_host_pred,
|
||||
param_env,
|
||||
&data.derived.parent_code,
|
||||
obligated_types,
|
||||
seen_requirements,
|
||||
long_ty_file,
|
||||
)
|
||||
});
|
||||
}
|
||||
ObligationCauseCode::BuiltinDerivedHost(ref data) => {
|
||||
ensure_sufficient_stack(|| {
|
||||
self.note_obligation_cause_code(
|
||||
body_id,
|
||||
err,
|
||||
data.parent_host_pred,
|
||||
param_env,
|
||||
&data.parent_code,
|
||||
obligated_types,
|
||||
seen_requirements,
|
||||
long_ty_file,
|
||||
)
|
||||
});
|
||||
}
|
||||
ObligationCauseCode::WellFormedDerived(ref data) => {
|
||||
let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred);
|
||||
let parent_predicate = parent_trait_ref;
|
||||
|
|
|
@ -474,8 +474,11 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
|
|||
// for normalizes-to.
|
||||
let pred_kind = goal.goal().predicate.kind();
|
||||
let child_mode = match pred_kind.skip_binder() {
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(parent_trait_pred)) => {
|
||||
ChildMode::Trait(pred_kind.rebind(parent_trait_pred))
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
|
||||
ChildMode::Trait(pred_kind.rebind(pred))
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(pred)) => {
|
||||
ChildMode::Host(pred_kind.rebind(pred))
|
||||
}
|
||||
ty::PredicateKind::NormalizesTo(normalizes_to)
|
||||
if matches!(
|
||||
|
@ -492,6 +495,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
|
|||
};
|
||||
|
||||
let mut impl_where_bound_count = 0;
|
||||
let mut impl_const_condition_bound_count = 0;
|
||||
for nested_goal in candidate.instantiate_nested_goals(self.span()) {
|
||||
trace!(nested_goal = ?(nested_goal.goal(), nested_goal.source(), nested_goal.result()));
|
||||
|
||||
|
@ -504,7 +508,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
|
|||
|
||||
let obligation;
|
||||
match (child_mode, nested_goal.source()) {
|
||||
(ChildMode::Trait(_), GoalSource::Misc) => {
|
||||
(ChildMode::Trait(_) | ChildMode::Host(_), GoalSource::Misc) => {
|
||||
continue;
|
||||
}
|
||||
(ChildMode::Trait(parent_trait_pred), GoalSource::ImplWhereBound) => {
|
||||
|
@ -517,6 +521,16 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
|
|||
));
|
||||
impl_where_bound_count += 1;
|
||||
}
|
||||
(ChildMode::Host(parent_host_pred), GoalSource::ImplWhereBound) => {
|
||||
obligation = make_obligation(derive_host_cause(
|
||||
tcx,
|
||||
candidate.kind(),
|
||||
self.obligation.cause.clone(),
|
||||
impl_const_condition_bound_count,
|
||||
parent_host_pred,
|
||||
));
|
||||
impl_const_condition_bound_count += 1;
|
||||
}
|
||||
// Skip over a higher-ranked predicate.
|
||||
(_, GoalSource::InstantiateHigherRanked) => {
|
||||
obligation = self.obligation.clone();
|
||||
|
@ -575,6 +589,10 @@ enum ChildMode<'tcx> {
|
|||
// and skip all `GoalSource::Misc`, which represent useless obligations
|
||||
// such as alias-eq which may not hold.
|
||||
Trait(ty::PolyTraitPredicate<'tcx>),
|
||||
// Try to derive an `ObligationCause::{ImplDerived,BuiltinDerived}`,
|
||||
// and skip all `GoalSource::Misc`, which represent useless obligations
|
||||
// such as alias-eq which may not hold.
|
||||
Host(ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>),
|
||||
// Skip trying to derive an `ObligationCause` from this obligation, and
|
||||
// report *all* sub-obligations as if they came directly from the parent
|
||||
// obligation.
|
||||
|
@ -616,3 +634,52 @@ fn derive_cause<'tcx>(
|
|||
};
|
||||
cause
|
||||
}
|
||||
|
||||
fn derive_host_cause<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
candidate_kind: inspect::ProbeKind<TyCtxt<'tcx>>,
|
||||
mut cause: ObligationCause<'tcx>,
|
||||
idx: usize,
|
||||
parent_host_pred: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>,
|
||||
) -> ObligationCause<'tcx> {
|
||||
match candidate_kind {
|
||||
inspect::ProbeKind::TraitCandidate {
|
||||
source: CandidateSource::Impl(impl_def_id),
|
||||
result: _,
|
||||
} => {
|
||||
if let Some((_, span)) = tcx
|
||||
.predicates_of(impl_def_id)
|
||||
.instantiate_identity(tcx)
|
||||
.into_iter()
|
||||
.chain(tcx.const_conditions(impl_def_id).instantiate_identity(tcx).into_iter().map(
|
||||
|(trait_ref, span)| {
|
||||
(
|
||||
trait_ref.to_host_effect_clause(
|
||||
tcx,
|
||||
parent_host_pred.skip_binder().constness,
|
||||
),
|
||||
span,
|
||||
)
|
||||
},
|
||||
))
|
||||
.nth(idx)
|
||||
{
|
||||
cause =
|
||||
cause.derived_host_cause(parent_host_pred, |derived| {
|
||||
ObligationCauseCode::ImplDerivedHost(Box::new(
|
||||
traits::ImplDerivedHostCause { derived, impl_def_id, span },
|
||||
))
|
||||
})
|
||||
}
|
||||
}
|
||||
inspect::ProbeKind::TraitCandidate {
|
||||
source: CandidateSource::BuiltinImpl(..),
|
||||
result: _,
|
||||
} => {
|
||||
cause =
|
||||
cause.derived_host_cause(parent_host_pred, ObligationCauseCode::BuiltinDerivedHost);
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
cause
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use rustc_hir as hir;
|
||||
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes};
|
||||
use rustc_infer::traits::{ImplSource, Obligation, PredicateObligation};
|
||||
use rustc_infer::traits::{
|
||||
ImplDerivedHostCause, ImplSource, Obligation, ObligationCauseCode, PredicateObligation,
|
||||
};
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
|
||||
use rustc_middle::ty::{self, TypingMode};
|
||||
|
@ -248,9 +250,22 @@ fn evaluate_host_effect_from_selection_candiate<'tcx>(
|
|||
tcx.const_conditions(impl_.impl_def_id)
|
||||
.instantiate(tcx, impl_.args)
|
||||
.into_iter()
|
||||
.map(|(trait_ref, _)| {
|
||||
obligation.with(
|
||||
.map(|(trait_ref, span)| {
|
||||
Obligation::new(
|
||||
tcx,
|
||||
obligation.cause.clone().derived_host_cause(
|
||||
ty::Binder::dummy(obligation.predicate),
|
||||
|derived| {
|
||||
ObligationCauseCode::ImplDerivedHost(Box::new(
|
||||
ImplDerivedHostCause {
|
||||
derived,
|
||||
impl_def_id: impl_.impl_def_id,
|
||||
span,
|
||||
},
|
||||
))
|
||||
},
|
||||
),
|
||||
obligation.param_env,
|
||||
trait_ref
|
||||
.to_host_effect_clause(tcx, obligation.predicate.constness),
|
||||
)
|
||||
|
|
|
@ -89,6 +89,7 @@ impl_binder_encode_decode! {
|
|||
ty::ExistentialPredicate<I>,
|
||||
ty::TraitRef<I>,
|
||||
ty::ExistentialTraitRef<I>,
|
||||
ty::HostEffectPredicate<I>,
|
||||
}
|
||||
|
||||
impl<I: Interner, T> Binder<I, T>
|
||||
|
|
|
@ -11,12 +11,30 @@ error[E0284]: type annotations needed: cannot normalize `<&T as ConstName>::{con
|
|||
|
|
||||
LL | impl<T: ?Sized + ConstName> const ConstName for &T
|
||||
| ^^ cannot normalize `<&T as ConstName>::{constant#0}`
|
||||
|
|
||||
note: required for `&T` to implement `~const ConstName`
|
||||
--> $DIR/issue-88119.rs:19:35
|
||||
|
|
||||
LL | impl<T: ?Sized + ConstName> const ConstName for &T
|
||||
| ^^^^^^^^^ ^^
|
||||
LL | where
|
||||
LL | [(); name_len::<T>()]:,
|
||||
| --------------------- unsatisfied trait bound introduced here
|
||||
|
||||
error[E0284]: type annotations needed: cannot normalize `<&mut T as ConstName>::{constant#0}`
|
||||
--> $DIR/issue-88119.rs:26:49
|
||||
|
|
||||
LL | impl<T: ?Sized + ConstName> const ConstName for &mut T
|
||||
| ^^^^^^ cannot normalize `<&mut T as ConstName>::{constant#0}`
|
||||
|
|
||||
note: required for `&mut T` to implement `~const ConstName`
|
||||
--> $DIR/issue-88119.rs:26:35
|
||||
|
|
||||
LL | impl<T: ?Sized + ConstName> const ConstName for &mut T
|
||||
| ^^^^^^^^^ ^^^^^^
|
||||
LL | where
|
||||
LL | [(); name_len::<T>()]:,
|
||||
| --------------------- unsatisfied trait bound introduced here
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ LL | T::Assoc::func();
|
|||
| ^^^^^^^^
|
||||
|
||||
error[E0277]: the trait bound `T: ~const Trait` is not satisfied
|
||||
--> $DIR/assoc-type-const-bound-usage-fail.rs:19:5
|
||||
--> $DIR/assoc-type-const-bound-usage-fail.rs:20:5
|
||||
|
|
||||
LL | <T as Trait>::Assoc::func();
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
error[E0277]: the trait bound `T: ~const Trait` is not satisfied
|
||||
error[E0277]: the trait bound `<T as Trait>::Assoc: ~const Trait` is not satisfied
|
||||
--> $DIR/assoc-type-const-bound-usage-fail.rs:17:5
|
||||
|
|
||||
LL | T::Assoc::func();
|
||||
| ^^^^^^^^
|
||||
|
||||
error[E0277]: the trait bound `T: ~const Trait` is not satisfied
|
||||
--> $DIR/assoc-type-const-bound-usage-fail.rs:19:5
|
||||
error[E0277]: the trait bound `<T as Trait>::Assoc: ~const Trait` is not satisfied
|
||||
--> $DIR/assoc-type-const-bound-usage-fail.rs:20:5
|
||||
|
|
||||
LL | <T as Trait>::Assoc::func();
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -15,9 +15,11 @@ trait Trait {
|
|||
|
||||
const fn unqualified<T: Trait>() {
|
||||
T::Assoc::func();
|
||||
//~^ ERROR the trait bound `T: ~const Trait` is not satisfied
|
||||
//[current]~^ ERROR the trait bound `T: ~const Trait` is not satisfied
|
||||
//[next]~^^ ERROR the trait bound `<T as Trait>::Assoc: ~const Trait` is not satisfied
|
||||
<T as Trait>::Assoc::func();
|
||||
//~^ ERROR the trait bound `T: ~const Trait` is not satisfied
|
||||
//[current]~^ ERROR the trait bound `T: ~const Trait` is not satisfied
|
||||
//[next]~^^ ERROR the trait bound `<T as Trait>::Assoc: ~const Trait` is not satisfied
|
||||
}
|
||||
|
||||
const fn works<T: ~const Trait>() {
|
||||
|
|
|
@ -12,7 +12,7 @@ note: required by a bound in `bar`
|
|||
LL | const fn bar<T: ~const Foo>(t: T) -> impl ~const Foo {
|
||||
| ^^^^^^ required by this bound in `bar`
|
||||
|
||||
error[E0277]: the trait bound `(): const Foo` is not satisfied
|
||||
error[E0277]: the trait bound `impl Foo: const Foo` is not satisfied
|
||||
--> $DIR/const-opaque.rs:33:12
|
||||
|
|
||||
LL | opaque.method();
|
||||
|
|
|
@ -31,7 +31,7 @@ const _: () = {
|
|||
let opaque = bar(());
|
||||
//[no]~^ ERROR the trait bound `(): const Foo` is not satisfied
|
||||
opaque.method();
|
||||
//[no]~^ ERROR the trait bound `(): const Foo` is not satisfied
|
||||
//[no]~^ ERROR the trait bound `impl Foo: const Foo` is not satisfied
|
||||
std::mem::forget(opaque);
|
||||
};
|
||||
|
||||
|
|
|
@ -16,6 +16,11 @@ error[E0277]: the trait bound `T: ~const Bar` is not satisfied
|
|||
LL | type Assoc<T> = C<T>
|
||||
| ^^^^
|
||||
|
|
||||
note: required for `C<T>` to implement `~const Bar`
|
||||
--> $DIR/item-bound-entailment-fails.rs:14:15
|
||||
|
|
||||
LL | impl<T> const Bar for C<T> where T: ~const Bar {}
|
||||
| ^^^ ^^^^ ------ unsatisfied trait bound introduced here
|
||||
note: required by a bound in `Foo::Assoc`
|
||||
--> $DIR/item-bound-entailment-fails.rs:5:20
|
||||
|
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue