1
Fork 0

Pass spans around new solver

This commit is contained in:
Michael Goulet 2025-02-05 18:32:06 +00:00
parent fd1110ce6a
commit 4e763c2297
16 changed files with 137 additions and 55 deletions

View file

@ -137,6 +137,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
expected, expected,
ty::Contravariant, ty::Contravariant,
actual, actual,
self.cause.span,
) )
.map(|goals| self.goals_to_obligations(goals)) .map(|goals| self.goals_to_obligations(goals))
} else { } else {
@ -163,8 +164,15 @@ impl<'a, 'tcx> At<'a, 'tcx> {
T: ToTrace<'tcx>, T: ToTrace<'tcx>,
{ {
if self.infcx.next_trait_solver { if self.infcx.next_trait_solver {
NextSolverRelate::relate(self.infcx, self.param_env, expected, ty::Covariant, actual) NextSolverRelate::relate(
.map(|goals| self.goals_to_obligations(goals)) self.infcx,
self.param_env,
expected,
ty::Covariant,
actual,
self.cause.span,
)
.map(|goals| self.goals_to_obligations(goals))
} else { } else {
let mut op = TypeRelating::new( let mut op = TypeRelating::new(
self.infcx, self.infcx,
@ -208,8 +216,15 @@ impl<'a, 'tcx> At<'a, 'tcx> {
T: Relate<TyCtxt<'tcx>>, T: Relate<TyCtxt<'tcx>>,
{ {
if self.infcx.next_trait_solver { if self.infcx.next_trait_solver {
NextSolverRelate::relate(self.infcx, self.param_env, expected, ty::Invariant, actual) NextSolverRelate::relate(
.map(|goals| self.goals_to_obligations(goals)) self.infcx,
self.param_env,
expected,
ty::Invariant,
actual,
self.cause.span,
)
.map(|goals| self.goals_to_obligations(goals))
} else { } else {
let mut op = TypeRelating::new( let mut op = TypeRelating::new(
self.infcx, self.infcx,

View file

@ -5,7 +5,7 @@ use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::relate::RelateResult; use rustc_middle::ty::relate::RelateResult;
use rustc_middle::ty::relate::combine::PredicateEmittingRelation; use rustc_middle::ty::relate::combine::PredicateEmittingRelation;
use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::{DUMMY_SP, ErrorGuaranteed}; use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
use super::{BoundRegionConversionTime, InferCtxt, RegionVariableOrigin, SubregionOrigin}; use super::{BoundRegionConversionTime, InferCtxt, RegionVariableOrigin, SubregionOrigin};
@ -203,23 +203,23 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
self.probe(|_| probe()) self.probe(|_| probe())
} }
fn sub_regions(&self, sub: ty::Region<'tcx>, sup: ty::Region<'tcx>) { fn sub_regions(&self, sub: ty::Region<'tcx>, sup: ty::Region<'tcx>, span: Span) {
self.inner.borrow_mut().unwrap_region_constraints().make_subregion( self.inner.borrow_mut().unwrap_region_constraints().make_subregion(
SubregionOrigin::RelateRegionParamBound(DUMMY_SP, None), SubregionOrigin::RelateRegionParamBound(span, None),
sub, sub,
sup, sup,
); );
} }
fn equate_regions(&self, a: ty::Region<'tcx>, b: ty::Region<'tcx>) { fn equate_regions(&self, a: ty::Region<'tcx>, b: ty::Region<'tcx>, span: Span) {
self.inner.borrow_mut().unwrap_region_constraints().make_eqregion( self.inner.borrow_mut().unwrap_region_constraints().make_eqregion(
SubregionOrigin::RelateRegionParamBound(DUMMY_SP, None), SubregionOrigin::RelateRegionParamBound(span, None),
a, a,
b, b,
); );
} }
fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>) { fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>, span: Span) {
self.register_region_obligation_with_cause(ty, r, &ObligationCause::dummy()); self.register_region_obligation_with_cause(ty, r, &ObligationCause::dummy_with_span(span));
} }
} }

View file

@ -4,8 +4,8 @@ use rustc_type_ir::fold::TypeFoldable;
use rustc_type_ir::solve::{Certainty, Goal, NoSolution}; use rustc_type_ir::solve::{Certainty, Goal, NoSolution};
use rustc_type_ir::{self as ty, InferCtxtLike, Interner}; use rustc_type_ir::{self as ty, InferCtxtLike, Interner};
pub trait SolverDelegate: Deref<Target = <Self as SolverDelegate>::Infcx> + Sized { pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
type Infcx: InferCtxtLike<Interner = <Self as SolverDelegate>::Interner>; type Infcx: InferCtxtLike<Interner = Self::Interner>;
type Interner: Interner; type Interner: Interner;
fn cx(&self) -> Self::Interner { fn cx(&self) -> Self::Interner {
(**self).cx() (**self).cx()
@ -59,6 +59,7 @@ pub trait SolverDelegate: Deref<Target = <Self as SolverDelegate>::Infcx> + Size
fn instantiate_canonical_var_with_infer( fn instantiate_canonical_var_with_infer(
&self, &self,
cv_info: ty::CanonicalVarInfo<Self::Interner>, cv_info: ty::CanonicalVarInfo<Self::Interner>,
span: <Self::Interner as Interner>::Span,
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex, universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
) -> <Self::Interner as Interner>::GenericArg; ) -> <Self::Interner as Interner>::GenericArg;
@ -84,6 +85,7 @@ pub trait SolverDelegate: Deref<Target = <Self as SolverDelegate>::Infcx> + Size
&self, &self,
key: ty::OpaqueTypeKey<Self::Interner>, key: ty::OpaqueTypeKey<Self::Interner>,
hidden_ty: <Self::Interner as Interner>::Ty, hidden_ty: <Self::Interner as Interner>::Ty,
span: <Self::Interner as Interner>::Span,
); );
fn reset_opaque_types(&self); fn reset_opaque_types(&self);

View file

@ -255,20 +255,29 @@ where
self.delegate, self.delegate,
&original_values, &original_values,
&response, &response,
self.origin_span,
); );
let Response { var_values, external_constraints, certainty } = let Response { var_values, external_constraints, certainty } =
self.delegate.instantiate_canonical(response, instantiation); self.delegate.instantiate_canonical(response, instantiation);
Self::unify_query_var_values(self.delegate, param_env, &original_values, var_values); Self::unify_query_var_values(
self.delegate,
param_env,
&original_values,
var_values,
self.origin_span,
);
let ExternalConstraintsData { let ExternalConstraintsData {
region_constraints, region_constraints,
opaque_types, opaque_types,
normalization_nested_goals, normalization_nested_goals,
} = &*external_constraints; } = &*external_constraints;
self.register_region_constraints(region_constraints); self.register_region_constraints(region_constraints);
self.register_new_opaque_types(opaque_types); self.register_new_opaque_types(opaque_types);
(normalization_nested_goals.clone(), certainty) (normalization_nested_goals.clone(), certainty)
} }
@ -279,6 +288,7 @@ where
delegate: &D, delegate: &D,
original_values: &[I::GenericArg], original_values: &[I::GenericArg],
response: &Canonical<I, T>, response: &Canonical<I, T>,
span: I::Span,
) -> CanonicalVarValues<I> { ) -> CanonicalVarValues<I> {
// FIXME: Longterm canonical queries should deal with all placeholders // FIXME: Longterm canonical queries should deal with all placeholders
// created inside of the query directly instead of returning them to the // created inside of the query directly instead of returning them to the
@ -331,7 +341,7 @@ where
// A variable from inside a binder of the query. While ideally these shouldn't // A variable from inside a binder of the query. While ideally these shouldn't
// exist at all (see the FIXME at the start of this method), we have to deal with // exist at all (see the FIXME at the start of this method), we have to deal with
// them for now. // them for now.
delegate.instantiate_canonical_var_with_infer(info, |idx| { delegate.instantiate_canonical_var_with_infer(info, span, |idx| {
ty::UniverseIndex::from(prev_universe.index() + idx.index()) ty::UniverseIndex::from(prev_universe.index() + idx.index())
}) })
} else if info.is_existential() { } else if info.is_existential() {
@ -345,7 +355,7 @@ where
if let Some(v) = opt_values[ty::BoundVar::from_usize(index)] { if let Some(v) = opt_values[ty::BoundVar::from_usize(index)] {
v v
} else { } else {
delegate.instantiate_canonical_var_with_infer(info, |_| prev_universe) delegate.instantiate_canonical_var_with_infer(info, span, |_| prev_universe)
} }
} else { } else {
// For placeholders which were already part of the input, we simply map this // For placeholders which were already part of the input, we simply map this
@ -376,12 +386,13 @@ where
param_env: I::ParamEnv, param_env: I::ParamEnv,
original_values: &[I::GenericArg], original_values: &[I::GenericArg],
var_values: CanonicalVarValues<I>, var_values: CanonicalVarValues<I>,
span: I::Span,
) { ) {
assert_eq!(original_values.len(), var_values.len()); assert_eq!(original_values.len(), var_values.len());
for (&orig, response) in iter::zip(original_values, var_values.var_values.iter()) { for (&orig, response) in iter::zip(original_values, var_values.var_values.iter()) {
let goals = let goals =
delegate.eq_structurally_relating_aliases(param_env, orig, response).unwrap(); delegate.eq_structurally_relating_aliases(param_env, orig, response, span).unwrap();
assert!(goals.is_empty()); assert!(goals.is_empty());
} }
} }
@ -401,7 +412,7 @@ where
fn register_new_opaque_types(&mut self, opaque_types: &[(ty::OpaqueTypeKey<I>, I::Ty)]) { fn register_new_opaque_types(&mut self, opaque_types: &[(ty::OpaqueTypeKey<I>, I::Ty)]) {
for &(key, ty) in opaque_types { for &(key, ty) in opaque_types {
self.delegate.inject_new_hidden_type_unchecked(key, ty); self.delegate.inject_new_hidden_type_unchecked(key, ty, self.origin_span);
} }
} }
} }
@ -451,10 +462,10 @@ where
} }
let instantiation = let instantiation =
EvalCtxt::compute_query_response_instantiation_values(delegate, orig_values, &state); EvalCtxt::compute_query_response_instantiation_values(delegate, orig_values, &state, span);
let inspect::State { var_values, data } = delegate.instantiate_canonical(state, instantiation); let inspect::State { var_values, data } = delegate.instantiate_canonical(state, instantiation);
EvalCtxt::unify_query_var_values(delegate, param_env, orig_values, var_values); EvalCtxt::unify_query_var_values(delegate, param_env, orig_values, var_values, span);
data data
} }

View file

@ -78,6 +78,8 @@ where
nested_goals: NestedGoals<I>, nested_goals: NestedGoals<I>,
pub(super) origin_span: I::Span,
// Has this `EvalCtxt` errored out with `NoSolution` in `try_evaluate_added_goals`? // Has this `EvalCtxt` errored out with `NoSolution` in `try_evaluate_added_goals`?
// //
// If so, then it can no longer be used to make a canonical query response, // If so, then it can no longer be used to make a canonical query response,
@ -134,6 +136,7 @@ pub trait SolverDelegateEvalExt: SolverDelegate {
&self, &self,
goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>, goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
generate_proof_tree: GenerateProofTree, generate_proof_tree: GenerateProofTree,
span: <Self::Interner as Interner>::Span,
) -> ( ) -> (
Result<(HasChanged, Certainty), NoSolution>, Result<(HasChanged, Certainty), NoSolution>,
Option<inspect::GoalEvaluation<Self::Interner>>, Option<inspect::GoalEvaluation<Self::Interner>>,
@ -174,8 +177,9 @@ where
&self, &self,
goal: Goal<I, I::Predicate>, goal: Goal<I, I::Predicate>,
generate_proof_tree: GenerateProofTree, generate_proof_tree: GenerateProofTree,
span: I::Span,
) -> (Result<(HasChanged, Certainty), NoSolution>, Option<inspect::GoalEvaluation<I>>) { ) -> (Result<(HasChanged, Certainty), NoSolution>, Option<inspect::GoalEvaluation<I>>) {
EvalCtxt::enter_root(self, self.cx().recursion_limit(), generate_proof_tree, |ecx| { EvalCtxt::enter_root(self, self.cx().recursion_limit(), generate_proof_tree, span, |ecx| {
ecx.evaluate_goal(GoalEvaluationKind::Root, GoalSource::Misc, goal) ecx.evaluate_goal(GoalEvaluationKind::Root, GoalSource::Misc, goal)
}) })
} }
@ -186,7 +190,7 @@ where
goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>, goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
) -> bool { ) -> bool {
self.probe(|| { self.probe(|| {
EvalCtxt::enter_root(self, root_depth, GenerateProofTree::No, |ecx| { EvalCtxt::enter_root(self, root_depth, GenerateProofTree::No, I::Span::dummy(), |ecx| {
ecx.evaluate_goal(GoalEvaluationKind::Root, GoalSource::Misc, goal) ecx.evaluate_goal(GoalEvaluationKind::Root, GoalSource::Misc, goal)
}) })
.0 .0
@ -203,9 +207,13 @@ where
Result<(NestedNormalizationGoals<I>, HasChanged, Certainty), NoSolution>, Result<(NestedNormalizationGoals<I>, HasChanged, Certainty), NoSolution>,
Option<inspect::GoalEvaluation<I>>, Option<inspect::GoalEvaluation<I>>,
) { ) {
EvalCtxt::enter_root(self, self.cx().recursion_limit(), generate_proof_tree, |ecx| { EvalCtxt::enter_root(
ecx.evaluate_goal_raw(GoalEvaluationKind::Root, GoalSource::Misc, goal) self,
}) self.cx().recursion_limit(),
generate_proof_tree,
I::Span::dummy(),
|ecx| ecx.evaluate_goal_raw(GoalEvaluationKind::Root, GoalSource::Misc, goal),
)
} }
} }
@ -229,6 +237,7 @@ where
delegate: &D, delegate: &D,
root_depth: usize, root_depth: usize,
generate_proof_tree: GenerateProofTree, generate_proof_tree: GenerateProofTree,
origin_span: I::Span,
f: impl FnOnce(&mut EvalCtxt<'_, D>) -> R, f: impl FnOnce(&mut EvalCtxt<'_, D>) -> R,
) -> (R, Option<inspect::GoalEvaluation<I>>) { ) -> (R, Option<inspect::GoalEvaluation<I>>) {
let mut search_graph = SearchGraph::new(root_depth); let mut search_graph = SearchGraph::new(root_depth);
@ -248,6 +257,7 @@ where
variables: Default::default(), variables: Default::default(),
var_values: CanonicalVarValues::dummy(), var_values: CanonicalVarValues::dummy(),
is_normalizes_to_goal: false, is_normalizes_to_goal: false,
origin_span,
tainted: Ok(()), tainted: Ok(()),
}; };
let result = f(&mut ecx); let result = f(&mut ecx);
@ -289,12 +299,13 @@ where
max_input_universe: canonical_input.canonical.max_universe, max_input_universe: canonical_input.canonical.max_universe,
search_graph, search_graph,
nested_goals: NestedGoals::new(), nested_goals: NestedGoals::new(),
origin_span: I::Span::dummy(),
tainted: Ok(()), tainted: Ok(()),
inspect: canonical_goal_evaluation.new_goal_evaluation_step(var_values), inspect: canonical_goal_evaluation.new_goal_evaluation_step(var_values),
}; };
for &(key, ty) in &input.predefined_opaques_in_body.opaque_types { for &(key, ty) in &input.predefined_opaques_in_body.opaque_types {
ecx.delegate.inject_new_hidden_type_unchecked(key, ty); ecx.delegate.inject_new_hidden_type_unchecked(key, ty, ecx.origin_span);
} }
if !ecx.nested_goals.is_empty() { if !ecx.nested_goals.is_empty() {
@ -822,8 +833,12 @@ where
let identity_args = self.fresh_args_for_item(alias.def_id); let identity_args = self.fresh_args_for_item(alias.def_id);
let rigid_ctor = ty::AliasTerm::new_from_args(cx, alias.def_id, identity_args); let rigid_ctor = ty::AliasTerm::new_from_args(cx, alias.def_id, identity_args);
let ctor_term = rigid_ctor.to_term(cx); let ctor_term = rigid_ctor.to_term(cx);
let obligations = let obligations = self.delegate.eq_structurally_relating_aliases(
self.delegate.eq_structurally_relating_aliases(param_env, term, ctor_term)?; param_env,
term,
ctor_term,
self.origin_span,
)?;
debug_assert!(obligations.is_empty()); debug_assert!(obligations.is_empty());
self.relate(param_env, alias, variance, rigid_ctor) self.relate(param_env, alias, variance, rigid_ctor)
} else { } else {
@ -841,7 +856,12 @@ where
lhs: T, lhs: T,
rhs: T, rhs: T,
) -> Result<(), NoSolution> { ) -> Result<(), NoSolution> {
let result = self.delegate.eq_structurally_relating_aliases(param_env, lhs, rhs)?; let result = self.delegate.eq_structurally_relating_aliases(
param_env,
lhs,
rhs,
self.origin_span,
)?;
assert_eq!(result, vec![]); assert_eq!(result, vec![]);
Ok(()) Ok(())
} }
@ -864,7 +884,7 @@ where
variance: ty::Variance, variance: ty::Variance,
rhs: T, rhs: T,
) -> Result<(), NoSolution> { ) -> Result<(), NoSolution> {
let goals = self.delegate.relate(param_env, lhs, variance, rhs)?; let goals = self.delegate.relate(param_env, lhs, variance, rhs, self.origin_span)?;
self.add_goals(GoalSource::Misc, goals); self.add_goals(GoalSource::Misc, goals);
Ok(()) Ok(())
} }
@ -881,7 +901,7 @@ where
lhs: T, lhs: T,
rhs: T, rhs: T,
) -> Result<Vec<Goal<I, I::Predicate>>, NoSolution> { ) -> Result<Vec<Goal<I, I::Predicate>>, NoSolution> {
Ok(self.delegate.relate(param_env, lhs, ty::Variance::Invariant, rhs)?) Ok(self.delegate.relate(param_env, lhs, ty::Variance::Invariant, rhs, self.origin_span)?)
} }
pub(super) fn instantiate_binder_with_infer<T: TypeFoldable<I> + Copy>( pub(super) fn instantiate_binder_with_infer<T: TypeFoldable<I> + Copy>(
@ -917,12 +937,12 @@ where
} }
pub(super) fn register_ty_outlives(&self, ty: I::Ty, lt: I::Region) { pub(super) fn register_ty_outlives(&self, ty: I::Ty, lt: I::Region) {
self.delegate.register_ty_outlives(ty, lt); self.delegate.register_ty_outlives(ty, lt, self.origin_span);
} }
pub(super) fn register_region_outlives(&self, a: I::Region, b: I::Region) { pub(super) fn register_region_outlives(&self, a: I::Region, b: I::Region) {
// `b : a` ==> `a <= b` // `b : a` ==> `a <= b`
self.delegate.sub_regions(b, a); self.delegate.sub_regions(b, a, self.origin_span);
} }
/// Computes the list of goals required for `arg` to be well-formed /// Computes the list of goals required for `arg` to be well-formed

