From a62ecba1e7e698d792d836cb7445eacfd1a3bd58 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 8 Apr 2023 22:28:46 +0000 Subject: [PATCH 1/2] Detect cyclic subtype goals in new solver --- compiler/rustc_infer/src/infer/mod.rs | 2 +- compiler/rustc_middle/src/traits/solve.rs | 12 +++++++ .../src/solve/eval_ctxt.rs | 8 +++++ .../src/solve/eval_ctxt/canonical.rs | 31 ++++++++++++---- .../rustc_trait_selection/src/solve/mod.rs | 1 + tests/ui/traits/new-solver/cyclic-type.rs | 8 +++++ tests/ui/traits/new-solver/cyclic-type.stderr | 14 ++++++++ .../equating-projection-cyclically.stderr | 36 ++++++++++++++----- ...unnormalizable_candidate.self_infer.stderr | 8 ++--- 9 files changed, 99 insertions(+), 21 deletions(-) create mode 100644 tests/ui/traits/new-solver/cyclic-type.rs create mode 100644 tests/ui/traits/new-solver/cyclic-type.stderr diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index b4f2ad0bb3433..be7f287be9cef 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -199,7 +199,7 @@ impl<'tcx> InferCtxtInner<'tcx> { } #[inline] - fn type_variables(&mut self) -> type_variable::TypeVariableTable<'_, 'tcx> { + pub fn type_variables(&mut self) -> type_variable::TypeVariableTable<'_, 'tcx> { self.type_variable_storage.with_log(&mut self.undo_log) } diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs index fef2be133e81f..001c7028dc2bd 100644 --- a/compiler/rustc_middle/src/traits/solve.rs +++ b/compiler/rustc_middle/src/traits/solve.rs @@ -125,6 +125,7 @@ pub struct ExternalConstraintsData<'tcx> { // FIXME: implement this. pub region_constraints: QueryRegionConstraints<'tcx>, pub opaque_types: Vec<(Ty<'tcx>, Ty<'tcx>)>, + pub stalled_subtypes: Vec<(Ty<'tcx>, Ty<'tcx>)>, } // FIXME: Having to clone `region_constraints` for folding feels bad and @@ -144,6 +145,11 @@ impl<'tcx> TypeFoldable> for ExternalConstraints<'tcx> { .iter() .map(|opaque| opaque.try_fold_with(folder)) .collect::>()?, + stalled_subtypes: self + .stalled_subtypes + .iter() + .map(|subtype| subtype.try_fold_with(folder)) + .collect::>()?, })) } @@ -151,6 +157,11 @@ impl<'tcx> TypeFoldable> for ExternalConstraints<'tcx> { TypeFolder::interner(folder).mk_external_constraints(ExternalConstraintsData { region_constraints: self.region_constraints.clone().fold_with(folder), opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(), + stalled_subtypes: self + .stalled_subtypes + .iter() + .map(|subtype| subtype.fold_with(folder)) + .collect(), }) } } @@ -162,6 +173,7 @@ impl<'tcx> TypeVisitable> for ExternalConstraints<'tcx> { ) -> std::ops::ControlFlow { self.region_constraints.visit_with(visitor)?; self.opaque_types.visit_with(visitor)?; + self.stalled_subtypes.visit_with(visitor)?; ControlFlow::Continue(()) } } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index 28aca76cceb66..8303b90780576 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -57,6 +57,11 @@ pub struct EvalCtxt<'a, 'tcx> { pub(super) search_graph: &'a mut SearchGraph<'tcx>, pub(super) nested_goals: NestedGoals<'tcx>, + + // Subtyping predicates which have stalled. These are passed down in query + // responses to help detect cycle errors in cases where we're computing a + // goal like `?0 <: Box` when we already know that `?0 <: ?1`. + pub(super) stalled_subtypes: Vec<(Ty<'tcx>, Ty<'tcx>)>, } #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -121,6 +126,7 @@ impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> { max_input_universe: ty::UniverseIndex::ROOT, var_values: CanonicalVarValues::dummy(), nested_goals: NestedGoals::new(), + stalled_subtypes: vec![], }; let result = ecx.evaluate_goal(IsNormalizesToHack::No, goal); @@ -172,6 +178,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { max_input_universe: canonical_goal.max_universe, search_graph, nested_goals: NestedGoals::new(), + stalled_subtypes: vec![], }; ecx.compute_goal(goal) }) @@ -404,6 +411,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { max_input_universe: self.max_input_universe, search_graph: self.search_graph, nested_goals: self.nested_goals.clone(), + stalled_subtypes: self.stalled_subtypes.clone(), }; self.infcx.probe(|_| f(&mut ecx)) } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index 861fa0a305ac0..45cbaab818c73 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -16,7 +16,7 @@ use rustc_infer::infer::canonical::CanonicalVarValues; use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints}; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{ExternalConstraints, ExternalConstraintsData}; -use rustc_middle::ty::{self, GenericArgKind}; +use rustc_middle::ty::{self, GenericArgKind, Ty}; use rustc_span::DUMMY_SP; use std::iter; use std::ops::Deref; @@ -79,9 +79,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { ) }); let opaque_types = self.infcx.clone_opaque_types_for_query_response(); - Ok(self - .tcx() - .mk_external_constraints(ExternalConstraintsData { region_constraints, opaque_types })) + Ok(self.tcx().mk_external_constraints(ExternalConstraintsData { + region_constraints, + opaque_types, + stalled_subtypes: self.stalled_subtypes.clone(), + })) } /// After calling a canonical query, we apply the constraints returned @@ -102,12 +104,17 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { let Response { var_values, external_constraints, certainty } = response.substitute(self.tcx(), &substitution); - let nested_goals = self.unify_query_var_values(param_env, &original_values, var_values)?; - // FIXME: implement external constraints. - let ExternalConstraintsData { region_constraints, opaque_types: _ } = + let ExternalConstraintsData { region_constraints, stalled_subtypes, opaque_types: _ } = external_constraints.deref(); self.register_region_constraints(region_constraints); + assert!( + stalled_subtypes.is_empty() || certainty != Certainty::Yes, + "stalled_subtypes is non-empty: {stalled_subtypes:?}, but certainty is Yes" + ); + self.register_stalled_subtypes(stalled_subtypes); + + let nested_goals = self.unify_query_var_values(param_env, &original_values, var_values)?; Ok((certainty, nested_goals)) } @@ -227,4 +234,14 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { let _ = member_constraint; } } + + fn register_stalled_subtypes(&mut self, stalled_subtypes: &[(Ty<'tcx>, Ty<'tcx>)]) { + for (sub, sup) in stalled_subtypes { + if let ty::Infer(ty::TyVar(sub_vid)) = *self.infcx.shallow_resolve(*sub).kind() + && let ty::Infer(ty::TyVar(sup_vid)) = *self.infcx.shallow_resolve(*sup).kind() + { + self.infcx.inner.borrow_mut().type_variables().sub(sub_vid, sup_vid); + } + } + } } diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 19bcbd461447d..5ba66417c6691 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -105,6 +105,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { goal: Goal<'tcx, SubtypePredicate<'tcx>>, ) -> QueryResult<'tcx> { if goal.predicate.a.is_ty_var() && goal.predicate.b.is_ty_var() { + self.stalled_subtypes.push((goal.predicate.a, goal.predicate.b)); self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) } else { self.sub(goal.param_env, goal.predicate.a, goal.predicate.b)?; diff --git a/tests/ui/traits/new-solver/cyclic-type.rs b/tests/ui/traits/new-solver/cyclic-type.rs new file mode 100644 index 0000000000000..e4b6ae4efa0e7 --- /dev/null +++ b/tests/ui/traits/new-solver/cyclic-type.rs @@ -0,0 +1,8 @@ +// compile-flags: -Ztrait-solver=next + +fn main() { + let x; + x = Box::new(x); + //~^ ERROR mismatched types + //~| NOTE cyclic type of infinite size +} diff --git a/tests/ui/traits/new-solver/cyclic-type.stderr b/tests/ui/traits/new-solver/cyclic-type.stderr new file mode 100644 index 0000000000000..9931528db62c5 --- /dev/null +++ b/tests/ui/traits/new-solver/cyclic-type.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/cyclic-type.rs:5:9 + | +LL | x = Box::new(x); + | ^^^^^^^^^^^ cyclic type of infinite size + | +help: consider unboxing the value + | +LL | x = *Box::new(x); + | + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/new-solver/equating-projection-cyclically.stderr b/tests/ui/traits/new-solver/equating-projection-cyclically.stderr index 57cbc65a17a92..f03f6b4bf9003 100644 --- a/tests/ui/traits/new-solver/equating-projection-cyclically.stderr +++ b/tests/ui/traits/new-solver/equating-projection-cyclically.stderr @@ -1,14 +1,32 @@ -error[E0308]: mismatched types - --> $DIR/equating-projection-cyclically.rs:22:19 +error[E0055]: reached the recursion limit while auto-dereferencing `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<_ as Test>::Assoc as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target` + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`equating_projection_cyclically`) + +error[E0055]: reached the recursion limit while auto-dereferencing `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<_ as Test>::Assoc as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target` + --> $DIR/equating-projection-cyclically.rs:22:9 | LL | x = transform(x); - | ^ expected inferred type, found associated type + | ^^^^^^^^^^^^ deref recursion limit reached | - = note: expected type `_` - found associated type `<_ as Test>::Assoc` - = help: consider constraining the associated type `<_ as Test>::Assoc` to `_` - = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`equating_projection_cyclically`) + +error[E0055]: reached the recursion limit while auto-dereferencing `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<_ as Test>::Assoc as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target` + --> $DIR/equating-projection-cyclically.rs:22:9 + | +LL | x = transform(x); + | ^^^^^^^^^^^^ deref recursion limit reached + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`equating_projection_cyclically`) + +error[E0308]: mismatched types + --> $DIR/equating-projection-cyclically.rs:22:9 + | +LL | x = transform(x); + | ^^^^^^^^^^^^- help: try using a conversion method: `.to_string()` + | | + | cyclic type of infinite size -error: aborting due to previous error +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0055, E0308. +For more information about an error, try `rustc --explain E0055`. diff --git a/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr b/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr index 0628320126104..c685c38b9b34e 100644 --- a/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr +++ b/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr @@ -1,13 +1,13 @@ error[E0282]: type annotations needed - --> $DIR/normalizes_to_ignores_unnormalizable_candidate.rs:36:5 + --> $DIR/normalizes_to_ignores_unnormalizable_candidate.rs:36:9 | LL | foo(unconstrained()) - | ^^^ cannot infer type of the type parameter `T` declared on the function `foo` + | ^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `unconstrained` | help: consider specifying the generic argument | -LL | foo::(unconstrained()) - | +++++ +LL | foo(unconstrained::()) + | +++++ error: aborting due to previous error From f4c695ad5010708b5da4fb4f90152b6c27cb32ef Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 12 Apr 2023 03:22:15 +0000 Subject: [PATCH 2/2] Don't autoderef infinitely on ambiguity --- compiler/rustc_hir_analysis/src/autoderef.rs | 39 ++++++++++++++----- .../traits/new-solver/autoderef-infinite.rs | 8 ++++ .../new-solver/autoderef-infinite.stderr | 16 ++++++++ .../equating-projection-cyclically.stderr | 25 +----------- 4 files changed, 56 insertions(+), 32 deletions(-) create mode 100644 tests/ui/traits/new-solver/autoderef-infinite.rs create mode 100644 tests/ui/traits/new-solver/autoderef-infinite.stderr diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs index ba2d4319af6e2..fb1a02a799f64 100644 --- a/compiler/rustc_hir_analysis/src/autoderef.rs +++ b/compiler/rustc_hir_analysis/src/autoderef.rs @@ -2,6 +2,7 @@ use crate::errors::AutoDerefReachedRecursionLimit; use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::NormalizeExt; use crate::traits::{self, TraitEngine, TraitEngineExt}; +use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::InferCtxt; use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -138,14 +139,34 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { return None; } - let normalized_ty = self - .infcx - .at(&cause, self.param_env) - .normalize(tcx.mk_projection(tcx.lang_items().deref_target()?, trait_ref.substs)); - let mut fulfillcx = >::new_in_snapshot(tcx); - let normalized_ty = - normalized_ty.into_value_registering_obligations(self.infcx, &mut *fulfillcx); - let errors = fulfillcx.select_where_possible(&self.infcx); + let mut fulfill_cx = >::new_in_snapshot(tcx); + let normalized_ty = if tcx.trait_solver_next() { + let ty_var = self.infcx.next_ty_var(TypeVariableOrigin { + span: self.span, + kind: TypeVariableOriginKind::NormalizeProjectionType, + }); + fulfill_cx.register_predicate_obligation( + self.infcx, + traits::Obligation::new( + tcx, + cause.clone(), + self.param_env, + ty::Binder::dummy(ty::ProjectionPredicate { + projection_ty: tcx.mk_alias_ty(tcx.lang_items().deref_target()?, [ty]), + term: ty_var.into(), + }), + ), + ); + ty_var + } else { + let normalized_ty = self + .infcx + .at(&cause, self.param_env) + .normalize(tcx.mk_projection(tcx.lang_items().deref_target()?, trait_ref.substs)); + normalized_ty.into_value_registering_obligations(self.infcx, &mut *fulfill_cx) + }; + + let errors = fulfill_cx.select_where_possible(&self.infcx); 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 @@ -153,7 +174,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { debug!("overloaded_deref_ty: encountered errors {:?} while fulfilling", errors); return None; } - let obligations = fulfillcx.pending_obligations(); + let obligations = fulfill_cx.pending_obligations(); debug!("overloaded_deref_ty({:?}) = ({:?}, {:?})", ty, normalized_ty, obligations); self.state.obligations.extend(obligations); diff --git a/tests/ui/traits/new-solver/autoderef-infinite.rs b/tests/ui/traits/new-solver/autoderef-infinite.rs new file mode 100644 index 0000000000000..4caeb1d3546c1 --- /dev/null +++ b/tests/ui/traits/new-solver/autoderef-infinite.rs @@ -0,0 +1,8 @@ +// compile-flags: -Ztrait-solver=next + +fn main() { + let y = [Default::default()]; + y[0].method(); + //~^ ERROR type annotations needed + //~| ERROR no method named `method` found +} diff --git a/tests/ui/traits/new-solver/autoderef-infinite.stderr b/tests/ui/traits/new-solver/autoderef-infinite.stderr new file mode 100644 index 0000000000000..e226c882b4b8a --- /dev/null +++ b/tests/ui/traits/new-solver/autoderef-infinite.stderr @@ -0,0 +1,16 @@ +error[E0282]: type annotations needed + --> $DIR/autoderef-infinite.rs:5:10 + | +LL | y[0].method(); + | ^^^^^^ cannot infer type + +error[E0599]: no method named `method` found for associated type `>::Output` in the current scope + --> $DIR/autoderef-infinite.rs:5:10 + | +LL | y[0].method(); + | ^^^^^^ method not found in `>::Output` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0282, E0599. +For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/traits/new-solver/equating-projection-cyclically.stderr b/tests/ui/traits/new-solver/equating-projection-cyclically.stderr index f03f6b4bf9003..2a4ad39e1335e 100644 --- a/tests/ui/traits/new-solver/equating-projection-cyclically.stderr +++ b/tests/ui/traits/new-solver/equating-projection-cyclically.stderr @@ -1,23 +1,3 @@ -error[E0055]: reached the recursion limit while auto-dereferencing `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<_ as Test>::Assoc as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target` - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`equating_projection_cyclically`) - -error[E0055]: reached the recursion limit while auto-dereferencing `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<_ as Test>::Assoc as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target` - --> $DIR/equating-projection-cyclically.rs:22:9 - | -LL | x = transform(x); - | ^^^^^^^^^^^^ deref recursion limit reached - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`equating_projection_cyclically`) - -error[E0055]: reached the recursion limit while auto-dereferencing `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<_ as Test>::Assoc as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target as Deref>::Target` - --> $DIR/equating-projection-cyclically.rs:22:9 - | -LL | x = transform(x); - | ^^^^^^^^^^^^ deref recursion limit reached - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`equating_projection_cyclically`) - error[E0308]: mismatched types --> $DIR/equating-projection-cyclically.rs:22:9 | @@ -26,7 +6,6 @@ LL | x = transform(x); | | | cyclic type of infinite size -error: aborting due to 4 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0055, E0308. -For more information about an error, try `rustc --explain E0055`. +For more information about this error, try `rustc --explain E0308`.