Apply nested goals certainty to InspectGoals for normalizes-to
This commit is contained in:
@@ -120,15 +120,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for NestedObligationsForSelfTy<'a, 'tcx> {
|
|||||||
fn visit_goal(&mut self, inspect_goal: &InspectGoal<'_, 'tcx>) {
|
fn visit_goal(&mut self, inspect_goal: &InspectGoal<'_, 'tcx>) {
|
||||||
// No need to walk into goal subtrees that certainly hold, since they
|
// No need to walk into goal subtrees that certainly hold, since they
|
||||||
// wouldn't then be stalled on an infer var.
|
// wouldn't then be stalled on an infer var.
|
||||||
// FIXME: We also walk into normalizes-to goals since their certainty
|
if inspect_goal.result() == Ok(Certainty::Yes) {
|
||||||
// is forced to `Certainty::Yes` since they pass down ambiguous subgoals
|
|
||||||
// to their parent.
|
|
||||||
if inspect_goal.result() == Ok(Certainty::Yes)
|
|
||||||
&& !matches!(
|
|
||||||
inspect_goal.goal().predicate.kind().skip_binder(),
|
|
||||||
ty::PredicateKind::NormalizesTo(_)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
|
|
||||||
use std::assert_matches::assert_matches;
|
use std::assert_matches::assert_matches;
|
||||||
|
|
||||||
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
|
use rustc_infer::infer::InferCtxt;
|
||||||
|
use rustc_infer::traits::Obligation;
|
||||||
use rustc_macros::extension;
|
use rustc_macros::extension;
|
||||||
use rustc_middle::traits::ObligationCause;
|
use rustc_middle::traits::ObligationCause;
|
||||||
use rustc_middle::traits::solve::{Certainty, Goal, GoalSource, NoSolution, QueryResult};
|
use rustc_middle::traits::solve::{Certainty, Goal, GoalSource, NoSolution, QueryResult};
|
||||||
@@ -20,7 +21,7 @@ use rustc_middle::{bug, ty};
|
|||||||
use rustc_next_trait_solver::resolve::eager_resolve_vars;
|
use rustc_next_trait_solver::resolve::eager_resolve_vars;
|
||||||
use rustc_next_trait_solver::solve::inspect::{self, instantiate_canonical_state};
|
use rustc_next_trait_solver::solve::inspect::{self, instantiate_canonical_state};
|
||||||
use rustc_next_trait_solver::solve::{GenerateProofTree, MaybeCause, SolverDelegateEvalExt as _};
|
use rustc_next_trait_solver::solve::{GenerateProofTree, MaybeCause, SolverDelegateEvalExt as _};
|
||||||
use rustc_span::{DUMMY_SP, Span};
|
use rustc_span::Span;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
use crate::solve::delegate::SolverDelegate;
|
use crate::solve::delegate::SolverDelegate;
|
||||||
@@ -60,28 +61,29 @@ impl<'tcx> NormalizesToTermHack<'tcx> {
|
|||||||
/// Relate the `term` with the new `unconstrained_term` created
|
/// Relate the `term` with the new `unconstrained_term` created
|
||||||
/// when computing the proof tree for this `NormalizesTo` goals.
|
/// when computing the proof tree for this `NormalizesTo` goals.
|
||||||
/// This handles nested obligations.
|
/// This handles nested obligations.
|
||||||
fn constrain(
|
fn constrain_and(
|
||||||
self,
|
&self,
|
||||||
infcx: &InferCtxt<'tcx>,
|
infcx: &InferCtxt<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
f: impl FnOnce(&ObligationCtxt<'_, 'tcx>),
|
||||||
) -> Result<Certainty, NoSolution> {
|
) -> Result<Certainty, NoSolution> {
|
||||||
infcx
|
let ocx = ObligationCtxt::new(infcx);
|
||||||
.at(&ObligationCause::dummy_with_span(span), param_env)
|
ocx.eq(
|
||||||
.eq(DefineOpaqueTypes::Yes, self.term, self.unconstrained_term)
|
&ObligationCause::dummy_with_span(span),
|
||||||
.map_err(|_| NoSolution)
|
param_env,
|
||||||
.and_then(|InferOk { value: (), obligations }| {
|
self.term,
|
||||||
let ocx = ObligationCtxt::new(infcx);
|
self.unconstrained_term,
|
||||||
ocx.register_obligations(obligations);
|
)?;
|
||||||
let errors = ocx.select_all_or_error();
|
f(&ocx);
|
||||||
if errors.is_empty() {
|
let errors = ocx.select_all_or_error();
|
||||||
Ok(Certainty::Yes)
|
if errors.is_empty() {
|
||||||
} else if errors.iter().all(|e| !e.is_true_error()) {
|
Ok(Certainty::Yes)
|
||||||
Ok(Certainty::AMBIGUOUS)
|
} else if errors.iter().all(|e| !e.is_true_error()) {
|
||||||
} else {
|
Ok(Certainty::AMBIGUOUS)
|
||||||
Err(NoSolution)
|
} else {
|
||||||
}
|
Err(NoSolution)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,11 +162,11 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
|
|||||||
let () =
|
let () =
|
||||||
instantiate_canonical_state(infcx, span, param_env, &mut orig_values, self.final_state);
|
instantiate_canonical_state(infcx, span, param_env, &mut orig_values, self.final_state);
|
||||||
|
|
||||||
if let Some(term_hack) = self.goal.normalizes_to_term_hack {
|
if let Some(term_hack) = &self.goal.normalizes_to_term_hack {
|
||||||
// FIXME: We ignore the expected term of `NormalizesTo` goals
|
// FIXME: We ignore the expected term of `NormalizesTo` goals
|
||||||
// when computing the result of its candidates. This is
|
// when computing the result of its candidates. This is
|
||||||
// scuffed.
|
// scuffed.
|
||||||
let _ = term_hack.constrain(infcx, span, param_env);
|
let _ = term_hack.constrain_and(infcx, span, param_env, |_| {});
|
||||||
}
|
}
|
||||||
|
|
||||||
instantiated_goals
|
instantiated_goals
|
||||||
@@ -240,13 +242,39 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
|
|||||||
// building their proof tree, the expected term was unconstrained, but when
|
// building their proof tree, the expected term was unconstrained, but when
|
||||||
// instantiating the candidate it is already constrained to the result of another
|
// instantiating the candidate it is already constrained to the result of another
|
||||||
// candidate.
|
// candidate.
|
||||||
let proof_tree = infcx
|
let normalizes_to_term_hack = NormalizesToTermHack { term, unconstrained_term };
|
||||||
.probe(|_| infcx.evaluate_root_goal_raw(goal, GenerateProofTree::Yes, None).1);
|
let (proof_tree, nested_goals_result) = infcx.probe(|_| {
|
||||||
|
// Here, if we have any nested goals, then we make sure to apply them
|
||||||
|
// considering the constrained RHS, and pass the resulting certainty to
|
||||||
|
// `InspectGoal::new` so that the goal has the right result (and maintains
|
||||||
|
// the impression that we don't do this normalizes-to infer hack at all).
|
||||||
|
let (nested, proof_tree) =
|
||||||
|
infcx.evaluate_root_goal_raw(goal, GenerateProofTree::Yes, None);
|
||||||
|
let proof_tree = proof_tree.unwrap();
|
||||||
|
let nested_goals_result = nested.and_then(|(nested, _)| {
|
||||||
|
normalizes_to_term_hack.constrain_and(
|
||||||
|
infcx,
|
||||||
|
span,
|
||||||
|
proof_tree.uncanonicalized_goal.param_env,
|
||||||
|
|ocx| {
|
||||||
|
ocx.register_obligations(nested.0.into_iter().map(|(_, goal)| {
|
||||||
|
Obligation::new(
|
||||||
|
infcx.tcx,
|
||||||
|
ObligationCause::dummy_with_span(span),
|
||||||
|
goal.param_env,
|
||||||
|
goal.predicate,
|
||||||
|
)
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
)
|
||||||
|
});
|
||||||
|
(proof_tree, nested_goals_result)
|
||||||
|
});
|
||||||
InspectGoal::new(
|
InspectGoal::new(
|
||||||
infcx,
|
infcx,
|
||||||
self.goal.depth + 1,
|
self.goal.depth + 1,
|
||||||
proof_tree.unwrap(),
|
proof_tree,
|
||||||
Some(NormalizesToTermHack { term, unconstrained_term }),
|
Some((normalizes_to_term_hack, nested_goals_result)),
|
||||||
source,
|
source,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -393,20 +421,21 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
|
|||||||
infcx: &'a InferCtxt<'tcx>,
|
infcx: &'a InferCtxt<'tcx>,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
root: inspect::GoalEvaluation<TyCtxt<'tcx>>,
|
root: inspect::GoalEvaluation<TyCtxt<'tcx>>,
|
||||||
normalizes_to_term_hack: Option<NormalizesToTermHack<'tcx>>,
|
term_hack_and_nested_certainty: Option<(
|
||||||
|
NormalizesToTermHack<'tcx>,
|
||||||
|
Result<Certainty, NoSolution>,
|
||||||
|
)>,
|
||||||
source: GoalSource,
|
source: GoalSource,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let infcx = <&SolverDelegate<'tcx>>::from(infcx);
|
let infcx = <&SolverDelegate<'tcx>>::from(infcx);
|
||||||
|
|
||||||
let inspect::GoalEvaluation { uncanonicalized_goal, orig_values, evaluation } = root;
|
let inspect::GoalEvaluation { uncanonicalized_goal, orig_values, evaluation } = root;
|
||||||
|
// If there's a normalizes-to goal, AND the evaluation result with the result of
|
||||||
|
// constraining the normalizes-to RHS and computing the nested goals.
|
||||||
let result = evaluation.result.and_then(|ok| {
|
let result = evaluation.result.and_then(|ok| {
|
||||||
if let Some(term_hack) = normalizes_to_term_hack {
|
let nested_goals_certainty =
|
||||||
infcx
|
term_hack_and_nested_certainty.map_or(Ok(Certainty::Yes), |(_, c)| c)?;
|
||||||
.probe(|_| term_hack.constrain(infcx, DUMMY_SP, uncanonicalized_goal.param_env))
|
Ok(ok.value.certainty.and(nested_goals_certainty))
|
||||||
.map(|certainty| ok.value.certainty.and(certainty))
|
|
||||||
} else {
|
|
||||||
Ok(ok.value.certainty)
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
InspectGoal {
|
InspectGoal {
|
||||||
@@ -416,7 +445,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
|
|||||||
goal: eager_resolve_vars(infcx, uncanonicalized_goal),
|
goal: eager_resolve_vars(infcx, uncanonicalized_goal),
|
||||||
result,
|
result,
|
||||||
evaluation_kind: evaluation.kind,
|
evaluation_kind: evaluation.kind,
|
||||||
normalizes_to_term_hack,
|
normalizes_to_term_hack: term_hack_and_nested_certainty.map(|(n, _)| n),
|
||||||
source,
|
source,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,22 @@
|
|||||||
error[E0284]: type annotations needed: cannot satisfy `impl Sized == _`
|
error[E0283]: type annotations needed
|
||||||
--> $DIR/auto-trait-selection-freeze.rs:19:5
|
--> $DIR/auto-trait-selection-freeze.rs:19:16
|
||||||
|
|
|
|
||||||
LL | if false { is_trait(foo()) } else { Default::default() }
|
LL | if false { is_trait(foo()) } else { Default::default() }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `impl Sized == _`
|
| ^^^^^^^^ ----- type must be known at this point
|
||||||
|
| |
|
||||||
|
| cannot infer type of the type parameter `T` declared on the function `is_trait`
|
||||||
|
|
|
||||||
|
= note: cannot satisfy `_: Trait<_>`
|
||||||
|
note: required by a bound in `is_trait`
|
||||||
|
--> $DIR/auto-trait-selection-freeze.rs:11:16
|
||||||
|
|
|
||||||
|
LL | fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
|
||||||
|
| ^^^^^^^^ required by this bound in `is_trait`
|
||||||
|
help: consider specifying the generic arguments
|
||||||
|
|
|
||||||
|
LL | if false { is_trait::<T, U>(foo()) } else { Default::default() }
|
||||||
|
| ++++++++
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0284`.
|
For more information about this error, try `rustc --explain E0283`.
|
||||||
|
|||||||
@@ -1,9 +1,22 @@
|
|||||||
error[E0284]: type annotations needed: cannot satisfy `impl Sized == _`
|
error[E0283]: type annotations needed
|
||||||
--> $DIR/auto-trait-selection.rs:15:5
|
--> $DIR/auto-trait-selection.rs:15:16
|
||||||
|
|
|
|
||||||
LL | if false { is_trait(foo()) } else { Default::default() }
|
LL | if false { is_trait(foo()) } else { Default::default() }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `impl Sized == _`
|
| ^^^^^^^^ ----- type must be known at this point
|
||||||
|
| |
|
||||||
|
| cannot infer type of the type parameter `T` declared on the function `is_trait`
|
||||||
|
|
|
||||||
|
= note: cannot satisfy `_: Trait<_>`
|
||||||
|
note: required by a bound in `is_trait`
|
||||||
|
--> $DIR/auto-trait-selection.rs:7:16
|
||||||
|
|
|
||||||
|
LL | fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
|
||||||
|
| ^^^^^^^^ required by this bound in `is_trait`
|
||||||
|
help: consider specifying the generic arguments
|
||||||
|
|
|
||||||
|
LL | if false { is_trait::<T, U>(foo()) } else { Default::default() }
|
||||||
|
| ++++++++
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0284`.
|
For more information about this error, try `rustc --explain E0283`.
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ LL | type LineStream<'c, 'd> = impl Stream;
|
|||||||
|
|
|
|
||||||
= note: `LineStream` must be used in combination with a concrete type within the same impl
|
= note: `LineStream` must be used in combination with a concrete type within the same impl
|
||||||
|
|
||||||
error[E0271]: type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> == ()`
|
error[E0271]: type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> normalizes-to ()`
|
||||||
--> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:29:43
|
--> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:29:43
|
||||||
|
|
|
|
||||||
LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
|
LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ impl X for Y {
|
|||||||
fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
|
fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
|
||||||
//~^ ERROR method `line_stream` is not a member of trait `X`
|
//~^ ERROR method `line_stream` is not a member of trait `X`
|
||||||
//[current]~^^ ERROR `()` is not a future
|
//[current]~^^ ERROR `()` is not a future
|
||||||
//[next]~^^^ ERROR type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> == ()`
|
//[next]~^^^ ERROR type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> normalizes-to ()`
|
||||||
//[next]~| ERROR type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> normalizes-to _`
|
//[next]~| ERROR type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> normalizes-to _`
|
||||||
//[next]~| ERROR type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> normalizes-to _`
|
//[next]~| ERROR type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> normalizes-to _`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
error[E0284]: type annotations needed: cannot satisfy `impl Sized == _`
|
error[E0284]: type annotations needed: cannot normalize `build<_>::{opaque#0}`
|
||||||
--> $DIR/recursive-in-exhaustiveness.rs:19:17
|
--> $DIR/recursive-in-exhaustiveness.rs:20:5
|
||||||
|
|
|
|
||||||
LL | let (x,) = (build(x),);
|
LL | build(x)
|
||||||
| ^^^^^^^^ cannot satisfy `impl Sized == _`
|
| ^^^^^^^^ cannot normalize `build<_>::{opaque#0}`
|
||||||
|
|
||||||
error[E0271]: type mismatch resolving `build2<(_,)>::{opaque#0} normalizes-to _`
|
error[E0271]: type mismatch resolving `build2<(_,)>::{opaque#0} normalizes-to _`
|
||||||
--> $DIR/recursive-in-exhaustiveness.rs:30:6
|
--> $DIR/recursive-in-exhaustiveness.rs:30:6
|
||||||
|
|||||||
@@ -17,8 +17,8 @@
|
|||||||
fn build<T>(x: T) -> impl Sized {
|
fn build<T>(x: T) -> impl Sized {
|
||||||
//[current]~^ ERROR cannot resolve opaque type
|
//[current]~^ ERROR cannot resolve opaque type
|
||||||
let (x,) = (build(x),);
|
let (x,) = (build(x),);
|
||||||
//[next]~^ ERROR type annotations needed
|
|
||||||
build(x)
|
build(x)
|
||||||
|
//[next]~^ ERROR type annotations needed: cannot normalize `build<_>::{opaque#0}`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opaque<T> = (Opaque<T>,)
|
// Opaque<T> = (Opaque<T>,)
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
error[E0284]: type annotations needed: cannot satisfy `_ == A`
|
error[E0282]: type annotations needed
|
||||||
--> $DIR/two_tait_defining_each_other2.rs:12:8
|
--> $DIR/two_tait_defining_each_other2.rs:12:11
|
||||||
|
|
|
|
||||||
LL | fn muh(x: A) -> B {
|
LL | fn muh(x: A) -> B {
|
||||||
| ^ cannot satisfy `_ == A`
|
| ^ cannot infer type
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0284`.
|
For more information about this error, try `rustc --explain E0282`.
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ trait Foo {}
|
|||||||
|
|
||||||
#[define_opaque(A, B)]
|
#[define_opaque(A, B)]
|
||||||
fn muh(x: A) -> B {
|
fn muh(x: A) -> B {
|
||||||
//[next]~^ ERROR: cannot satisfy `_ == A`
|
//[next]~^ ERROR: type annotations needed
|
||||||
x // B's hidden type is A (opaquely)
|
x // B's hidden type is A (opaquely)
|
||||||
//[current]~^ ERROR opaque type's hidden type cannot be another opaque type
|
//[current]~^ ERROR opaque type's hidden type cannot be another opaque type
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn weird0() -> impl Sized + !Sized {}
|
fn weird0() -> impl Sized + !Sized {}
|
||||||
//~^ ERROR type mismatch resolving
|
//~^ ERROR the trait bound `(): !Sized` is not satisfied
|
||||||
fn weird1() -> impl !Sized + Sized {}
|
fn weird1() -> impl !Sized + Sized {}
|
||||||
//~^ ERROR type mismatch resolving
|
//~^ ERROR the trait bound `(): !Sized` is not satisfied
|
||||||
fn weird2() -> impl !Sized {}
|
fn weird2() -> impl !Sized {}
|
||||||
//~^ ERROR type mismatch resolving
|
//~^ ERROR the trait bound `(): !Sized` is not satisfied
|
||||||
//~| ERROR the size for values of type
|
//~| ERROR the size for values of type
|
||||||
|
|||||||
@@ -7,23 +7,23 @@ LL | fn weird2() -> impl !Sized {}
|
|||||||
= help: the trait `Sized` is not implemented for `impl !Sized`
|
= help: the trait `Sized` is not implemented for `impl !Sized`
|
||||||
= note: the return type of a function must have a statically known size
|
= note: the return type of a function must have a statically known size
|
||||||
|
|
||||||
error[E0271]: type mismatch resolving `impl !Sized + Sized == ()`
|
error[E0277]: the trait bound `(): !Sized` is not satisfied
|
||||||
--> $DIR/opaque-type-unsatisfied-bound.rs:15:16
|
--> $DIR/opaque-type-unsatisfied-bound.rs:15:16
|
||||||
|
|
|
|
||||||
LL | fn weird0() -> impl Sized + !Sized {}
|
LL | fn weird0() -> impl Sized + !Sized {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^ types differ
|
| ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
|
||||||
|
|
||||||
error[E0271]: type mismatch resolving `impl !Sized + Sized == ()`
|
error[E0277]: the trait bound `(): !Sized` is not satisfied
|
||||||
--> $DIR/opaque-type-unsatisfied-bound.rs:17:16
|
--> $DIR/opaque-type-unsatisfied-bound.rs:17:16
|
||||||
|
|
|
|
||||||
LL | fn weird1() -> impl !Sized + Sized {}
|
LL | fn weird1() -> impl !Sized + Sized {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^ types differ
|
| ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
|
||||||
|
|
||||||
error[E0271]: type mismatch resolving `impl !Sized == ()`
|
error[E0277]: the trait bound `(): !Sized` is not satisfied
|
||||||
--> $DIR/opaque-type-unsatisfied-bound.rs:19:16
|
--> $DIR/opaque-type-unsatisfied-bound.rs:19:16
|
||||||
|
|
|
|
||||||
LL | fn weird2() -> impl !Sized {}
|
LL | fn weird2() -> impl !Sized {}
|
||||||
| ^^^^^^^^^^^ types differ
|
| ^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
|
||||||
|
|
||||||
error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied
|
error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied
|
||||||
--> $DIR/opaque-type-unsatisfied-bound.rs:12:13
|
--> $DIR/opaque-type-unsatisfied-bound.rs:12:13
|
||||||
@@ -41,5 +41,4 @@ LL | fn consume(_: impl Trait) {}
|
|||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0271, E0277.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
For more information about an error, try `rustc --explain E0271`.
|
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
#![feature(negative_bounds, unboxed_closures)]
|
#![feature(negative_bounds, unboxed_closures)]
|
||||||
|
|
||||||
fn produce() -> impl !Fn<(u32,)> {}
|
fn produce() -> impl !Fn<(u32,)> {}
|
||||||
//~^ ERROR type mismatch resolving
|
//~^ ERROR the trait bound `(): !Fn(u32)` is not satisfied
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
error[E0271]: type mismatch resolving `impl !Fn<(u32,)> == ()`
|
error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied
|
||||||
--> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17
|
--> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17
|
||||||
|
|
|
|
||||||
LL | fn produce() -> impl !Fn<(u32,)> {}
|
LL | fn produce() -> impl !Fn<(u32,)> {}
|
||||||
| ^^^^^^^^^^^^^^^^ types differ
|
| ^^^^^^^^^^^^^^^^ the trait bound `(): !Fn(u32)` is not satisfied
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0271`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|||||||
@@ -1,9 +1,16 @@
|
|||||||
error[E0284]: type annotations needed: cannot satisfy `Foo == _`
|
error[E0283]: type annotations needed: cannot satisfy `Foo: Send`
|
||||||
--> $DIR/dont-type_of-tait-in-defining-scope.rs:16:18
|
--> $DIR/dont-type_of-tait-in-defining-scope.rs:16:18
|
||||||
|
|
|
|
||||||
LL | needs_send::<Foo>();
|
LL | needs_send::<Foo>();
|
||||||
| ^^^ cannot satisfy `Foo == _`
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: cannot satisfy `Foo: Send`
|
||||||
|
note: required by a bound in `needs_send`
|
||||||
|
--> $DIR/dont-type_of-tait-in-defining-scope.rs:12:18
|
||||||
|
|
|
||||||
|
LL | fn needs_send<T: Send>() {}
|
||||||
|
| ^^^^ required by this bound in `needs_send`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0284`.
|
For more information about this error, try `rustc --explain E0283`.
|
||||||
|
|||||||
@@ -1,9 +1,16 @@
|
|||||||
error[E0284]: type annotations needed: cannot satisfy `Foo == _`
|
error[E0283]: type annotations needed: cannot satisfy `Foo: Send`
|
||||||
--> $DIR/dont-type_of-tait-in-defining-scope.rs:16:18
|
--> $DIR/dont-type_of-tait-in-defining-scope.rs:16:18
|
||||||
|
|
|
|
||||||
LL | needs_send::<Foo>();
|
LL | needs_send::<Foo>();
|
||||||
| ^^^ cannot satisfy `Foo == _`
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: cannot satisfy `Foo: Send`
|
||||||
|
note: required by a bound in `needs_send`
|
||||||
|
--> $DIR/dont-type_of-tait-in-defining-scope.rs:12:18
|
||||||
|
|
|
||||||
|
LL | fn needs_send<T: Send>() {}
|
||||||
|
| ^^^^ required by this bound in `needs_send`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0284`.
|
For more information about this error, try `rustc --explain E0283`.
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ fn needs_send<T: Send>() {}
|
|||||||
#[define_opaque(Foo)]
|
#[define_opaque(Foo)]
|
||||||
fn test(_: Foo) {
|
fn test(_: Foo) {
|
||||||
needs_send::<Foo>();
|
needs_send::<Foo>();
|
||||||
//~^ ERROR type annotations needed: cannot satisfy `Foo == _`
|
//~^ ERROR type annotations needed
|
||||||
}
|
}
|
||||||
|
|
||||||
#[define_opaque(Foo)]
|
#[define_opaque(Foo)]
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ LL | impl<In, Out> Trait<Bar, In> for Out {
|
|||||||
LL | impl<In, Out> Trait<(), In> for Out {
|
LL | impl<In, Out> Trait<(), In> for Out {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
|
||||||
|
|
||||||
error[E0284]: type annotations needed: cannot satisfy `Bar == _`
|
error[E0282]: type annotations needed
|
||||||
--> $DIR/issue-84660-unsoundness.rs:24:37
|
--> $DIR/issue-84660-unsoundness.rs:24:37
|
||||||
|
|
|
|
||||||
LL | fn convert(_i: In) -> Self::Out {
|
LL | fn convert(_i: In) -> Self::Out {
|
||||||
@@ -16,9 +16,9 @@ LL | |
|
|||||||
LL | |
|
LL | |
|
||||||
LL | | unreachable!();
|
LL | | unreachable!();
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_____^ cannot satisfy `Bar == _`
|
| |_____^ cannot infer type
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0119, E0284.
|
Some errors have detailed explanations: E0119, E0282.
|
||||||
For more information about an error, try `rustc --explain E0119`.
|
For more information about an error, try `rustc --explain E0119`.
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ impl<In, Out> Trait<Bar, In> for Out {
|
|||||||
type Out = Out;
|
type Out = Out;
|
||||||
#[define_opaque(Bar)]
|
#[define_opaque(Bar)]
|
||||||
fn convert(_i: In) -> Self::Out {
|
fn convert(_i: In) -> Self::Out {
|
||||||
//[next]~^ ERROR: type annotations needed: cannot satisfy `Bar == _`
|
//[next]~^ ERROR: type annotations needed
|
||||||
//[current]~^^ ERROR: item does not constrain `Bar::{opaque#0}`
|
//[current]~^^ ERROR: item does not constrain `Bar::{opaque#0}`
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
error[E0284]: type annotations needed: cannot satisfy `impl Foo<FooX> == ()`
|
error[E0282]: type annotations needed
|
||||||
--> $DIR/nested-tait-inference2.rs:20:5
|
--> $DIR/nested-tait-inference2.rs:20:5
|
||||||
|
|
|
|
||||||
LL | ()
|
LL | ()
|
||||||
| ^^ cannot satisfy `impl Foo<FooX> == ()`
|
| ^^ cannot infer type
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0284`.
|
For more information about this error, try `rustc --explain E0282`.
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ impl Foo<u32> for () {}
|
|||||||
fn foo() -> impl Foo<FooX> {
|
fn foo() -> impl Foo<FooX> {
|
||||||
//[current]~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied
|
//[current]~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied
|
||||||
()
|
()
|
||||||
//[next]~^ ERROR: cannot satisfy `impl Foo<FooX> == ()`
|
//[next]~^ ERROR: type annotations needed
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|||||||
Reference in New Issue
Block a user