FIXME(-Znext-solver) triage
Co-authored-by: Michael Goulet <michael@errs.io>
This commit is contained in:
@@ -141,8 +141,11 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
||||
}
|
||||
|
||||
if !tcx.recursion_limit().value_within_limit(iteration) {
|
||||
// This may actually be reachable. If so, we should convert
|
||||
// this to a proper error/consider whether we should detect
|
||||
// this somewhere else.
|
||||
bug!(
|
||||
"FIXME(-Znext-solver): Overflowed when processing region obligations: {outlives_predicates:#?}"
|
||||
"unexpected overflowed when processing region obligations: {outlives_predicates:#?}"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
|
||||
self.param_env,
|
||||
ty::Binder::dummy(trait_ref),
|
||||
);
|
||||
if !self.infcx.predicate_may_hold(&obligation) {
|
||||
if !self.infcx.next_trait_solver() && !self.infcx.predicate_may_hold(&obligation) {
|
||||
debug!("overloaded_deref_ty: cannot match obligation");
|
||||
return None;
|
||||
}
|
||||
@@ -184,17 +184,17 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
|
||||
self.param_env,
|
||||
ty,
|
||||
) else {
|
||||
// We shouldn't have errors here, except for evaluate/fulfill mismatches,
|
||||
// but that's not a reason for an ICE (`predicate_may_hold` is conservative
|
||||
// by design).
|
||||
// FIXME(-Znext-solver): This *actually* shouldn't happen then.
|
||||
// We shouldn't have errors here in the old solver, except for
|
||||
// evaluate/fulfill mismatches, but that's not a reason for an ICE.
|
||||
return None;
|
||||
};
|
||||
let errors = ocx.select_where_possible();
|
||||
if !errors.is_empty() {
|
||||
// This shouldn't happen, except for evaluate/fulfill mismatches,
|
||||
// but that's not a reason for an ICE (`predicate_may_hold` is conservative
|
||||
// by design).
|
||||
if self.infcx.next_trait_solver() {
|
||||
unreachable!();
|
||||
}
|
||||
// We shouldn't have errors here in the old solver, except for
|
||||
// evaluate/fulfill mismatches, but that's not a reason for an ICE.
|
||||
debug!(?errors, "encountered errors while fulfilling");
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -805,7 +805,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity })
|
||||
});
|
||||
let bound = (bound.upcast(tcx), span);
|
||||
// FIXME(-Znext-solver): We can likely remove this hack once the new trait solver lands.
|
||||
// FIXME(-Znext-solver): We can likely remove this hack once the
|
||||
// new trait solver lands. This fixed an overflow in the old solver.
|
||||
// This may have performance implications, so please check perf when
|
||||
// removing it.
|
||||
// This was added in <https://github.com/rust-lang/rust/pull/123302>.
|
||||
if tcx.is_lang_item(trait_def_id, rustc_hir::LangItem::Sized) {
|
||||
bounds.insert(0, bound);
|
||||
} else {
|
||||
|
||||
@@ -600,7 +600,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let (def_id, args) = match *expected_ty.kind() {
|
||||
// FIXME: Could also check that the RPIT is not defined
|
||||
ty::Alias(ty::Opaque, alias_ty) => (alias_ty.def_id.as_local()?, alias_ty.args),
|
||||
// FIXME(-Znext-solver): Remove this branch once `replace_opaque_types_with_infer` is gone.
|
||||
// FIXME(-Znext-solver=no): Remove this branch once `replace_opaque_types_with_infer` is gone.
|
||||
ty::Infer(ty::TyVar(_)) => self
|
||||
.inner
|
||||
.borrow_mut()
|
||||
|
||||
@@ -260,7 +260,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
mut expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
|
||||
allow_two_phase: AllowTwoPhase,
|
||||
) -> Result<Ty<'tcx>, Diag<'a>> {
|
||||
let expected = self.resolve_vars_with_obligations(expected);
|
||||
let expected = if self.next_trait_solver() {
|
||||
expected
|
||||
} else {
|
||||
self.resolve_vars_with_obligations(expected)
|
||||
};
|
||||
|
||||
let e = match self.coerce(expr, checked_ty, expected, allow_two_phase, None) {
|
||||
Ok(ty) => return Ok(ty),
|
||||
|
||||
@@ -1436,8 +1436,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
/// in this case.
|
||||
#[instrument(level = "debug", skip(self, sp), ret)]
|
||||
pub(crate) fn try_structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
let ty = self.resolve_vars_with_obligations(ty);
|
||||
|
||||
if self.next_trait_solver()
|
||||
&& let ty::Alias(..) = ty.kind()
|
||||
{
|
||||
@@ -1455,7 +1453,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ty
|
||||
self.resolve_vars_with_obligations(ty)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -412,9 +412,10 @@ pub(crate) struct LoweredTy<'tcx> {
|
||||
|
||||
impl<'tcx> LoweredTy<'tcx> {
|
||||
fn from_raw(fcx: &FnCtxt<'_, 'tcx>, span: Span, raw: Ty<'tcx>) -> LoweredTy<'tcx> {
|
||||
// FIXME(-Znext-solver): We're still figuring out how to best handle
|
||||
// normalization and this doesn't feel too great. We should look at this
|
||||
// code again before stabilizing it.
|
||||
// FIXME(-Znext-solver=no): This is easier than requiring all uses of `LoweredTy`
|
||||
// to call `try_structurally_resolve_type` instead. This seems like a lot of
|
||||
// effort, especially as we're still supporting the old solver. We may revisit
|
||||
// this in the future.
|
||||
let normalized = if fcx.next_trait_solver() {
|
||||
fcx.try_structurally_resolve_type(span, raw)
|
||||
} else {
|
||||
|
||||
@@ -1913,8 +1913,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
ty::Binder::dummy(trait_ref),
|
||||
);
|
||||
|
||||
// FIXME(-Znext-solver): We only need this hack to deal with fatal
|
||||
// overflow in the old solver.
|
||||
// We only need this hack to deal with fatal overflow in the old solver.
|
||||
if self.infcx.next_trait_solver() || self.infcx.predicate_may_hold(&obligation)
|
||||
{
|
||||
ocx.register_obligation(obligation);
|
||||
@@ -1955,17 +1954,17 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(-Znext-solver): See the linked issue below.
|
||||
// <https://github.com/rust-lang/trait-system-refactor-initiative/issues/134>
|
||||
// See <https://github.com/rust-lang/trait-system-refactor-initiative/issues/134>.
|
||||
//
|
||||
// In the new solver, check the well-formedness of the return type.
|
||||
// This emulates, in a way, the predicates that fall out of
|
||||
// normalizing the return type in the old solver.
|
||||
//
|
||||
// We alternatively could check the predicates of the method itself hold,
|
||||
// but we intentionally do not do this in the old solver b/c of cycles,
|
||||
// and doing it in the new solver would be stronger. This should be fixed
|
||||
// in the future, since it likely leads to much better method winnowing.
|
||||
// FIXME(-Znext-solver): We alternatively could check the predicates of
|
||||
// the method itself hold, but we intentionally do not do this in the old
|
||||
// solver b/c of cycles, and doing it in the new solver would be stronger.
|
||||
// This should be fixed in the future, since it likely leads to much better
|
||||
// method winnowing.
|
||||
if let Some(xform_ret_ty) = xform_ret_ty
|
||||
&& self.infcx.next_trait_solver()
|
||||
{
|
||||
|
||||
@@ -198,8 +198,11 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
}
|
||||
|
||||
if !self.tcx.recursion_limit().value_within_limit(iteration) {
|
||||
// This may actually be reachable. If so, we should convert
|
||||
// this to a proper error/consider whether we should detect
|
||||
// this somewhere else.
|
||||
bug!(
|
||||
"FIXME(-Znext-solver): Overflowed when processing region obligations: {my_region_obligations:#?}"
|
||||
"unexpected overflowed when processing region obligations: {my_region_obligations:#?}"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -86,6 +86,10 @@ use crate::ty::{
|
||||
|
||||
#[allow(rustc::usage_of_ty_tykind)]
|
||||
impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||
fn next_trait_solver_globally(self) -> bool {
|
||||
self.next_trait_solver_globally()
|
||||
}
|
||||
|
||||
type DefId = DefId;
|
||||
type LocalDefId = LocalDefId;
|
||||
type Span = Span;
|
||||
|
||||
@@ -138,7 +138,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>(
|
||||
}
|
||||
false
|
||||
}
|
||||
// FIXME(-Znext-solver): Remove this hack when trait solver overflow can return an error.
|
||||
// FIXME(-Znext-solver=no): Remove this hack when trait solver overflow can return an error.
|
||||
// In code like that pointed out in #128887, the type complexity we ask the solver to deal with
|
||||
// grows as we recurse into the call graph. If we use the same recursion limit here and in the
|
||||
// solver, the solver hits the limit first and emits a fatal error. But if we use a reduced
|
||||
|
||||
@@ -237,8 +237,8 @@ where
|
||||
return None;
|
||||
}
|
||||
|
||||
// FIXME(-Znext-solver): We should instead try to find a `Certainty::Yes` response with
|
||||
// a subset of the constraints that all the other responses have.
|
||||
// FIXME(-Znext-solver): Add support to merge region constraints in
|
||||
// responses to deal with trait-system-refactor-initiative#27.
|
||||
let one = responses[0];
|
||||
if responses[1..].iter().all(|&resp| resp == one) {
|
||||
return Some(one);
|
||||
|
||||
@@ -41,6 +41,9 @@ where
|
||||
// and we tag the impl bounds with `GoalSource::ImplWhereBound`?
|
||||
// Right now this includes both the impl and the assoc item where bounds,
|
||||
// and I don't think the assoc item where-bounds are allowed to be coinductive.
|
||||
//
|
||||
// Projecting to the IAT also "steps out the impl contructor", so we would have
|
||||
// to be very careful when changing the impl where-clauses to be productive.
|
||||
self.add_goals(
|
||||
GoalSource::Misc,
|
||||
cx.predicates_of(inherent.def_id)
|
||||
|
||||
@@ -235,7 +235,11 @@ where
|
||||
.predicates_of(goal.predicate.def_id())
|
||||
.iter_instantiated(cx, goal.predicate.trait_ref.args)
|
||||
.map(|p| goal.with(cx, p));
|
||||
// FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`?
|
||||
// While you could think of trait aliases to have a single builtin impl
|
||||
// which uses its implied trait bounds as where-clauses, using
|
||||
// `GoalSource::ImplWhereClause` here would be incorrect, as we also
|
||||
// impl them, which means we're "stepping out of the impl constructor"
|
||||
// again. To handle this, we treat these cycles as ambiguous for now.
|
||||
ecx.add_goals(GoalSource::Misc, nested_obligations);
|
||||
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
})
|
||||
|
||||
@@ -47,7 +47,7 @@ impl<'tcx> At<'_, 'tcx> {
|
||||
/// same goals in both a temporary and the shared context which negatively impacts
|
||||
/// performance as these don't share caching.
|
||||
///
|
||||
/// FIXME(-Znext-solver): For performance reasons, we currently reuse an existing
|
||||
/// FIXME(-Znext-solver=no): For performance reasons, we currently reuse an existing
|
||||
/// fulfillment context in the old solver. Once we have removed the old solver, we
|
||||
/// can remove the `fulfill_cx` parameter on this function.
|
||||
fn deeply_normalize<T, E>(
|
||||
|
||||
@@ -58,7 +58,6 @@ pub(crate) fn codegen_select_candidate<'tcx>(
|
||||
// Currently, we use a fulfillment context to completely resolve
|
||||
// all nested obligations. This is because they can inform the
|
||||
// inference of the impl's type parameters.
|
||||
// FIXME(-Znext-solver): Doesn't need diagnostics if new solver.
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
let impl_source = selection.map(|obligation| {
|
||||
ocx.register_obligation(obligation);
|
||||
|
||||
@@ -84,6 +84,9 @@ pub enum TreatParams {
|
||||
///
|
||||
/// This also treats projections with inference variables as infer vars
|
||||
/// since they could be further normalized.
|
||||
// FIXME(@lcnr): This treats aliases as rigid. This is only correct if the
|
||||
// type has been structurally normalized. We should reflect this requirement
|
||||
// in the variant name. It is currently incorrectly used in diagnostics.
|
||||
AsRigid,
|
||||
}
|
||||
|
||||
@@ -151,9 +154,11 @@ pub fn simplify_type<I: Interner>(
|
||||
ty::Alias(..) => match treat_params {
|
||||
// When treating `ty::Param` as a placeholder, projections also
|
||||
// don't unify with anything else as long as they are fully normalized.
|
||||
// FIXME(-Znext-solver): Can remove this `if` and always simplify to `Placeholder`
|
||||
// when the new solver is enabled by default.
|
||||
TreatParams::AsRigid if !ty.has_non_region_infer() => Some(SimplifiedType::Placeholder),
|
||||
TreatParams::AsRigid
|
||||
if !ty.has_non_region_infer() || cx.next_trait_solver_globally() =>
|
||||
{
|
||||
Some(SimplifiedType::Placeholder)
|
||||
}
|
||||
TreatParams::AsRigid | TreatParams::InstantiateWithInfer => None,
|
||||
},
|
||||
ty::Foreign(def_id) => Some(SimplifiedType::Foreign(def_id)),
|
||||
|
||||
@@ -33,6 +33,10 @@ pub trait Interner:
|
||||
+ IrPrint<ty::FnSig<Self>>
|
||||
+ IrPrint<ty::PatternKind<Self>>
|
||||
{
|
||||
fn next_trait_solver_globally(self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
type DefId: DefId<Self>;
|
||||
type LocalDefId: Copy + Debug + Hash + Eq + Into<Self::DefId> + TypeFoldable<Self>;
|
||||
type Span: Span<Self>;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/recursive-coroutine-boxed.rs:14:23
|
||||
--> $DIR/recursive-coroutine-boxed.rs:11:23
|
||||
|
|
||||
LL | let mut gen = Box::pin(foo());
|
||||
| ^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Box`
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
use std::ops::{Coroutine, CoroutineState};
|
||||
|
||||
fn foo() -> impl Coroutine<Yield = (), Return = ()> {
|
||||
// FIXME(-Znext-solver): this fails with a mismatched types as the
|
||||
// hidden type of the opaque ends up as {type error}. We should not
|
||||
// emit errors for such goals.
|
||||
#[coroutine] || {
|
||||
let mut gen = Box::pin(foo());
|
||||
//[next]~^ ERROR type annotations needed
|
||||
|
||||
Reference in New Issue
Block a user