Manually walk into WF obligations in BestObligation proof tree visitor
This commit is contained in:
parent
d8b176f683
commit
304b3cfcb2
18 changed files with 164 additions and 104 deletions
|
@ -1,7 +1,7 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::def_id::{CRATE_DEF_ID, DefId};
|
||||
use rustc_infer::infer::canonical::query_response::make_query_region_constraints;
|
||||
use rustc_infer::infer::canonical::{
|
||||
Canonical, CanonicalExt as _, CanonicalQueryInput, CanonicalVarInfo, CanonicalVarValues,
|
||||
|
@ -98,9 +98,10 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
|
|||
param_env: ty::ParamEnv<'tcx>,
|
||||
arg: ty::GenericArg<'tcx>,
|
||||
) -> Option<Vec<Goal<'tcx, ty::Predicate<'tcx>>>> {
|
||||
crate::traits::wf::unnormalized_obligations(&self.0, param_env, arg).map(|obligations| {
|
||||
obligations.into_iter().map(|obligation| obligation.into()).collect()
|
||||
})
|
||||
crate::traits::wf::unnormalized_obligations(&self.0, param_env, arg, DUMMY_SP, CRATE_DEF_ID)
|
||||
.map(|obligations| {
|
||||
obligations.into_iter().map(|obligation| obligation.into()).collect()
|
||||
})
|
||||
}
|
||||
|
||||
fn clone_opaque_types_for_query_response(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
|
||||
|
|
|
@ -10,13 +10,13 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
|||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_next_trait_solver::solve::{GenerateProofTree, SolverDelegateEvalExt as _};
|
||||
use rustc_type_ir::solve::NoSolution;
|
||||
use rustc_type_ir::solve::{Goal, NoSolution};
|
||||
use tracing::{instrument, trace};
|
||||
|
||||
use crate::solve::Certainty;
|
||||
use crate::solve::delegate::SolverDelegate;
|
||||
use crate::solve::inspect::{self, ProofTreeInferCtxtExt, ProofTreeVisitor};
|
||||
use crate::traits::{FulfillmentError, FulfillmentErrorCode};
|
||||
use crate::traits::{FulfillmentError, FulfillmentErrorCode, wf};
|
||||
|
||||
pub(super) fn fulfillment_error_for_no_solution<'tcx>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
|
@ -207,14 +207,10 @@ impl<'tcx> BestObligation<'tcx> {
|
|||
| GoalSource::AliasBoundConstCondition
|
||||
| GoalSource::InstantiateHigherRanked
|
||||
| GoalSource::AliasWellFormed
|
||||
) && match self.consider_ambiguities {
|
||||
true => {
|
||||
matches!(
|
||||
nested_goal.result(),
|
||||
Ok(Certainty::Maybe(MaybeCause::Ambiguity))
|
||||
)
|
||||
}
|
||||
false => matches!(nested_goal.result(), Err(_)),
|
||||
) && match (self.consider_ambiguities, nested_goal.result()) {
|
||||
(true, Ok(Certainty::Maybe(MaybeCause::Ambiguity)))
|
||||
| (false, Err(_)) => true,
|
||||
_ => false,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -233,6 +229,39 @@ impl<'tcx> BestObligation<'tcx> {
|
|||
|
||||
candidates
|
||||
}
|
||||
|
||||
/// HACK: We walk the nested obligations for a well-formed arg manually,
|
||||
/// since there's nontrivial logic in `wf.rs` to set up an obligation cause.
|
||||
/// Ideally we'd be able to track this better.
|
||||
fn visit_well_formed_goal(
|
||||
&mut self,
|
||||
candidate: &inspect::InspectCandidate<'_, 'tcx>,
|
||||
arg: ty::GenericArg<'tcx>,
|
||||
) -> ControlFlow<PredicateObligation<'tcx>> {
|
||||
let infcx = candidate.goal().infcx();
|
||||
let param_env = candidate.goal().goal().param_env;
|
||||
let body_id = self.obligation.cause.body_id;
|
||||
|
||||
for obligation in wf::unnormalized_obligations(infcx, param_env, arg, self.span(), body_id)
|
||||
.into_iter()
|
||||
.flatten()
|
||||
{
|
||||
let nested_goal = candidate.instantiate_proof_tree_for_nested_goal(
|
||||
GoalSource::Misc,
|
||||
Goal::new(infcx.tcx, obligation.param_env, obligation.predicate),
|
||||
self.span(),
|
||||
);
|
||||
// Skip nested goals that aren't the *reason* for our goal's failure.
|
||||
match (self.consider_ambiguities, nested_goal.result()) {
|
||||
(true, Ok(Certainty::Maybe(MaybeCause::Ambiguity))) | (false, Err(_)) => {}
|
||||
_ => continue,
|
||||
}
|
||||
|
||||
self.with_derived_obligation(obligation, |this| nested_goal.visit_with(this))?;
|
||||
}
|
||||
|
||||
ControlFlow::Break(self.obligation.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
|
||||
|
@ -283,6 +312,9 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
|
|||
polarity: ty::PredicatePolarity::Positive,
|
||||
}))
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
|
||||
return self.visit_well_formed_goal(candidate, arg);
|
||||
}
|
||||
_ => ChildMode::PassThrough,
|
||||
};
|
||||
|
||||
|
@ -355,12 +387,8 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
|
|||
}
|
||||
|
||||
// Skip nested goals that aren't the *reason* for our goal's failure.
|
||||
match self.consider_ambiguities {
|
||||
true if matches!(
|
||||
nested_goal.result(),
|
||||
Ok(Certainty::Maybe(MaybeCause::Ambiguity))
|
||||
) => {}
|
||||
false if matches!(nested_goal.result(), Err(_)) => {}
|
||||
match (self.consider_ambiguities, nested_goal.result()) {
|
||||
(true, Ok(Certainty::Maybe(MaybeCause::Ambiguity))) | (false, Err(_)) => {}
|
||||
_ => continue,
|
||||
}
|
||||
|
||||
|
|
|
@ -194,47 +194,57 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
|
|||
|
||||
let goals = instantiated_goals
|
||||
.into_iter()
|
||||
.map(|(source, goal)| match goal.predicate.kind().no_bound_vars() {
|
||||
Some(ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })) => {
|
||||
let unconstrained_term = match term.unpack() {
|
||||
ty::TermKind::Ty(_) => infcx.next_ty_var(span).into(),
|
||||
ty::TermKind::Const(_) => infcx.next_const_var(span).into(),
|
||||
};
|
||||
let goal =
|
||||
goal.with(infcx.tcx, ty::NormalizesTo { alias, term: unconstrained_term });
|
||||
// We have to use a `probe` here as evaluating a `NormalizesTo` can constrain the
|
||||
// expected term. This means that candidates which only fail due to nested goals
|
||||
// and which normalize to a different term then the final result could ICE: when
|
||||
// building their proof tree, the expected term was unconstrained, but when
|
||||
// instantiating the candidate it is already constrained to the result of another
|
||||
// candidate.
|
||||
let proof_tree = infcx
|
||||
.probe(|_| infcx.evaluate_root_goal_raw(goal, GenerateProofTree::Yes).1);
|
||||
InspectGoal::new(
|
||||
infcx,
|
||||
self.goal.depth + 1,
|
||||
proof_tree.unwrap(),
|
||||
Some(NormalizesToTermHack { term, unconstrained_term }),
|
||||
source,
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
// We're using a probe here as evaluating a goal could constrain
|
||||
// inference variables by choosing one candidate. If we then recurse
|
||||
// into another candidate who ends up with different inference
|
||||
// constraints, we get an ICE if we already applied the constraints
|
||||
// from the chosen candidate.
|
||||
let proof_tree = infcx
|
||||
.probe(|_| infcx.evaluate_root_goal(goal, GenerateProofTree::Yes).1)
|
||||
.unwrap();
|
||||
InspectGoal::new(infcx, self.goal.depth + 1, proof_tree, None, source)
|
||||
}
|
||||
})
|
||||
.map(|(source, goal)| self.instantiate_proof_tree_for_nested_goal(source, goal, span))
|
||||
.collect();
|
||||
|
||||
(goals, opt_impl_args)
|
||||
}
|
||||
|
||||
pub fn instantiate_proof_tree_for_nested_goal(
|
||||
&self,
|
||||
source: GoalSource,
|
||||
goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
||||
span: Span,
|
||||
) -> InspectGoal<'a, 'tcx> {
|
||||
let infcx = self.goal.infcx;
|
||||
match goal.predicate.kind().no_bound_vars() {
|
||||
Some(ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })) => {
|
||||
let unconstrained_term = match term.unpack() {
|
||||
ty::TermKind::Ty(_) => infcx.next_ty_var(span).into(),
|
||||
ty::TermKind::Const(_) => infcx.next_const_var(span).into(),
|
||||
};
|
||||
let goal =
|
||||
goal.with(infcx.tcx, ty::NormalizesTo { alias, term: unconstrained_term });
|
||||
// We have to use a `probe` here as evaluating a `NormalizesTo` can constrain the
|
||||
// expected term. This means that candidates which only fail due to nested goals
|
||||
// and which normalize to a different term then the final result could ICE: when
|
||||
// building their proof tree, the expected term was unconstrained, but when
|
||||
// instantiating the candidate it is already constrained to the result of another
|
||||
// candidate.
|
||||
let proof_tree =
|
||||
infcx.probe(|_| infcx.evaluate_root_goal_raw(goal, GenerateProofTree::Yes).1);
|
||||
InspectGoal::new(
|
||||
infcx,
|
||||
self.goal.depth + 1,
|
||||
proof_tree.unwrap(),
|
||||
Some(NormalizesToTermHack { term, unconstrained_term }),
|
||||
source,
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
// We're using a probe here as evaluating a goal could constrain
|
||||
// inference variables by choosing one candidate. If we then recurse
|
||||
// into another candidate who ends up with different inference
|
||||
// constraints, we get an ICE if we already applied the constraints
|
||||
// from the chosen candidate.
|
||||
let proof_tree = infcx
|
||||
.probe(|_| infcx.evaluate_root_goal(goal, GenerateProofTree::Yes).1)
|
||||
.unwrap();
|
||||
InspectGoal::new(infcx, self.goal.depth + 1, proof_tree, None, source)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Visit all nested goals of this candidate, rolling back
|
||||
/// all inference constraints.
|
||||
pub fn visit_nested_in_probe<V: ProofTreeVisitor<'tcx>>(&self, visitor: &mut V) -> V::Result {
|
||||
|
|
|
@ -5,8 +5,8 @@ use rustc_infer::traits::query::type_op::ImpliedOutlivesBounds;
|
|||
use rustc_middle::infer::canonical::CanonicalQueryResponse;
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFolder, TypeVisitableExt};
|
||||
use rustc_span::Span;
|
||||
use rustc_span::def_id::CRATE_DEF_ID;
|
||||
use rustc_span::{DUMMY_SP, Span};
|
||||
use rustc_type_ir::outlives::{Component, push_outlives_components};
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
use tracing::debug;
|
||||
|
@ -92,7 +92,9 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
|
|||
|
||||
// From the full set of obligations, just filter down to the region relationships.
|
||||
for obligation in
|
||||
wf::unnormalized_obligations(ocx.infcx, param_env, arg).into_iter().flatten()
|
||||
wf::unnormalized_obligations(ocx.infcx, param_env, arg, DUMMY_SP, CRATE_DEF_ID)
|
||||
.into_iter()
|
||||
.flatten()
|
||||
{
|
||||
assert!(!obligation.has_escaping_bound_vars());
|
||||
let Some(pred) = obligation.predicate.kind().no_bound_vars() else {
|
||||
|
|
|
@ -8,8 +8,8 @@ use rustc_middle::ty::{
|
|||
self, GenericArg, GenericArgKind, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable,
|
||||
TypeVisitable, TypeVisitableExt, TypeVisitor,
|
||||
};
|
||||
use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
|
||||
use rustc_span::{DUMMY_SP, Span};
|
||||
use rustc_span::Span;
|
||||
use rustc_span::def_id::{DefId, LocalDefId};
|
||||
use tracing::{debug, instrument, trace};
|
||||
|
||||
use crate::infer::InferCtxt;
|
||||
|
@ -89,6 +89,8 @@ pub fn unnormalized_obligations<'tcx>(
|
|||
infcx: &InferCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
arg: GenericArg<'tcx>,
|
||||
span: Span,
|
||||
body_id: LocalDefId,
|
||||
) -> Option<PredicateObligations<'tcx>> {
|
||||
debug_assert_eq!(arg, infcx.resolve_vars_if_possible(arg));
|
||||
|
||||
|
@ -106,8 +108,8 @@ pub fn unnormalized_obligations<'tcx>(
|
|||
let mut wf = WfPredicates {
|
||||
infcx,
|
||||
param_env,
|
||||
body_id: CRATE_DEF_ID,
|
||||
span: DUMMY_SP,
|
||||
body_id,
|
||||
span,
|
||||
out: PredicateObligations::new(),
|
||||
recursion_depth: 0,
|
||||
item: None,
|
||||
|
|
|
@ -5,6 +5,8 @@ LL | fn main() -> Foo::Bar::<Vec<[u32]>> {}
|
|||
| ^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[u32]`
|
||||
note: required by an implicit `Sized` bound in `Vec`
|
||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
@ -6,35 +6,29 @@ LL | #![feature(const_trait_impl, generic_const_exprs)]
|
|||
|
|
||||
= help: remove one of these features
|
||||
|
||||
error[E0284]: type annotations needed: cannot normalize `<&T as ConstName>::{constant#0}`
|
||||
--> $DIR/issue-88119.rs:19:49
|
||||
error[E0284]: type annotations needed: cannot satisfy `the constant `name_len::<T>()` can be evaluated`
|
||||
--> $DIR/issue-88119.rs:21:5
|
||||
|
|
||||
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
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `the constant `name_len::<T>()` can be evaluated`
|
||||
|
|
||||
note: required by a bound in `<&T as ConstName>`
|
||||
--> $DIR/issue-88119.rs:21:10
|
||||
|
|
||||
LL | [(); name_len::<T>()]:,
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `<&T as ConstName>`
|
||||
|
||||
error[E0284]: type annotations needed: cannot normalize `<&mut T as ConstName>::{constant#0}`
|
||||
--> $DIR/issue-88119.rs:26:49
|
||||
error[E0284]: type annotations needed: cannot satisfy `the constant `name_len::<T>()` can be evaluated`
|
||||
--> $DIR/issue-88119.rs:28:5
|
||||
|
|
||||
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
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `the constant `name_len::<T>()` can be evaluated`
|
||||
|
|
||||
note: required by a bound in `<&mut T as ConstName>`
|
||||
--> $DIR/issue-88119.rs:28:10
|
||||
|
|
||||
LL | [(); name_len::<T>()]:,
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `<&mut T as ConstName>`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
@ -16,23 +16,13 @@ LL | where
|
|||
LL | T: AsExpression<Self::SqlType>,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::check`
|
||||
|
||||
error[E0277]: the trait bound `&str: AsExpression<Integer>` is not satisfied
|
||||
--> $DIR/as_expression.rs:55:15
|
||||
|
|
||||
LL | SelectInt.check("bar");
|
||||
| ^^^^^ the trait `AsExpression<Integer>` is not implemented for `&str`
|
||||
|
|
||||
= help: the trait `AsExpression<Integer>` is not implemented for `&str`
|
||||
but trait `AsExpression<Text>` is implemented for it
|
||||
= help: for that trait implementation, expected `Text`, found `Integer`
|
||||
|
||||
error[E0271]: type mismatch resolving `<SelectInt as Expression>::SqlType == Text`
|
||||
--> $DIR/as_expression.rs:55:5
|
||||
|
|
||||
LL | SelectInt.check("bar");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ expected `Text`, found `Integer`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0271, E0277.
|
||||
For more information about an error, try `rustc --explain E0271`.
|
||||
|
|
|
@ -53,7 +53,7 @@ impl<T> Foo for T where T: Expression {}
|
|||
|
||||
fn main() {
|
||||
SelectInt.check("bar");
|
||||
//~^ ERROR the trait bound `&str: AsExpression<Integer>` is not satisfied
|
||||
//[next]~| the trait bound `&str: AsExpression<<SelectInt as Expression>::SqlType>` is not satisfied
|
||||
//[current]~^ ERROR the trait bound `&str: AsExpression<Integer>` is not satisfied
|
||||
//[next]~^^ the trait bound `&str: AsExpression<<SelectInt as Expression>::SqlType>` is not satisfied
|
||||
//[next]~| type mismatch
|
||||
}
|
||||
|
|
|
@ -18,6 +18,11 @@ help: this trait has no implementations, consider adding one
|
|||
|
|
||||
LL | trait Foo {}
|
||||
| ^^^^^^^^^
|
||||
note: required by a bound in `A`
|
||||
--> $DIR/alias-bounds-when-not-wf.rs:8:11
|
||||
|
|
||||
LL | type A<T: Foo> = T;
|
||||
| ^^^ required by this bound in `A`
|
||||
|
||||
error[E0277]: the trait bound `usize: Foo` is not satisfied
|
||||
--> $DIR/alias-bounds-when-not-wf.rs:16:10
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error[E0284]: type annotations needed: cannot normalize `X::{constant#0}`
|
||||
error[E0284]: type annotations needed: cannot satisfy `the constant `{ || {} }` can be evaluated`
|
||||
--> $DIR/const-region-infer-to-static-in-binder.rs:4:10
|
||||
|
|
||||
LL | struct X<const FN: fn() = { || {} }>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `X::{constant#0}`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `the constant `{ || {} }` can be evaluated`
|
||||
|
||||
error: using function pointers as const generic parameters is forbidden
|
||||
--> $DIR/const-region-infer-to-static-in-binder.rs:4:20
|
||||
|
|
|
@ -10,11 +10,11 @@ LL | #![feature(specialization)]
|
|||
|
||||
error: cannot normalize `<T as Default>::Id: '_`
|
||||
|
||||
error[E0284]: type annotations needed: cannot normalize `<T as Default>::Id`
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/specialization-transmute.rs:15:23
|
||||
|
|
||||
LL | fn intu(&self) -> &Self::Id {
|
||||
| ^^^^^^^^^ cannot normalize `<T as Default>::Id`
|
||||
| ^^^^^^^^^ cannot infer type for reference `&<T as Default>::Id`
|
||||
|
||||
error[E0284]: type annotations needed: cannot satisfy `<T as Default>::Id normalizes-to T`
|
||||
--> $DIR/specialization-transmute.rs:17:9
|
||||
|
@ -36,4 +36,5 @@ LL | fn transmute<T: Default<Id = U>, U: Copy>(t: T) -> U {
|
|||
|
||||
error: aborting due to 4 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0284`.
|
||||
Some errors have detailed explanations: E0282, E0284.
|
||||
For more information about an error, try `rustc --explain E0282`.
|
||||
|
|
|
@ -9,6 +9,8 @@ error: the constant `N` is not of type `usize`
|
|||
|
|
||||
LL | fn func<const N: u32>() -> [(); N];
|
||||
| ^^^^^^^ expected `usize`, found `u32`
|
||||
|
|
||||
= note: the length of array `[(); N]` must be type `usize`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ LL | union U2 {
|
|||
LL | a: PartialEqNotEq,
|
||||
| ^^^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `PartialEqNotEq`
|
||||
|
|
||||
note: required by a bound in `AssertParamIsEq`
|
||||
--> $SRC_DIR/core/src/cmp.rs:LL:COL
|
||||
= note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider annotating `PartialEqNotEq` with `#[derive(Eq)]`
|
||||
|
|
||||
|
|
|
@ -5,6 +5,7 @@ LL | const _: <[[[[[[u8]]]]]] as WellUnformed>::RequestNormalize = ();
|
|||
| ^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[[[[[u8]]]]]`
|
||||
= note: slice and array elements must have `Sized` type
|
||||
|
||||
error[E0277]: the size for values of type `[[[[[u8]]]]]` cannot be known at compilation time
|
||||
--> $DIR/wf-normalization-sized.rs:19:11
|
||||
|
@ -13,6 +14,7 @@ LL | const _: <[[[[[[u8]]]]]] as WellUnformed>::RequestNormalize = ();
|
|||
| ^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[[[[[u8]]]]]`
|
||||
= note: slice and array elements must have `Sized` type
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||
|
@ -22,6 +24,8 @@ LL | const _: <Vec<str> as WellUnformed>::RequestNormalize = ();
|
|||
| ^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `str`
|
||||
note: required by an implicit `Sized` bound in `Vec`
|
||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||
|
||||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||
--> $DIR/wf-normalization-sized.rs:22:11
|
||||
|
@ -30,6 +34,8 @@ LL | const _: <Vec<str> as WellUnformed>::RequestNormalize = ();
|
|||
| ^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `str`
|
||||
note: required by an implicit `Sized` bound in `Vec`
|
||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
|
|
@ -4,6 +4,11 @@ error[E0277]: the trait bound `Self: Eq` is not satisfied
|
|||
LL | fn bar(&self, x: &Bar<Self>);
|
||||
| ^^^^^^^^^ the trait `Eq` is not implemented for `Self`
|
||||
|
|
||||
note: required by a bound in `Bar`
|
||||
--> $DIR/wf-trait-fn-arg.rs:11:15
|
||||
|
|
||||
LL | struct Bar<T: Eq + ?Sized> {
|
||||
| ^^ required by this bound in `Bar`
|
||||
help: consider further restricting `Self`
|
||||
|
|
||||
LL | fn bar(&self, x: &Bar<Self>) where Self: Eq;
|
||||
|
|
|
@ -4,6 +4,11 @@ error[E0277]: the trait bound `Self: Eq` is not satisfied
|
|||
LL | fn bar(&self) -> &Bar<Self>;
|
||||
| ^^^^^^^^^ the trait `Eq` is not implemented for `Self`
|
||||
|
|
||||
note: required by a bound in `Bar`
|
||||
--> $DIR/wf-trait-fn-ret.rs:10:15
|
||||
|
|
||||
LL | struct Bar<T: Eq + ?Sized> {
|
||||
| ^^ required by this bound in `Bar`
|
||||
help: consider further restricting `Self`
|
||||
|
|
||||
LL | fn bar(&self) -> &Bar<Self> where Self: Eq;
|
||||
|
|
|
@ -4,6 +4,11 @@ error[E0277]: the trait bound `Self: Eq` is not satisfied
|
|||
LL | Bar<Self>: Copy;
|
||||
| ^^^^ the trait `Eq` is not implemented for `Self`
|
||||
|
|
||||
note: required by a bound in `Bar`
|
||||
--> $DIR/wf-trait-fn-where-clause.rs:10:15
|
||||
|
|
||||
LL | struct Bar<T: Eq + ?Sized> {
|
||||
| ^^ required by this bound in `Bar`
|
||||
help: consider further restricting `Self`
|
||||
|
|
||||
LL | Bar<Self>: Copy, Self: Eq;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue