normalizes-to disable infer var check
This commit is contained in:
parent
3e33bda032
commit
b64b25b99e
@ -16,7 +16,7 @@
|
|||||||
use rustc_type_ir::inherent::*;
|
use rustc_type_ir::inherent::*;
|
||||||
use rustc_type_ir::relate::solver_relating::RelateExt;
|
use rustc_type_ir::relate::solver_relating::RelateExt;
|
||||||
use rustc_type_ir::{self as ty, Canonical, CanonicalVarValues, InferCtxtLike, Interner};
|
use rustc_type_ir::{self as ty, Canonical, CanonicalVarValues, InferCtxtLike, Interner};
|
||||||
use tracing::{instrument, trace};
|
use tracing::{debug, instrument, trace};
|
||||||
|
|
||||||
use crate::canonicalizer::{CanonicalizeMode, Canonicalizer};
|
use crate::canonicalizer::{CanonicalizeMode, Canonicalizer};
|
||||||
use crate::delegate::SolverDelegate;
|
use crate::delegate::SolverDelegate;
|
||||||
@ -165,13 +165,22 @@ pub(in crate::solve) fn evaluate_added_goals_and_make_canonical_response(
|
|||||||
// HACK: We bail with overflow if the response would have too many non-region
|
// HACK: We bail with overflow if the response would have too many non-region
|
||||||
// inference variables. This tends to only happen if we encounter a lot of
|
// inference variables. This tends to only happen if we encounter a lot of
|
||||||
// ambiguous alias types which get replaced with fresh inference variables
|
// ambiguous alias types which get replaced with fresh inference variables
|
||||||
// during generalization. This prevents a hang in nalgebra.
|
// during generalization. This prevents hangs caused by an exponential blowup,
|
||||||
|
// see tests/ui/traits/next-solver/coherence-alias-hang.rs.
|
||||||
|
//
|
||||||
|
// We don't do so for `NormalizesTo` goals as we erased the expected term and
|
||||||
|
// bailing with overflow here would prevent us from detecting a type-mismatch,
|
||||||
|
// causing a coherence error in diesel, see #131969. We still bail with verflow
|
||||||
|
// when later returning from the parent AliasRelate goal.
|
||||||
|
if !self.is_normalizes_to_goal {
|
||||||
let num_non_region_vars = canonical.variables.iter().filter(|c| !c.is_region()).count();
|
let num_non_region_vars = canonical.variables.iter().filter(|c| !c.is_region()).count();
|
||||||
if num_non_region_vars > self.cx().recursion_limit() {
|
if num_non_region_vars > self.cx().recursion_limit() {
|
||||||
|
debug!(?num_non_region_vars, "too many inference variables -> overflow");
|
||||||
return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow {
|
return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow {
|
||||||
suggest_increasing_limit: true,
|
suggest_increasing_limit: true,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(canonical)
|
Ok(canonical)
|
||||||
}
|
}
|
||||||
|
@ -298,6 +298,7 @@ fn equate_impl_headers<'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The result of [fn impl_intersection_has_impossible_obligation].
|
/// The result of [fn impl_intersection_has_impossible_obligation].
|
||||||
|
#[derive(Debug)]
|
||||||
enum IntersectionHasImpossibleObligations<'tcx> {
|
enum IntersectionHasImpossibleObligations<'tcx> {
|
||||||
Yes,
|
Yes,
|
||||||
No {
|
No {
|
||||||
@ -328,6 +329,7 @@ enum IntersectionHasImpossibleObligations<'tcx> {
|
|||||||
/// of the two impls above to be empty.
|
/// of the two impls above to be empty.
|
||||||
///
|
///
|
||||||
/// Importantly, this works even if there isn't a `impl !Error for MyLocalType`.
|
/// Importantly, this works even if there isn't a `impl !Error for MyLocalType`.
|
||||||
|
#[instrument(level = "debug", skip(selcx), ret)]
|
||||||
fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>(
|
fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>(
|
||||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||||
obligations: &'a [PredicateObligation<'tcx>],
|
obligations: &'a [PredicateObligation<'tcx>],
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
// When canonicalizing a response in the trait solver, we bail with overflow
|
||||||
|
// if there are too many non-region inference variables. Doing so in normalizes-to
|
||||||
|
// goals ends up hiding inference constraints in cases which we want to support,
|
||||||
|
// see #131969. To prevent this issue we do not check for too many inference
|
||||||
|
// variables in normalizes-to goals.
|
||||||
|
#![recursion_limit = "8"]
|
||||||
|
|
||||||
|
trait Bound {}
|
||||||
|
trait Trait {
|
||||||
|
type Assoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<T0, T1, T2, T3, T4, T5, T6, T7> Trait for (T0, T1, T2, T3, T4, T5, T6, T7)
|
||||||
|
where
|
||||||
|
T0: Trait,
|
||||||
|
T1: Trait,
|
||||||
|
T2: Trait,
|
||||||
|
T3: Trait,
|
||||||
|
T4: Trait,
|
||||||
|
T5: Trait,
|
||||||
|
T6: Trait,
|
||||||
|
T7: Trait,
|
||||||
|
(
|
||||||
|
T0::Assoc,
|
||||||
|
T1::Assoc,
|
||||||
|
T2::Assoc,
|
||||||
|
T3::Assoc,
|
||||||
|
T4::Assoc,
|
||||||
|
T5::Assoc,
|
||||||
|
T6::Assoc,
|
||||||
|
T7::Assoc,
|
||||||
|
): Clone,
|
||||||
|
{
|
||||||
|
type Assoc = (
|
||||||
|
T0::Assoc,
|
||||||
|
T1::Assoc,
|
||||||
|
T2::Assoc,
|
||||||
|
T3::Assoc,
|
||||||
|
T4::Assoc,
|
||||||
|
T5::Assoc,
|
||||||
|
T6::Assoc,
|
||||||
|
T7::Assoc,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Overlap {}
|
||||||
|
impl<T: Trait<Assoc = ()>> Overlap for T {}
|
||||||
|
impl<T0, T1, T2, T3, T4, T5, T6, T7> Overlap for (T0, T1, T2, T3, T4, T5, T6, T7) {}
|
||||||
|
fn main() {}
|
@ -1,8 +1,5 @@
|
|||||||
//@ check-pass
|
//@ check-pass
|
||||||
//@ revisions: ai_current ai_next ia_current ia_next ii_current ii_next
|
//@ revisions: ai ia ii
|
||||||
//@[ai_next] compile-flags: -Znext-solver
|
|
||||||
//@[ia_next] compile-flags: -Znext-solver
|
|
||||||
//@[ii_next] compile-flags: -Znext-solver
|
|
||||||
|
|
||||||
// Regression test for nalgebra hang <https://github.com/rust-lang/rust/issues/130056>.
|
// Regression test for nalgebra hang <https://github.com/rust-lang/rust/issues/130056>.
|
||||||
|
|
||||||
@ -17,11 +14,11 @@ trait Trait {
|
|||||||
type Assoc: ?Sized;
|
type Assoc: ?Sized;
|
||||||
}
|
}
|
||||||
impl<T: ?Sized + Trait> Trait for W<T, T> {
|
impl<T: ?Sized + Trait> Trait for W<T, T> {
|
||||||
#[cfg(any(ai_current, ai_next))]
|
#[cfg(ai)]
|
||||||
type Assoc = W<T::Assoc, Id<T::Assoc>>;
|
type Assoc = W<T::Assoc, Id<T::Assoc>>;
|
||||||
#[cfg(any(ia_current, ia_next))]
|
#[cfg(ia)]
|
||||||
type Assoc = W<Id<T::Assoc>, T::Assoc>;
|
type Assoc = W<Id<T::Assoc>, T::Assoc>;
|
||||||
#[cfg(any(ii_current, ii_next))]
|
#[cfg(ii)]
|
||||||
type Assoc = W<Id<T::Assoc>, Id<T::Assoc>>;
|
type Assoc = W<Id<T::Assoc>, Id<T::Assoc>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user