View file

@ -39,6 +39,7 @@ where
max_input_universe, max_input_universe,
search_graph: outer_ecx.search_graph, search_graph: outer_ecx.search_graph,
nested_goals: outer_ecx.nested_goals.clone(), nested_goals: outer_ecx.nested_goals.clone(),
origin_span: outer_ecx.origin_span,
tainted: outer_ecx.tainted, tainted: outer_ecx.tainted,
inspect: outer_ecx.inspect.take_and_enter_probe(), inspect: outer_ecx.inspect.take_and_enter_probe(),
}; };

View file

@ -145,9 +145,10 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
fn instantiate_canonical_var_with_infer( fn instantiate_canonical_var_with_infer(
&self, &self,
cv_info: CanonicalVarInfo<'tcx>, cv_info: CanonicalVarInfo<'tcx>,
span: Span,
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex, universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
) -> ty::GenericArg<'tcx> { ) -> ty::GenericArg<'tcx> {
self.0.instantiate_canonical_var(DUMMY_SP, cv_info, universe_map) self.0.instantiate_canonical_var(span, cv_info, universe_map)
} }
fn insert_hidden_type( fn insert_hidden_type(
@ -173,11 +174,13 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
self.0.add_item_bounds_for_hidden_type(def_id, args, param_env, hidden_ty, goals); self.0.add_item_bounds_for_hidden_type(def_id, args, param_env, hidden_ty, goals);
} }
fn inject_new_hidden_type_unchecked(&self, key: ty::OpaqueTypeKey<'tcx>, hidden_ty: Ty<'tcx>) { fn inject_new_hidden_type_unchecked(
self.0.inject_new_hidden_type_unchecked(key, ty::OpaqueHiddenType { &self,
ty: hidden_ty, key: ty::OpaqueTypeKey<'tcx>,
span: DUMMY_SP, hidden_ty: Ty<'tcx>,
}) span: Span,
) {
self.0.inject_new_hidden_type_unchecked(key, ty::OpaqueHiddenType { ty: hidden_ty, span })
} }
fn reset_opaque_types(&self) { fn reset_opaque_types(&self) {

View file

@ -82,7 +82,7 @@ impl<'tcx> ObligationStorage<'tcx> {
self.overflowed.extend(ExtractIf::new(&mut self.pending, |o| { self.overflowed.extend(ExtractIf::new(&mut self.pending, |o| {
let goal = o.clone().into(); let goal = o.clone().into();
let result = <&SolverDelegate<'tcx>>::from(infcx) let result = <&SolverDelegate<'tcx>>::from(infcx)
.evaluate_root_goal(goal, GenerateProofTree::No) .evaluate_root_goal(goal, GenerateProofTree::No, o.cause.span)
.0; .0;
matches!(result, Ok((HasChanged::Yes, _))) matches!(result, Ok((HasChanged::Yes, _)))
})); }));
@ -163,7 +163,7 @@ where
for obligation in self.obligations.unstalled_for_select() { for obligation in self.obligations.unstalled_for_select() {
let goal = obligation.clone().into(); let goal = obligation.clone().into();
let result = <&SolverDelegate<'tcx>>::from(infcx) let result = <&SolverDelegate<'tcx>>::from(infcx)
.evaluate_root_goal(goal, GenerateProofTree::No) .evaluate_root_goal(goal, GenerateProofTree::No, obligation.cause.span)
.0; .0;
self.inspect_evaluated_obligation(infcx, &obligation, &result); self.inspect_evaluated_obligation(infcx, &obligation, &result);
let (changed, certainty) = match result { let (changed, certainty) = match result {

View file

@ -88,7 +88,11 @@ pub(super) fn fulfillment_error_for_stalled<'tcx>(
) -> FulfillmentError<'tcx> { ) -> FulfillmentError<'tcx> {
let (code, refine_obligation) = infcx.probe(|_| { let (code, refine_obligation) = infcx.probe(|_| {
match <&SolverDelegate<'tcx>>::from(infcx) match <&SolverDelegate<'tcx>>::from(infcx)
.evaluate_root_goal(root_obligation.clone().into(), GenerateProofTree::No) .evaluate_root_goal(
root_obligation.clone().into(),
GenerateProofTree::No,
root_obligation.cause.span,
)
.0 .0
{ {
Ok((_, Certainty::Maybe(MaybeCause::Ambiguity))) => { Ok((_, Certainty::Maybe(MaybeCause::Ambiguity))) => {

View file

@ -238,7 +238,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
// constraints, we get an ICE if we already applied the constraints // constraints, we get an ICE if we already applied the constraints
// from the chosen candidate. // from the chosen candidate.
let proof_tree = infcx let proof_tree = infcx
.probe(|_| infcx.evaluate_root_goal(goal, GenerateProofTree::Yes).1) .probe(|_| infcx.evaluate_root_goal(goal, GenerateProofTree::Yes, span).1)
.unwrap(); .unwrap();
InspectGoal::new(infcx, self.goal.depth + 1, proof_tree, None, source) InspectGoal::new(infcx, self.goal.depth + 1, proof_tree, None, source)
} }
@ -440,8 +440,11 @@ impl<'tcx> InferCtxt<'tcx> {
depth: usize, depth: usize,
visitor: &mut V, visitor: &mut V,
) -> V::Result { ) -> V::Result {
let (_, proof_tree) = let (_, proof_tree) = <&SolverDelegate<'tcx>>::from(self).evaluate_root_goal(
<&SolverDelegate<'tcx>>::from(self).evaluate_root_goal(goal, GenerateProofTree::Yes); goal,
GenerateProofTree::Yes,
visitor.span(),
);
let proof_tree = proof_tree.unwrap(); let proof_tree = proof_tree.unwrap();
visitor.visit_goal(&InspectGoal::new(self, depth, proof_tree, None, GoalSource::Misc)) visitor.visit_goal(&InspectGoal::new(self, depth, proof_tree, None, GoalSource::Misc))
} }

View file

@ -201,17 +201,20 @@ pub trait InferCtxtLike: Sized {
&self, &self,
sub: <Self::Interner as Interner>::Region, sub: <Self::Interner as Interner>::Region,
sup: <Self::Interner as Interner>::Region, sup: <Self::Interner as Interner>::Region,
span: <Self::Interner as Interner>::Span,
); );
fn equate_regions( fn equate_regions(
&self, &self,
a: <Self::Interner as Interner>::Region, a: <Self::Interner as Interner>::Region,
b: <Self::Interner as Interner>::Region, b: <Self::Interner as Interner>::Region,
span: <Self::Interner as Interner>::Span,
); );
fn register_ty_outlives( fn register_ty_outlives(
&self, &self,
ty: <Self::Interner as Interner>::Ty, ty: <Self::Interner as Interner>::Ty,
r: <Self::Interner as Interner>::Region, r: <Self::Interner as Interner>::Region,
span: <Self::Interner as Interner>::Span,
); );
} }

View file

@ -13,6 +13,7 @@ pub trait RelateExt: InferCtxtLike {
lhs: T, lhs: T,
variance: ty::Variance, variance: ty::Variance,
rhs: T, rhs: T,
span: <Self::Interner as Interner>::Span,
) -> Result< ) -> Result<
Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>, Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>,
TypeError<Self::Interner>, TypeError<Self::Interner>,
@ -23,6 +24,7 @@ pub trait RelateExt: InferCtxtLike {
param_env: <Self::Interner as Interner>::ParamEnv, param_env: <Self::Interner as Interner>::ParamEnv,
lhs: T, lhs: T,
rhs: T, rhs: T,
span: <Self::Interner as Interner>::Span,
) -> Result< ) -> Result<
Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>, Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>,
TypeError<Self::Interner>, TypeError<Self::Interner>,
@ -36,12 +38,13 @@ impl<Infcx: InferCtxtLike> RelateExt for Infcx {
lhs: T, lhs: T,
variance: ty::Variance, variance: ty::Variance,
rhs: T, rhs: T,
span: <Self::Interner as Interner>::Span,
) -> Result< ) -> Result<
Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>, Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>,
TypeError<Self::Interner>, TypeError<Self::Interner>,
> { > {
let mut relate = let mut relate =
SolverRelating::new(self, StructurallyRelateAliases::No, variance, param_env); SolverRelating::new(self, StructurallyRelateAliases::No, variance, param_env, span);
relate.relate(lhs, rhs)?; relate.relate(lhs, rhs)?;
Ok(relate.goals) Ok(relate.goals)
} }
@ -51,12 +54,18 @@ impl<Infcx: InferCtxtLike> RelateExt for Infcx {
param_env: <Self::Interner as Interner>::ParamEnv, param_env: <Self::Interner as Interner>::ParamEnv,
lhs: T, lhs: T,
rhs: T, rhs: T,
span: <Self::Interner as Interner>::Span,
) -> Result< ) -> Result<
Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>, Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>,
TypeError<Self::Interner>, TypeError<Self::Interner>,
> { > {
let mut relate = let mut relate = SolverRelating::new(
SolverRelating::new(self, StructurallyRelateAliases::Yes, ty::Invariant, param_env); self,
StructurallyRelateAliases::Yes,
ty::Invariant,
param_env,
span,
);
relate.relate(lhs, rhs)?; relate.relate(lhs, rhs)?;
Ok(relate.goals) Ok(relate.goals)
} }
@ -68,6 +77,7 @@ pub struct SolverRelating<'infcx, Infcx, I: Interner> {
// Immutable fields. // Immutable fields.
structurally_relate_aliases: StructurallyRelateAliases, structurally_relate_aliases: StructurallyRelateAliases,
param_env: I::ParamEnv, param_env: I::ParamEnv,
span: I::Span,
// Mutable fields. // Mutable fields.
ambient_variance: ty::Variance, ambient_variance: ty::Variance,
goals: Vec<Goal<I, I::Predicate>>, goals: Vec<Goal<I, I::Predicate>>,
@ -106,10 +116,12 @@ where
structurally_relate_aliases: StructurallyRelateAliases, structurally_relate_aliases: StructurallyRelateAliases,
ambient_variance: ty::Variance, ambient_variance: ty::Variance,
param_env: I::ParamEnv, param_env: I::ParamEnv,
span: I::Span,
) -> Self { ) -> Self {
SolverRelating { SolverRelating {
infcx, infcx,
structurally_relate_aliases, structurally_relate_aliases,
span,
ambient_variance, ambient_variance,
param_env, param_env,
goals: vec![], goals: vec![],
@ -241,10 +253,10 @@ where
fn regions(&mut self, a: I::Region, b: I::Region) -> RelateResult<I, I::Region> { fn regions(&mut self, a: I::Region, b: I::Region) -> RelateResult<I, I::Region> {
match self.ambient_variance { match self.ambient_variance {
// Subtype(&'a u8, &'b u8) => Outlives('a: 'b) => SubRegion('b, 'a) // Subtype(&'a u8, &'b u8) => Outlives('a: 'b) => SubRegion('b, 'a)
ty::Covariant => self.infcx.sub_regions(b, a), ty::Covariant => self.infcx.sub_regions(b, a, self.span),
// Suptype(&'a u8, &'b u8) => Outlives('b: 'a) => SubRegion('a, 'b) // Suptype(&'a u8, &'b u8) => Outlives('b: 'a) => SubRegion('a, 'b)
ty::Contravariant => self.infcx.sub_regions(a, b), ty::Contravariant => self.infcx.sub_regions(a, b, self.span),
ty::Invariant => self.infcx.equate_regions(a, b), ty::Invariant => self.infcx.equate_regions(a, b, self.span),
ty::Bivariant => { ty::Bivariant => {
unreachable!("Expected bivariance to be handled in relate_with_variance") unreachable!("Expected bivariance to be handled in relate_with_variance")
} }

View file

@ -1,5 +1,4 @@
//@ compile-flags: -Znext-solver //@ compile-flags: -Znext-solver
//~^ ERROR cannot normalize `<T as Default>::Id: '_`
#![feature(specialization)] #![feature(specialization)]
//~^ WARN the feature `specialization` is incomplete //~^ WARN the feature `specialization` is incomplete
@ -14,6 +13,7 @@ impl<T> Default for T {
// This will be fixed by #111994 // This will be fixed by #111994
fn intu(&self) -> &Self::Id { fn intu(&self) -> &Self::Id {
//~^ ERROR type annotations needed //~^ ERROR type annotations needed
//~| ERROR cannot normalize `<T as Default>::Id: '_`
self //~ ERROR cannot satisfy self //~ ERROR cannot satisfy
} }
} }

View file

@ -1,5 +1,5 @@
warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/specialization-transmute.rs:3:12 --> $DIR/specialization-transmute.rs:2:12
| |
LL | #![feature(specialization)] LL | #![feature(specialization)]
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
@ -9,9 +9,13 @@ LL | #![feature(specialization)]
= note: `#[warn(incomplete_features)]` on by default = note: `#[warn(incomplete_features)]` on by default
error: cannot normalize `<T as Default>::Id: '_` error: cannot normalize `<T as Default>::Id: '_`
--> $DIR/specialization-transmute.rs:14:5
|
LL | fn intu(&self) -> &Self::Id {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0282]: type annotations needed error[E0282]: type annotations needed
--> $DIR/specialization-transmute.rs:15:23 --> $DIR/specialization-transmute.rs:14:23
| |
LL | fn intu(&self) -> &Self::Id { LL | fn intu(&self) -> &Self::Id {
| ^^^^^^^^^ cannot infer type for reference `&<T as Default>::Id` | ^^^^^^^^^ cannot infer type for reference `&<T as Default>::Id`

View file

@ -1,4 +1,3 @@
//~ ERROR the type `&'a ()` does not fulfill the required lifetime
//@ compile-flags: -Znext-solver //@ compile-flags: -Znext-solver
// Regression test for rust-lang/trait-system-refactor-initiative#59 // Regression test for rust-lang/trait-system-refactor-initiative#59
@ -8,6 +7,7 @@ trait StaticTy {
impl StaticTy for () { impl StaticTy for () {
type Item<'a> = &'a (); type Item<'a> = &'a ();
//~^ ERROR the type `&'a ()` does not fulfill the required lifetime
} }
fn main() {} fn main() {}

View file

@ -1,4 +1,8 @@
error[E0477]: the type `&'a ()` does not fulfill the required lifetime error[E0477]: the type `&'a ()` does not fulfill the required lifetime
--> $DIR/unsound-region-obligation.rs:9:21
|
LL | type Item<'a> = &'a ();
| ^^^^^^
| |
= note: type must satisfy the static lifetime = note: type must satisfy the static lifetime