instantiate predicate binder without recanonicalizing goal in new solver
This commit is contained in:
parent
c0c37cafdc
commit
5508b471bd
23 changed files with 114 additions and 213 deletions
|
|
@ -1,7 +1,6 @@
|
|||
//! A utility module to inspect currently ambiguous obligations in the current context.
|
||||
|
||||
use rustc_infer::traits::{self, ObligationCause, PredicateObligations};
|
||||
use rustc_middle::traits::solve::GoalSource;
|
||||
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::solve::Certainty;
|
||||
|
|
@ -127,21 +126,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for NestedObligationsForSelfTy<'a, 'tcx> {
|
|||
|
||||
let tcx = self.fcx.tcx;
|
||||
let goal = inspect_goal.goal();
|
||||
if self.fcx.predicate_has_self_ty(goal.predicate, self.self_ty)
|
||||
// We do not push the instantiated forms of goals as it would cause any
|
||||
// aliases referencing bound vars to go from having escaping bound vars to
|
||||
// being able to be normalized to an inference variable.
|
||||
//
|
||||
// This is mostly just a hack as arbitrary nested goals could still contain
|
||||
// such aliases while having a different `GoalSource`. Closure signature inference
|
||||
// however can't really handle *every* higher ranked `Fn` goal also being present
|
||||
// in the form of `?c: Fn<(<?x as Trait<'!a>>::Assoc)`.
|
||||
//
|
||||
// This also just better matches the behaviour of the old solver where we do not
|
||||
// encounter instantiated forms of goals, only nested goals that referred to bound
|
||||
// vars from instantiated goals.
|
||||
&& !matches!(inspect_goal.source(), GoalSource::InstantiateHigherRanked)
|
||||
{
|
||||
if self.fcx.predicate_has_self_ty(goal.predicate, self.self_ty) {
|
||||
self.obligations_for_self_ty.push(traits::Obligation::new(
|
||||
tcx,
|
||||
self.root_cause.clone(),
|
||||
|
|
|
|||
|
|
@ -297,9 +297,6 @@ where
|
|||
// corecursive functions as explained in #136824, relating types never
|
||||
// introduces a constructor which could cause the recursion to be guarded.
|
||||
GoalSource::TypeRelating => PathKind::Inductive,
|
||||
// Instantiating a higher ranked goal can never cause the recursion to be
|
||||
// guarded and is therefore unproductive.
|
||||
GoalSource::InstantiateHigherRanked => PathKind::Inductive,
|
||||
// These goal sources are likely unproductive and can be changed to
|
||||
// `PathKind::Inductive`. Keeping them as unknown until we're confident
|
||||
// about this and have an example where it is necessary.
|
||||
|
|
@ -567,66 +564,56 @@ where
|
|||
pub(super) fn compute_goal(&mut self, goal: Goal<I, I::Predicate>) -> QueryResult<I> {
|
||||
let Goal { param_env, predicate } = goal;
|
||||
let kind = predicate.kind();
|
||||
if let Some(kind) = kind.no_bound_vars() {
|
||||
match kind {
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)) => {
|
||||
self.compute_trait_goal(Goal { param_env, predicate }).map(|(r, _via)| r)
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(predicate)) => {
|
||||
self.compute_host_effect_goal(Goal { param_env, predicate })
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Projection(predicate)) => {
|
||||
self.compute_projection_goal(Goal { param_env, predicate })
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(predicate)) => {
|
||||
self.compute_type_outlives_goal(Goal { param_env, predicate })
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(predicate)) => {
|
||||
self.compute_region_outlives_goal(Goal { param_env, predicate })
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
|
||||
self.compute_const_arg_has_type_goal(Goal { param_env, predicate: (ct, ty) })
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(symbol)) => {
|
||||
self.compute_unstable_feature_goal(param_env, symbol)
|
||||
}
|
||||
ty::PredicateKind::Subtype(predicate) => {
|
||||
self.compute_subtype_goal(Goal { param_env, predicate })
|
||||
}
|
||||
ty::PredicateKind::Coerce(predicate) => {
|
||||
self.compute_coerce_goal(Goal { param_env, predicate })
|
||||
}
|
||||
ty::PredicateKind::DynCompatible(trait_def_id) => {
|
||||
self.compute_dyn_compatible_goal(trait_def_id)
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term)) => {
|
||||
self.compute_well_formed_goal(Goal { param_env, predicate: term })
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(ct)) => {
|
||||
self.compute_const_evaluatable_goal(Goal { param_env, predicate: ct })
|
||||
}
|
||||
ty::PredicateKind::ConstEquate(_, _) => {
|
||||
panic!("ConstEquate should not be emitted when `-Znext-solver` is active")
|
||||
}
|
||||
ty::PredicateKind::NormalizesTo(predicate) => {
|
||||
self.compute_normalizes_to_goal(Goal { param_env, predicate })
|
||||
}
|
||||
ty::PredicateKind::AliasRelate(lhs, rhs, direction) => self
|
||||
.compute_alias_relate_goal(Goal {
|
||||
param_env,
|
||||
predicate: (lhs, rhs, direction),
|
||||
}),
|
||||
ty::PredicateKind::Ambiguous => {
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
|
||||
}
|
||||
self.enter_forall(kind, |ecx, kind| match kind {
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)) => {
|
||||
ecx.compute_trait_goal(Goal { param_env, predicate }).map(|(r, _via)| r)
|
||||
}
|
||||
} else {
|
||||
self.enter_forall(kind, |ecx, kind| {
|
||||
let goal = goal.with(ecx.cx(), ty::Binder::dummy(kind));
|
||||
ecx.add_goal(GoalSource::InstantiateHigherRanked, goal);
|
||||
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
})
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(predicate)) => {
|
||||
ecx.compute_host_effect_goal(Goal { param_env, predicate })
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Projection(predicate)) => {
|
||||
ecx.compute_projection_goal(Goal { param_env, predicate })
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(predicate)) => {
|
||||
ecx.compute_type_outlives_goal(Goal { param_env, predicate })
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(predicate)) => {
|
||||
ecx.compute_region_outlives_goal(Goal { param_env, predicate })
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
|
||||
ecx.compute_const_arg_has_type_goal(Goal { param_env, predicate: (ct, ty) })
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(symbol)) => {
|
||||
ecx.compute_unstable_feature_goal(param_env, symbol)
|
||||
}
|
||||
ty::PredicateKind::Subtype(predicate) => {
|
||||
ecx.compute_subtype_goal(Goal { param_env, predicate })
|
||||
}
|
||||
ty::PredicateKind::Coerce(predicate) => {
|
||||
ecx.compute_coerce_goal(Goal { param_env, predicate })
|
||||
}
|
||||
ty::PredicateKind::DynCompatible(trait_def_id) => {
|
||||
ecx.compute_dyn_compatible_goal(trait_def_id)
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term)) => {
|
||||
ecx.compute_well_formed_goal(Goal { param_env, predicate: term })
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(ct)) => {
|
||||
ecx.compute_const_evaluatable_goal(Goal { param_env, predicate: ct })
|
||||
}
|
||||
ty::PredicateKind::ConstEquate(_, _) => {
|
||||
panic!("ConstEquate should not be emitted when `-Znext-solver` is active")
|
||||
}
|
||||
ty::PredicateKind::NormalizesTo(predicate) => {
|
||||
ecx.compute_normalizes_to_goal(Goal { param_env, predicate })
|
||||
}
|
||||
ty::PredicateKind::AliasRelate(lhs, rhs, direction) => {
|
||||
ecx.compute_alias_relate_goal(Goal { param_env, predicate: (lhs, rhs, direction) })
|
||||
}
|
||||
ty::PredicateKind::Ambiguous => {
|
||||
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Recursively evaluates all the goals added to this `EvalCtxt` to completion, returning
|
||||
|
|
|
|||
|
|
@ -231,7 +231,6 @@ impl<'tcx> BestObligation<'tcx> {
|
|||
nested_goal.source(),
|
||||
GoalSource::ImplWhereBound
|
||||
| GoalSource::AliasBoundConstCondition
|
||||
| GoalSource::InstantiateHigherRanked
|
||||
| GoalSource::AliasWellFormed
|
||||
) && nested_goal.result().is_err()
|
||||
},
|
||||
|
|
@ -523,10 +522,6 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
|
|||
));
|
||||
impl_where_bound_count += 1;
|
||||
}
|
||||
// Skip over a higher-ranked predicate.
|
||||
(_, GoalSource::InstantiateHigherRanked) => {
|
||||
obligation = self.obligation.clone();
|
||||
}
|
||||
(ChildMode::PassThrough, _)
|
||||
| (_, GoalSource::AliasWellFormed | GoalSource::AliasBoundConstCondition) => {
|
||||
obligation = make_obligation(self.obligation.cause.clone());
|
||||
|
|
|
|||
|
|
@ -735,9 +735,10 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
|
|||
// For bound predicates we simply call `infcx.enter_forall`
|
||||
// and then prove the resulting predicate as a nested goal.
|
||||
let Goal { param_env, predicate } = goal.goal();
|
||||
let trait_ref = match predicate.kind().no_bound_vars() {
|
||||
Some(ty::PredicateKind::Clause(ty::ClauseKind::Trait(tr))) => tr.trait_ref,
|
||||
Some(ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)))
|
||||
let predicate_kind = goal.infcx().enter_forall_and_leak_universe(predicate.kind());
|
||||
let trait_ref = match predicate_kind {
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(tr)) => tr.trait_ref,
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj))
|
||||
if matches!(
|
||||
infcx.tcx.def_kind(proj.projection_term.def_id),
|
||||
DefKind::AssocTy | DefKind::AssocConst
|
||||
|
|
|
|||
|
|
@ -78,8 +78,6 @@ pub enum GoalSource {
|
|||
ImplWhereBound,
|
||||
/// Const conditions that need to hold for `[const]` alias bounds to hold.
|
||||
AliasBoundConstCondition,
|
||||
/// Instantiating a higher-ranked goal and re-proving it.
|
||||
InstantiateHigherRanked,
|
||||
/// Predicate required for an alias projection to be well-formed.
|
||||
/// This is used in three places:
|
||||
/// 1. projecting to an opaque whose hidden type is already registered in
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ LL | impl<T> Trait for Box<T> {}
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>`
|
||||
|
|
||||
= note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>`
|
||||
= note: downstream crates may implement trait `WhereBound` for type `std::boxed::Box<_>`
|
||||
= note: downstream crates may implement trait `WhereBound` for type `std::boxed::Box<<std::boxed::Box<_> as WithAssoc<'a>>::Assoc>`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
//@ known-bug: #140609
|
||||
//@ check-pass
|
||||
#![feature(with_negative_coherence)]
|
||||
#![feature(generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
#![crate_type = "lib"]
|
||||
trait Trait {}
|
||||
struct A<const B: bool>;
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
error[E0277]: the trait bound `for<'a> &'a &T: Trait` is not satisfied
|
||||
--> $DIR/candidate-from-env-universe-err-1.rs:27:16
|
||||
|
|
||||
LL | hr_bound::<&T>();
|
||||
| ^^ the trait `for<'a> Trait` is not implemented for `&'a &T`
|
||||
|
|
||||
note: required by a bound in `hr_bound`
|
||||
--> $DIR/candidate-from-env-universe-err-1.rs:14:20
|
||||
|
|
||||
LL | fn hr_bound<T>()
|
||||
| -------- required by a bound in this function
|
||||
LL | where
|
||||
LL | for<'a> &'a T: Trait,
|
||||
| ^^^^^ required by this bound in `hr_bound`
|
||||
help: consider removing the leading `&`-reference
|
||||
|
|
||||
LL - hr_bound::<&T>();
|
||||
LL + hr_bound::<T>();
|
||||
|
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
//@ revisions: old next
|
||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@[old] check-pass
|
||||
//@ check-pass
|
||||
|
||||
// cc #119820
|
||||
|
||||
|
|
@ -24,8 +25,11 @@ where
|
|||
// but are able to successfully use the impl candidate. Without
|
||||
// the leak check both candidates may apply and we prefer the
|
||||
// `param_env` candidate in winnowing.
|
||||
//
|
||||
// By doing the leak check for each candidate, we discard the `param_env`
|
||||
// candidate and use the impl candidate instead, allowing this to
|
||||
// compile.
|
||||
hr_bound::<&T>();
|
||||
//[next]~^ ERROR the trait bound `for<'a> &'a &T: Trait` is not satisfied
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
error[E0277]: the trait bound `for<'a> T: Trait<'a, '_>` is not satisfied
|
||||
--> $DIR/candidate-from-env-universe-err-2.rs:15:15
|
||||
|
|
||||
LL | impl_hr::<T>();
|
||||
| ^ the trait `for<'a> Trait<'a, '_>` is not implemented for `T`
|
||||
|
|
||||
note: required by a bound in `impl_hr`
|
||||
--> $DIR/candidate-from-env-universe-err-2.rs:12:19
|
||||
|
|
||||
LL | fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impl_hr`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
//@ revisions: current next
|
||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@[current] check-pass
|
||||
//@ check-pass
|
||||
|
||||
// cc #119820
|
||||
|
||||
|
|
@ -13,7 +14,6 @@ fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {}
|
|||
|
||||
fn not_hr<'a, T: for<'b> Trait<'a, 'b> + OtherTrait<'static>>() {
|
||||
impl_hr::<T>();
|
||||
//[next]~^ ERROR the trait bound `for<'a> T: Trait<'a, '_>` is not satisfied
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ LL | projection_bound::<T>();
|
|||
= note: expected associated type `<T as Trait<'static>>::Assoc`
|
||||
found associated type `<T as Trait<'a>>::Assoc`
|
||||
note: the lifetime requirement is introduced here
|
||||
--> $DIR/candidate-from-env-universe-err-project.rs:18:42
|
||||
--> $DIR/candidate-from-env-universe-err-project.rs:19:42
|
||||
|
|
||||
LL | fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -1,26 +1,14 @@
|
|||
error[E0277]: the trait bound `for<'a> T: Trait<'a>` is not satisfied
|
||||
--> $DIR/candidate-from-env-universe-err-project.rs:28:19
|
||||
|
|
||||
LL | trait_bound::<T>();
|
||||
| ^ the trait `for<'a> Trait<'a>` is not implemented for `T`
|
||||
|
|
||||
note: required by a bound in `trait_bound`
|
||||
--> $DIR/candidate-from-env-universe-err-project.rs:17:19
|
||||
|
|
||||
LL | fn trait_bound<T: for<'a> Trait<'a>>() {}
|
||||
| ^^^^^^^^^^^^^^^^^ required by this bound in `trait_bound`
|
||||
|
||||
error[E0277]: the trait bound `for<'a> T: Trait<'a>` is not satisfied
|
||||
error[E0271]: type mismatch resolving `<T as Trait<'a>>::Assoc == usize`
|
||||
--> $DIR/candidate-from-env-universe-err-project.rs:38:24
|
||||
|
|
||||
LL | projection_bound::<T>();
|
||||
| ^ the trait `for<'a> Trait<'a>` is not implemented for `T`
|
||||
| ^ types differ
|
||||
|
|
||||
note: required by a bound in `projection_bound`
|
||||
--> $DIR/candidate-from-env-universe-err-project.rs:18:24
|
||||
--> $DIR/candidate-from-env-universe-err-project.rs:19:42
|
||||
|
|
||||
LL | fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `projection_bound`
|
||||
| ^^^^^^^^^^^^^ required by this bound in `projection_bound`
|
||||
|
||||
error: higher-ranked subtype error
|
||||
--> $DIR/candidate-from-env-universe-err-project.rs:52:30
|
||||
|
|
@ -36,6 +24,6 @@ LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
|
|||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
For more information about this error, try `rustc --explain E0271`.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
//@ revisions: next current
|
||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
|
||||
// cc #119820 the behavior is inconsistent as we discard the where-bound
|
||||
|
|
@ -20,13 +21,12 @@ fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
|
|||
// We use a function with a trivial where-bound which is more
|
||||
// restrictive than the impl.
|
||||
fn function1<T: Trait<'static>>() {
|
||||
// err
|
||||
// ok
|
||||
//
|
||||
// Proving `for<'a> T: Trait<'a>` using the where-bound does not
|
||||
// result in a leak check failure even though it does not apply.
|
||||
// We prefer env candidates over impl candidatescausing this to succeed.
|
||||
trait_bound::<T>();
|
||||
//[next]~^ ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied
|
||||
}
|
||||
|
||||
fn function2<T: Trait<'static, Assoc = usize>>() {
|
||||
|
|
@ -36,7 +36,7 @@ fn function2<T: Trait<'static, Assoc = usize>>() {
|
|||
// does not use the leak check when trying the where-bound, causing us
|
||||
// to prefer it over the impl, resulting in a placeholder error.
|
||||
projection_bound::<T>();
|
||||
//[next]~^ ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied
|
||||
//[next]~^ ERROR type mismatch resolving `<T as Trait<'a>>::Assoc == usize`
|
||||
//[current]~^^ ERROR mismatched types
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
error[E0283]: type annotations needed
|
||||
--> $DIR/leak-check-in-selection-2.rs:17:5
|
||||
|
|
||||
LL | impls_trait::<(), _>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `impls_trait`
|
||||
|
|
||||
note: multiple `impl`s satisfying `for<'a> (): Trait<&'a str, _>` found
|
||||
--> $DIR/leak-check-in-selection-2.rs:10:1
|
||||
|
|
||||
LL | impl<'a> Trait<&'a str, &'a str> for () {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL |
|
||||
LL | impl<'a> Trait<&'a str, String> for () {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: required by a bound in `impls_trait`
|
||||
--> $DIR/leak-check-in-selection-2.rs:14:19
|
||||
|
|
||||
LL | fn impls_trait<T: for<'a> Trait<&'a str, U>, U>() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impls_trait`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0283`.
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
//@ revisions: old next
|
||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@[old] check-pass
|
||||
//@ check-pass
|
||||
|
||||
// cc #119820
|
||||
|
||||
|
|
@ -15,5 +16,4 @@ fn impls_trait<T: for<'a> Trait<&'a str, U>, U>() {}
|
|||
|
||||
fn main() {
|
||||
impls_trait::<(), _>();
|
||||
//[next]~^ ERROR type annotations needed
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,3 @@
|
|||
error[E0283]: type annotations needed
|
||||
--> $DIR/leak-check-in-selection-3.rs:18:5
|
||||
|
|
||||
LL | impls_leak::<Box<_>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls_leak`
|
||||
|
|
||||
note: multiple `impl`s satisfying `for<'a> Box<_>: Leak<'a>` found
|
||||
--> $DIR/leak-check-in-selection-3.rs:9:1
|
||||
|
|
||||
LL | impl Leak<'_> for Box<u32> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | impl Leak<'static> for Box<u16> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: required by a bound in `impls_leak`
|
||||
--> $DIR/leak-check-in-selection-3.rs:12:18
|
||||
|
|
||||
LL | fn impls_leak<T: for<'a> Leak<'a>>() {}
|
||||
| ^^^^^^^^^^^^^^^^ required by this bound in `impls_leak`
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/leak-check-in-selection-3.rs:35:5
|
||||
|
|
||||
|
|
@ -24,7 +5,7 @@ LL | impls_indirect_leak::<Box<_>>();
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls_indirect_leak`
|
||||
|
|
||||
note: multiple `impl`s satisfying `for<'a> Box<_>: Leak<'a>` found
|
||||
--> $DIR/leak-check-in-selection-3.rs:9:1
|
||||
--> $DIR/leak-check-in-selection-3.rs:10:1
|
||||
|
|
||||
LL | impl Leak<'_> for Box<u32> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -43,6 +24,6 @@ note: required by a bound in `impls_indirect_leak`
|
|||
LL | fn impls_indirect_leak<T: for<'a> IndirectLeak<'a>>() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impls_indirect_leak`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0283`.
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ LL | impls_indirect_leak::<Box<_>>();
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls_indirect_leak`
|
||||
|
|
||||
note: multiple `impl`s satisfying `Box<_>: Leak<'_>` found
|
||||
--> $DIR/leak-check-in-selection-3.rs:9:1
|
||||
--> $DIR/leak-check-in-selection-3.rs:10:1
|
||||
|
|
||||
LL | impl Leak<'_> for Box<u32> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
//@ revisions: old next
|
||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
|
||||
// cc #119820, the behavior here is inconsistent,
|
||||
|
|
@ -16,7 +17,6 @@ fn direct() {
|
|||
// The `Box<u16>` impls fails the leak check,
|
||||
// meaning that we apply the `Box<u32>` impl.
|
||||
impls_leak::<Box<_>>();
|
||||
//[next]~^ ERROR type annotations needed
|
||||
}
|
||||
|
||||
trait IndirectLeak<'a> {}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
error[E0283]: type annotations needed
|
||||
--> $DIR/leak-check-in-selection-6-ambig-unify.rs:30:5
|
||||
--> $DIR/leak-check-in-selection-6-ambig-unify.rs:32:5
|
||||
|
|
||||
LL | impls_trait::<(), _, _>()
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `impls_trait`
|
||||
|
|
||||
note: multiple `impl`s satisfying `(): Trait<_, _>` found
|
||||
--> $DIR/leak-check-in-selection-6-ambig-unify.rs:26:1
|
||||
--> $DIR/leak-check-in-selection-6-ambig-unify.rs:28:1
|
||||
|
|
||||
LL | impl<V> Trait<u32, V> for () where for<'b> (): LeakCheckFailure<'static, 'b, V> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | impl<V> Trait<u32, V> for () where for<'b> ((),): LeakCheckFailure<'static, 'b, V> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | impl<V> Trait<u16, V> for () {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: required by a bound in `impls_trait`
|
||||
--> $DIR/leak-check-in-selection-6-ambig-unify.rs:28:19
|
||||
--> $DIR/leak-check-in-selection-6-ambig-unify.rs:30:19
|
||||
|
|
||||
LL | fn impls_trait<T: Trait<U, V>, U: Id<V>, V>() {}
|
||||
| ^^^^^^^^^^^ required by this bound in `impls_trait`
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
error[E0283]: type annotations needed
|
||||
--> $DIR/leak-check-in-selection-6-ambig-unify.rs:30:5
|
||||
--> $DIR/leak-check-in-selection-6-ambig-unify.rs:32:5
|
||||
|
|
||||
LL | impls_trait::<(), _, _>()
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `impls_trait`
|
||||
|
|
||||
note: multiple `impl`s satisfying `(): Trait<_, _>` found
|
||||
--> $DIR/leak-check-in-selection-6-ambig-unify.rs:26:1
|
||||
--> $DIR/leak-check-in-selection-6-ambig-unify.rs:28:1
|
||||
|
|
||||
LL | impl<V> Trait<u32, V> for () where for<'b> (): LeakCheckFailure<'static, 'b, V> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | impl<V> Trait<u32, V> for () where for<'b> ((),): LeakCheckFailure<'static, 'b, V> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | impl<V> Trait<u16, V> for () {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: required by a bound in `impls_trait`
|
||||
--> $DIR/leak-check-in-selection-6-ambig-unify.rs:28:19
|
||||
--> $DIR/leak-check-in-selection-6-ambig-unify.rs:30:19
|
||||
|
|
||||
LL | fn impls_trait<T: Trait<U, V>, U: Id<V>, V>() {}
|
||||
| ^^^^^^^^^^^ required by this bound in `impls_trait`
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
//@ revisions: old next
|
||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
|
||||
// The new trait solver does not return region constraints if the goal
|
||||
|
|
@ -21,9 +22,10 @@ impl Id<u16> for u16 {}
|
|||
|
||||
trait LeakCheckFailure<'a, 'b, V: ?Sized> {}
|
||||
impl<'a, 'b: 'a, V: ?Sized + Ambig> LeakCheckFailure<'a, 'b, V> for () {}
|
||||
impl<'a, 'b, V: ?Sized, T: LeakCheckFailure<'a, 'b, V>> LeakCheckFailure<'a, 'b, V> for (T,) {}
|
||||
|
||||
trait Trait<U, V> {}
|
||||
impl<V> Trait<u32, V> for () where for<'b> (): LeakCheckFailure<'static, 'b, V> {}
|
||||
impl<V> Trait<u32, V> for () where for<'b> ((),): LeakCheckFailure<'static, 'b, V> {}
|
||||
impl<V> Trait<u16, V> for () {}
|
||||
fn impls_trait<T: Trait<U, V>, U: Id<V>, V>() {}
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
//@ check-pass
|
||||
|
||||
// cc #119820
|
||||
struct W<T, U>(T, U);
|
||||
|
||||
trait Trait<T> {}
|
||||
// using this impl results in a higher-ranked region error.
|
||||
impl<'a> Trait<W<&'a str, &'a str>> for () {}
|
||||
impl<'a> Trait<W<&'a str, String>> for () {}
|
||||
|
||||
trait NotString {}
|
||||
impl NotString for &str {}
|
||||
impl NotString for u32 {}
|
||||
|
||||
|
||||
trait Overlap<U> {}
|
||||
impl<T: for<'a> Trait<W<&'a str, U>>, U> Overlap<U> for T {}
|
||||
impl<U: NotString> Overlap<U> for () {}
|
||||
|
||||
fn main() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue