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:
Jubilee 2025-02-05 19:53:46 -08:00 committed by GitHub
commit b9bacc4da5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 139 additions and 61 deletions

View File

@ -137,6 +137,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
expected,
ty::Contravariant,
actual,
self.cause.span,
)
.map(|goals| self.goals_to_obligations(goals))
} else {
@ -163,8 +164,15 @@ impl<'a, 'tcx> At<'a, 'tcx> {
T: ToTrace<'tcx>,
{
if self.infcx.next_trait_solver {
NextSolverRelate::relate(self.infcx, self.param_env, expected, ty::Covariant, actual)
.map(|goals| self.goals_to_obligations(goals))
NextSolverRelate::relate(
self.infcx,
self.param_env,
expected,
ty::Covariant,
actual,
self.cause.span,
)
.map(|goals| self.goals_to_obligations(goals))
} else {
let mut op = TypeRelating::new(
self.infcx,
@ -208,8 +216,15 @@ impl<'a, 'tcx> At<'a, 'tcx> {
T: Relate<TyCtxt<'tcx>>,
{
if self.infcx.next_trait_solver {
NextSolverRelate::relate(self.infcx, self.param_env, expected, ty::Invariant, actual)
.map(|goals| self.goals_to_obligations(goals))
NextSolverRelate::relate(
self.infcx,
self.param_env,
expected,
ty::Invariant,
actual,
self.cause.span,
)
.map(|goals| self.goals_to_obligations(goals))
} else {
let mut op = TypeRelating::new(
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::combine::PredicateEmittingRelation;
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};
@ -203,23 +203,23 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
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(
SubregionOrigin::RelateRegionParamBound(DUMMY_SP, None),
SubregionOrigin::RelateRegionParamBound(span, None),
sub,
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(
SubregionOrigin::RelateRegionParamBound(DUMMY_SP, None),
SubregionOrigin::RelateRegionParamBound(span, None),
a,
b,
);
}
fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>) {
self.register_region_obligation_with_cause(ty, r, &ObligationCause::dummy());
fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>, span: Span) {
self.register_region_obligation_with_cause(ty, r, &ObligationCause::dummy_with_span(span));
}
}

View File

@ -4,15 +4,13 @@ use rustc_type_ir::fold::TypeFoldable;
use rustc_type_ir::solve::{Certainty, Goal, NoSolution};
use rustc_type_ir::{self as ty, InferCtxtLike, Interner};
pub trait SolverDelegate: Deref<Target = <Self as SolverDelegate>::Infcx> + Sized {
type Infcx: InferCtxtLike<Interner = <Self as SolverDelegate>::Interner>;
pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
type Infcx: InferCtxtLike<Interner = Self::Interner>;
type Interner: Interner;
fn cx(&self) -> Self::Interner {
(**self).cx()
}
type Span: Copy;
fn build_with_canonical<V>(
cx: Self::Interner,
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(
&self,
arg: <Self::Interner as Interner>::GenericArg,
span: Self::Span,
span: <Self::Interner as Interner>::Span,
) -> <Self::Interner as Interner>::GenericArg;
// 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(
&self,
cv_info: ty::CanonicalVarInfo<Self::Interner>,
span: <Self::Interner as Interner>::Span,
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
) -> <Self::Interner as Interner>::GenericArg;
@ -86,6 +85,7 @@ pub trait SolverDelegate: Deref<Target = <Self as SolverDelegate>::Infcx> + Size
&self,
key: ty::OpaqueTypeKey<Self::Interner>,
hidden_ty: <Self::Interner as Interner>::Ty,
span: <Self::Interner as Interner>::Span,
);
fn reset_opaque_types(&self);

View File

@ -255,20 +255,29 @@ where
self.delegate,
&original_values,
&response,
self.origin_span,
);
let Response { var_values, external_constraints, certainty } =
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 {
region_constraints,
opaque_types,
normalization_nested_goals,
} = &*external_constraints;
self.register_region_constraints(region_constraints);
self.register_new_opaque_types(opaque_types);
(normalization_nested_goals.clone(), certainty)
}
@ -279,6 +288,7 @@ where
delegate: &D,
original_values: &[I::GenericArg],
response: &Canonical<I, T>,
span: I::Span,
) -> CanonicalVarValues<I> {
// FIXME: Longterm canonical queries should deal with all placeholders
// 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
// exist at all (see the FIXME at the start of this method), we have to deal with
// 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())
})
} else if info.is_existential() {
@ -345,7 +355,7 @@ where
if let Some(v) = opt_values[ty::BoundVar::from_usize(index)] {
v
} else {
delegate.instantiate_canonical_var_with_infer(info, |_| prev_universe)
delegate.instantiate_canonical_var_with_infer(info, span, |_| prev_universe)
}
} else {
// For placeholders which were already part of the input, we simply map this
@ -376,12 +386,13 @@ where
param_env: I::ParamEnv,
original_values: &[I::GenericArg],
var_values: CanonicalVarValues<I>,
span: I::Span,
) {
assert_eq!(original_values.len(), var_values.len());
for (&orig, response) in iter::zip(original_values, var_values.var_values.iter()) {
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());
}
}
@ -401,7 +412,7 @@ where
fn register_new_opaque_types(&mut self, opaque_types: &[(ty::OpaqueTypeKey<I>, I::Ty)]) {
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`.
pub fn instantiate_canonical_state<D, I, T: TypeFoldable<I>>(
delegate: &D,
span: D::Span,
span: I::Span,
param_env: I::ParamEnv,
orig_values: &mut Vec<I::GenericArg>,
state: inspect::CanonicalState<I, T>,
@ -451,10 +462,10 @@ where
}
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);
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
}

View File

@ -78,6 +78,8 @@ where
nested_goals: NestedGoals<I>,
pub(super) origin_span: I::Span,
// 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,
@ -134,6 +136,7 @@ pub trait SolverDelegateEvalExt: SolverDelegate {
&self,
goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
generate_proof_tree: GenerateProofTree,
span: <Self::Interner as Interner>::Span,
) -> (
Result<(HasChanged, Certainty), NoSolution>,
Option<inspect::GoalEvaluation<Self::Interner>>,
@ -174,8 +177,9 @@ where
&self,
goal: Goal<I, I::Predicate>,
generate_proof_tree: GenerateProofTree,
span: I::Span,
) -> (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)
})
}
@ -186,7 +190,7 @@ where
goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
) -> bool {
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)
})
.0
@ -203,9 +207,13 @@ where
Result<(NestedNormalizationGoals<I>, HasChanged, Certainty), NoSolution>,
Option<inspect::GoalEvaluation<I>>,
) {
EvalCtxt::enter_root(self, self.cx().recursion_limit(), generate_proof_tree, |ecx| {
ecx.evaluate_goal_raw(GoalEvaluationKind::Root, GoalSource::Misc, goal)
})
EvalCtxt::enter_root(
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,
root_depth: usize,
generate_proof_tree: GenerateProofTree,
origin_span: I::Span,
f: impl FnOnce(&mut EvalCtxt<'_, D>) -> R,
) -> (R, Option<inspect::GoalEvaluation<I>>) {
let mut search_graph = SearchGraph::new(root_depth);
@ -248,6 +257,7 @@ where
variables: Default::default(),
var_values: CanonicalVarValues::dummy(),
is_normalizes_to_goal: false,
origin_span,
tainted: Ok(()),
};
let result = f(&mut ecx);
@ -289,12 +299,13 @@ where
max_input_universe: canonical_input.canonical.max_universe,
search_graph,
nested_goals: NestedGoals::new(),
origin_span: I::Span::dummy(),
tainted: Ok(()),
inspect: canonical_goal_evaluation.new_goal_evaluation_step(var_values),
};
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() {
@ -822,8 +833,12 @@ where
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 ctor_term = rigid_ctor.to_term(cx);
let obligations =
self.delegate.eq_structurally_relating_aliases(param_env, term, ctor_term)?;
let obligations = self.delegate.eq_structurally_relating_aliases(
param_env,
term,
ctor_term,
self.origin_span,
)?;
debug_assert!(obligations.is_empty());
self.relate(param_env, alias, variance, rigid_ctor)
} else {
@ -841,7 +856,12 @@ where
lhs: T,
rhs: T,
) -> 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![]);
Ok(())
}
@ -864,7 +884,7 @@ where
variance: ty::Variance,
rhs: T,
) -> 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);
Ok(())
}
@ -881,7 +901,7 @@ where
lhs: T,
rhs: T,
) -> 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>(
@ -917,12 +937,12 @@ where
}
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) {
// `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

View File

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

View File

@ -43,8 +43,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
self.0.tcx
}
type Span = Span;
fn build_with_canonical<V>(
interner: TyCtxt<'tcx>,
canonical: &CanonicalQueryInput<'tcx, V>,
@ -147,9 +145,10 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
fn instantiate_canonical_var_with_infer(
&self,
cv_info: CanonicalVarInfo<'tcx>,
span: Span,
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
) -> 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(
@ -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);
}
fn inject_new_hidden_type_unchecked(&self, key: ty::OpaqueTypeKey<'tcx>, hidden_ty: Ty<'tcx>) {
self.0.inject_new_hidden_type_unchecked(key, ty::OpaqueHiddenType {
ty: hidden_ty,
span: DUMMY_SP,
})
fn inject_new_hidden_type_unchecked(
&self,
key: ty::OpaqueTypeKey<'tcx>,
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) {

View File

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

View File

@ -88,7 +88,11 @@ pub(super) fn fulfillment_error_for_stalled<'tcx>(
) -> FulfillmentError<'tcx> {
let (code, refine_obligation) = infcx.probe(|_| {
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
{
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
// from the chosen candidate.
let proof_tree = infcx
.probe(|_| infcx.evaluate_root_goal(goal, GenerateProofTree::Yes).1)
.probe(|_| infcx.evaluate_root_goal(goal, GenerateProofTree::Yes, span).1)
.unwrap();
InspectGoal::new(infcx, self.goal.depth + 1, proof_tree, None, source)
}
@ -440,8 +440,11 @@ impl<'tcx> InferCtxt<'tcx> {
depth: usize,
visitor: &mut V,
) -> V::Result {
let (_, proof_tree) =
<&SolverDelegate<'tcx>>::from(self).evaluate_root_goal(goal, GenerateProofTree::Yes);
let (_, proof_tree) = <&SolverDelegate<'tcx>>::from(self).evaluate_root_goal(
goal,
GenerateProofTree::Yes,
visitor.span(),
);
let proof_tree = proof_tree.unwrap();
visitor.visit_goal(&InspectGoal::new(self, depth, proof_tree, None, GoalSource::Misc))
}

View File

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

View File

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

View File

@ -1,5 +1,4 @@
//@ compile-flags: -Znext-solver
//~^ ERROR cannot normalize `<T as Default>::Id: '_`
#![feature(specialization)]
//~^ WARN the feature `specialization` is incomplete
@ -14,6 +13,7 @@ impl<T> Default for T {
// This will be fixed by #111994
fn intu(&self) -> &Self::Id {
//~^ ERROR type annotations needed
//~| ERROR cannot normalize `<T as Default>::Id: '_`
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
--> $DIR/specialization-transmute.rs:3:12
--> $DIR/specialization-transmute.rs:2:12
|
LL | #![feature(specialization)]
| ^^^^^^^^^^^^^^
@ -9,9 +9,13 @@ LL | #![feature(specialization)]
= note: `#[warn(incomplete_features)]` on by default
error: cannot normalize `<T as Default>::Id: '_`
--> $DIR/specialization-transmute.rs:14:5
|
LL | fn intu(&self) -> &Self::Id {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0282]: type annotations needed
--> $DIR/specialization-transmute.rs:15:23
--> $DIR/specialization-transmute.rs:14:23
|
LL | fn intu(&self) -> &Self::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
// Regression test for rust-lang/trait-system-refactor-initiative#59
@ -8,6 +7,7 @@ trait StaticTy {
impl StaticTy for () {
type Item<'a> = &'a ();
//~^ ERROR the type `&'a ()` does not fulfill the required lifetime
}
fn main() {}

View File

@ -1,4 +1,8 @@
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