mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 19:58:32 +00:00
Rollup merge of #136269 - compiler-errors:spanned, r=lcnr
Pass spans around new solver ...so that when we instantiate canonical responses, we can actually have region obligations with the right span. Within the solver itself, we still use dummy spans everywhere.
This commit is contained in:
commit
b9bacc4da5
@ -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,
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,15 +4,13 @@ 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()
|
||||||
}
|
}
|
||||||
|
|
||||||
type Span: Copy;
|
|
||||||
|
|
||||||
fn build_with_canonical<V>(
|
fn build_with_canonical<V>(
|
||||||
cx: Self::Interner,
|
cx: Self::Interner,
|
||||||
canonical: &ty::CanonicalQueryInput<Self::Interner, V>,
|
canonical: &ty::CanonicalQueryInput<Self::Interner, V>,
|
||||||
@ -23,7 +21,7 @@ pub trait SolverDelegate: Deref<Target = <Self as SolverDelegate>::Infcx> + Size
|
|||||||
fn fresh_var_for_kind_with_span(
|
fn fresh_var_for_kind_with_span(
|
||||||
&self,
|
&self,
|
||||||
arg: <Self::Interner as Interner>::GenericArg,
|
arg: <Self::Interner as Interner>::GenericArg,
|
||||||
span: Self::Span,
|
span: <Self::Interner as Interner>::Span,
|
||||||
) -> <Self::Interner as Interner>::GenericArg;
|
) -> <Self::Interner as Interner>::GenericArg;
|
||||||
|
|
||||||
// FIXME: Uplift the leak check into this crate.
|
// FIXME: Uplift the leak check into this crate.
|
||||||
@ -61,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;
|
||||||
|
|
||||||
@ -86,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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -431,7 +442,7 @@ where
|
|||||||
// `rustc_trait_selection::solve::inspect::analyse`.
|
// `rustc_trait_selection::solve::inspect::analyse`.
|
||||||
pub fn instantiate_canonical_state<D, I, T: TypeFoldable<I>>(
|
pub fn instantiate_canonical_state<D, I, T: TypeFoldable<I>>(
|
||||||
delegate: &D,
|
delegate: &D,
|
||||||
span: D::Span,
|
span: I::Span,
|
||||||
param_env: I::ParamEnv,
|
param_env: I::ParamEnv,
|
||||||
orig_values: &mut Vec<I::GenericArg>,
|
orig_values: &mut Vec<I::GenericArg>,
|
||||||
state: inspect::CanonicalState<I, T>,
|
state: inspect::CanonicalState<I, T>,
|
||||||
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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(),
|
||||||
};
|
};
|
||||||
|
@ -43,8 +43,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
|
|||||||
self.0.tcx
|
self.0.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
type Span = Span;
|
|
||||||
|
|
||||||
fn build_with_canonical<V>(
|
fn build_with_canonical<V>(
|
||||||
interner: TyCtxt<'tcx>,
|
interner: TyCtxt<'tcx>,
|
||||||
canonical: &CanonicalQueryInput<'tcx, V>,
|
canonical: &CanonicalQueryInput<'tcx, V>,
|
||||||
@ -147,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(
|
||||||
@ -175,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) {
|
||||||
|
@ -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 {
|
||||||
|
@ -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))) => {
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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`
|
||||||
|
@ -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() {}
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user