mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
Normalize the whole PolyTypeOutlivesPredicate, more simplifications
This commit is contained in:
parent
a371059933
commit
e951bcff96
@ -5,13 +5,11 @@ use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelega
|
|||||||
use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
|
use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
|
||||||
use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
|
use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
|
||||||
use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
|
use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
|
||||||
|
use rustc_middle::traits::query::NoSolution;
|
||||||
use rustc_middle::traits::ObligationCause;
|
use rustc_middle::traits::ObligationCause;
|
||||||
use rustc_middle::ty::GenericArgKind;
|
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
|
||||||
use rustc_middle::ty::{TypeFoldable, TypeVisitableExt};
|
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
use rustc_trait_selection::solve::deeply_normalize;
|
use rustc_trait_selection::solve::deeply_normalize;
|
||||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
|
||||||
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
|
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
|
||||||
use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
|
use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
|
||||||
|
|
||||||
@ -146,7 +144,6 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
|||||||
let ConstraintConversion {
|
let ConstraintConversion {
|
||||||
tcx,
|
tcx,
|
||||||
infcx,
|
infcx,
|
||||||
param_env,
|
|
||||||
region_bound_pairs,
|
region_bound_pairs,
|
||||||
implicit_region_bound,
|
implicit_region_bound,
|
||||||
known_type_outlives_obligations,
|
known_type_outlives_obligations,
|
||||||
@ -178,43 +175,10 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
|||||||
// Normalize the type we receive from a `TypeOutlives` obligation
|
// Normalize the type we receive from a `TypeOutlives` obligation
|
||||||
// in the new trait solver.
|
// in the new trait solver.
|
||||||
if infcx.next_trait_solver() {
|
if infcx.next_trait_solver() {
|
||||||
let result = CustomTypeOp::new(
|
t1 = self.normalize_and_add_type_outlives_constraints(
|
||||||
|ocx| {
|
t1,
|
||||||
match deeply_normalize(
|
&mut next_outlives_predicates,
|
||||||
ocx.infcx.at(
|
);
|
||||||
&ObligationCause::dummy_with_span(self.span),
|
|
||||||
param_env,
|
|
||||||
),
|
|
||||||
t1,
|
|
||||||
) {
|
|
||||||
Ok(normalized_ty) => {
|
|
||||||
t1 = normalized_ty;
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
infcx.err_ctxt().report_fulfillment_errors(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
"normalize type outlives obligation",
|
|
||||||
)
|
|
||||||
.fully_perform(infcx, self.span);
|
|
||||||
|
|
||||||
match result {
|
|
||||||
Ok(TypeOpOutput { output: (), constraints, .. }) => {
|
|
||||||
if let Some(constraints) = constraints {
|
|
||||||
assert!(
|
|
||||||
constraints.member_constraints.is_empty(),
|
|
||||||
"no member constraints expected from normalizing: {:#?}",
|
|
||||||
constraints.member_constraints
|
|
||||||
);
|
|
||||||
next_outlives_predicates
|
|
||||||
.extend(constraints.outlives.iter().copied());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(_) => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// we don't actually use this for anything, but
|
// we don't actually use this for anything, but
|
||||||
@ -306,6 +270,42 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
|||||||
debug!("add_type_test(type_test={:?})", type_test);
|
debug!("add_type_test(type_test={:?})", type_test);
|
||||||
self.constraints.type_tests.push(type_test);
|
self.constraints.type_tests.push(type_test);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn normalize_and_add_type_outlives_constraints(
|
||||||
|
&self,
|
||||||
|
ty: Ty<'tcx>,
|
||||||
|
next_outlives_predicates: &mut Vec<(
|
||||||
|
ty::OutlivesPredicate<ty::GenericArg<'tcx>, ty::Region<'tcx>>,
|
||||||
|
ConstraintCategory<'tcx>,
|
||||||
|
)>,
|
||||||
|
) -> Ty<'tcx> {
|
||||||
|
let result = CustomTypeOp::new(
|
||||||
|
|ocx| {
|
||||||
|
deeply_normalize(
|
||||||
|
ocx.infcx.at(&ObligationCause::dummy_with_span(self.span), self.param_env),
|
||||||
|
ty,
|
||||||
|
)
|
||||||
|
.map_err(|_| NoSolution)
|
||||||
|
},
|
||||||
|
"normalize type outlives obligation",
|
||||||
|
)
|
||||||
|
.fully_perform(self.infcx, self.span);
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(TypeOpOutput { output: ty, constraints, .. }) => {
|
||||||
|
if let Some(constraints) = constraints {
|
||||||
|
assert!(
|
||||||
|
constraints.member_constraints.is_empty(),
|
||||||
|
"no member constraints expected from normalizing: {:#?}",
|
||||||
|
constraints.member_constraints
|
||||||
|
);
|
||||||
|
next_outlives_predicates.extend(constraints.outlives.iter().copied());
|
||||||
|
}
|
||||||
|
ty
|
||||||
|
}
|
||||||
|
Err(_) => ty,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, 'tcx> TypeOutlivesDelegate<'tcx> for &'a mut ConstraintConversion<'b, 'tcx> {
|
impl<'a, 'b, 'tcx> TypeOutlivesDelegate<'tcx> for &'a mut ConstraintConversion<'b, 'tcx> {
|
||||||
|
@ -11,7 +11,7 @@ use rustc_middle::traits::query::OutlivesBound;
|
|||||||
use rustc_middle::traits::ObligationCause;
|
use rustc_middle::traits::ObligationCause;
|
||||||
use rustc_middle::ty::{self, RegionVid, Ty, TypeVisitableExt};
|
use rustc_middle::ty::{self, RegionVid, Ty, TypeVisitableExt};
|
||||||
use rustc_span::{ErrorGuaranteed, DUMMY_SP};
|
use rustc_span::{ErrorGuaranteed, DUMMY_SP};
|
||||||
use rustc_trait_selection::solve::deeply_normalize_with_skipped_universes;
|
use rustc_trait_selection::solve::deeply_normalize;
|
||||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
||||||
use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
|
use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -226,18 +226,16 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
|
|||||||
let mut constraints = vec![];
|
let mut constraints = vec![];
|
||||||
let mut known_type_outlives_obligations = vec![];
|
let mut known_type_outlives_obligations = vec![];
|
||||||
for bound in param_env.caller_bounds() {
|
for bound in param_env.caller_bounds() {
|
||||||
let Some(outlives) = bound.as_type_outlives_clause() else { continue };
|
let Some(mut outlives) = bound.as_type_outlives_clause() else { continue };
|
||||||
let ty::OutlivesPredicate(mut ty, region) = outlives.skip_binder();
|
|
||||||
|
|
||||||
// In the new solver, normalize the type-outlives obligation assumptions.
|
// In the new solver, normalize the type-outlives obligation assumptions.
|
||||||
if self.infcx.next_trait_solver() {
|
if self.infcx.next_trait_solver() {
|
||||||
match deeply_normalize_with_skipped_universes(
|
match deeply_normalize(
|
||||||
self.infcx.at(&ObligationCause::misc(span, defining_ty_def_id), self.param_env),
|
self.infcx.at(&ObligationCause::misc(span, defining_ty_def_id), self.param_env),
|
||||||
ty,
|
outlives,
|
||||||
vec![None; ty.outer_exclusive_binder().as_usize()],
|
|
||||||
) {
|
) {
|
||||||
Ok(normalized_ty) => {
|
Ok(normalized_outlives) => {
|
||||||
ty = normalized_ty;
|
outlives = normalized_outlives;
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
self.infcx.err_ctxt().report_fulfillment_errors(e);
|
self.infcx.err_ctxt().report_fulfillment_errors(e);
|
||||||
@ -245,8 +243,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
known_type_outlives_obligations
|
known_type_outlives_obligations.push(outlives);
|
||||||
.push(outlives.rebind(ty::OutlivesPredicate(ty, region)));
|
|
||||||
}
|
}
|
||||||
let known_type_outlives_obligations =
|
let known_type_outlives_obligations =
|
||||||
self.infcx.tcx.arena.alloc_slice(&known_type_outlives_obligations);
|
self.infcx.tcx.arena.alloc_slice(&known_type_outlives_obligations);
|
||||||
|
@ -71,6 +71,7 @@ use rustc_hir::lang_items::LangItem;
|
|||||||
use rustc_middle::dep_graph::DepContext;
|
use rustc_middle::dep_graph::DepContext;
|
||||||
use rustc_middle::ty::print::{with_forced_trimmed_paths, PrintError};
|
use rustc_middle::ty::print::{with_forced_trimmed_paths, PrintError};
|
||||||
use rustc_middle::ty::relate::{self, RelateResult, TypeRelation};
|
use rustc_middle::ty::relate::{self, RelateResult, TypeRelation};
|
||||||
|
use rustc_middle::ty::ToPredicate;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, error::TypeError, IsSuggestable, List, Region, Ty, TyCtxt, TypeFoldable,
|
self, error::TypeError, IsSuggestable, List, Region, Ty, TyCtxt, TypeFoldable,
|
||||||
TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
|
TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
|
||||||
@ -519,10 +520,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||||||
self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit();
|
self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
RegionResolutionError::CannotNormalize(ty, origin) => {
|
RegionResolutionError::CannotNormalize(clause, origin) => {
|
||||||
|
let clause: ty::Clause<'tcx> =
|
||||||
|
clause.map_bound(ty::ClauseKind::TypeOutlives).to_predicate(self.tcx);
|
||||||
self.tcx
|
self.tcx
|
||||||
.dcx()
|
.dcx()
|
||||||
.struct_span_err(origin.span(), format!("cannot normalize `{ty}`"))
|
.struct_span_err(origin.span(), format!("cannot normalize `{clause}`"))
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ pub enum RegionResolutionError<'tcx> {
|
|||||||
Region<'tcx>, // the placeholder `'b`
|
Region<'tcx>, // the placeholder `'b`
|
||||||
),
|
),
|
||||||
|
|
||||||
CannotNormalize(Ty<'tcx>, SubregionOrigin<'tcx>),
|
CannotNormalize(ty::PolyTypeOutlivesPredicate<'tcx>, SubregionOrigin<'tcx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> RegionResolutionError<'tcx> {
|
impl<'tcx> RegionResolutionError<'tcx> {
|
||||||
|
@ -4,8 +4,8 @@ use super::region_constraints::RegionConstraintData;
|
|||||||
use super::{InferCtxt, RegionResolutionError, SubregionOrigin};
|
use super::{InferCtxt, RegionResolutionError, SubregionOrigin};
|
||||||
use crate::infer::free_regions::RegionRelations;
|
use crate::infer::free_regions::RegionRelations;
|
||||||
use crate::infer::lexical_region_resolve;
|
use crate::infer::lexical_region_resolve;
|
||||||
use rustc_middle::traits::query::OutlivesBound;
|
use rustc_middle::traits::query::{NoSolution, OutlivesBound};
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty;
|
||||||
|
|
||||||
pub mod components;
|
pub mod components;
|
||||||
pub mod env;
|
pub mod env;
|
||||||
@ -49,12 +49,15 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||||||
pub fn resolve_regions_with_normalize(
|
pub fn resolve_regions_with_normalize(
|
||||||
&self,
|
&self,
|
||||||
outlives_env: &OutlivesEnvironment<'tcx>,
|
outlives_env: &OutlivesEnvironment<'tcx>,
|
||||||
deeply_normalize_ty: impl Fn(Ty<'tcx>, SubregionOrigin<'tcx>) -> Result<Ty<'tcx>, Ty<'tcx>>,
|
deeply_normalize_ty: impl Fn(
|
||||||
|
ty::PolyTypeOutlivesPredicate<'tcx>,
|
||||||
|
SubregionOrigin<'tcx>,
|
||||||
|
) -> Result<ty::PolyTypeOutlivesPredicate<'tcx>, NoSolution>,
|
||||||
) -> Vec<RegionResolutionError<'tcx>> {
|
) -> Vec<RegionResolutionError<'tcx>> {
|
||||||
match self.process_registered_region_obligations(outlives_env, deeply_normalize_ty) {
|
match self.process_registered_region_obligations(outlives_env, deeply_normalize_ty) {
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err((ty, origin)) => {
|
Err((clause, origin)) => {
|
||||||
return vec![RegionResolutionError::CannotNormalize(ty, origin)];
|
return vec![RegionResolutionError::CannotNormalize(clause, origin)];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -68,8 +68,9 @@ use crate::infer::{
|
|||||||
use crate::traits::{ObligationCause, ObligationCauseCode};
|
use crate::traits::{ObligationCause, ObligationCauseCode};
|
||||||
use rustc_data_structures::undo_log::UndoLogs;
|
use rustc_data_structures::undo_log::UndoLogs;
|
||||||
use rustc_middle::mir::ConstraintCategory;
|
use rustc_middle::mir::ConstraintCategory;
|
||||||
use rustc_middle::ty::GenericArgKind;
|
use rustc_middle::traits::query::NoSolution;
|
||||||
use rustc_middle::ty::{self, GenericArgsRef, Region, Ty, TyCtxt, TypeVisitableExt};
|
use rustc_middle::ty::{self, GenericArgsRef, Region, Ty, TyCtxt, TypeVisitableExt};
|
||||||
|
use rustc_middle::ty::{GenericArgKind, PolyTypeOutlivesPredicate};
|
||||||
use rustc_span::DUMMY_SP;
|
use rustc_span::DUMMY_SP;
|
||||||
use smallvec::smallvec;
|
use smallvec::smallvec;
|
||||||
|
|
||||||
@ -125,11 +126,15 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||||||
/// invoked after all type-inference variables have been bound --
|
/// invoked after all type-inference variables have been bound --
|
||||||
/// right before lexical region resolution.
|
/// right before lexical region resolution.
|
||||||
#[instrument(level = "debug", skip(self, outlives_env, deeply_normalize_ty))]
|
#[instrument(level = "debug", skip(self, outlives_env, deeply_normalize_ty))]
|
||||||
pub fn process_registered_region_obligations<E>(
|
pub fn process_registered_region_obligations(
|
||||||
&self,
|
&self,
|
||||||
outlives_env: &OutlivesEnvironment<'tcx>,
|
outlives_env: &OutlivesEnvironment<'tcx>,
|
||||||
mut deeply_normalize_ty: impl FnMut(Ty<'tcx>, SubregionOrigin<'tcx>) -> Result<Ty<'tcx>, E>,
|
mut deeply_normalize_ty: impl FnMut(
|
||||||
) -> Result<(), (E, SubregionOrigin<'tcx>)> {
|
PolyTypeOutlivesPredicate<'tcx>,
|
||||||
|
SubregionOrigin<'tcx>,
|
||||||
|
)
|
||||||
|
-> Result<PolyTypeOutlivesPredicate<'tcx>, NoSolution>,
|
||||||
|
) -> Result<(), (PolyTypeOutlivesPredicate<'tcx>, SubregionOrigin<'tcx>)> {
|
||||||
assert!(!self.in_snapshot(), "cannot process registered region obligations in a snapshot");
|
assert!(!self.in_snapshot(), "cannot process registered region obligations in a snapshot");
|
||||||
|
|
||||||
let normalized_caller_bounds: Vec<_> = outlives_env
|
let normalized_caller_bounds: Vec<_> = outlives_env
|
||||||
@ -137,21 +142,19 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||||||
.caller_bounds()
|
.caller_bounds()
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|clause| {
|
.filter_map(|clause| {
|
||||||
let bound_clause = clause.kind();
|
let outlives = clause.as_type_outlives_clause()?;
|
||||||
let ty::ClauseKind::TypeOutlives(outlives) = bound_clause.skip_binder() else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
Some(
|
Some(
|
||||||
deeply_normalize_ty(
|
deeply_normalize_ty(
|
||||||
outlives.0,
|
outlives,
|
||||||
SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP),
|
SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP),
|
||||||
)
|
)
|
||||||
.map(|ty| bound_clause.rebind(ty::OutlivesPredicate(ty, outlives.1))),
|
// FIXME(-Znext-solver): How do we accurately report an error span here :(
|
||||||
|
.map_err(|NoSolution| {
|
||||||
|
(outlives, SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP))
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
// FIXME(-Znext-solver): How do we accurately report an error here :(
|
.try_collect()?;
|
||||||
.try_collect()
|
|
||||||
.map_err(|e| (e, SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP)))?;
|
|
||||||
|
|
||||||
// Must loop since the process of normalizing may itself register region obligations.
|
// Must loop since the process of normalizing may itself register region obligations.
|
||||||
for iteration in 0.. {
|
for iteration in 0.. {
|
||||||
@ -167,8 +170,13 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for RegionObligation { sup_type, sub_region, origin } in my_region_obligations {
|
for RegionObligation { sup_type, sub_region, origin } in my_region_obligations {
|
||||||
let sup_type = deeply_normalize_ty(sup_type, origin.clone())
|
let outlives = ty::Binder::dummy(ty::OutlivesPredicate(sup_type, sub_region));
|
||||||
.map_err(|e| (e, origin.clone()))?;
|
let ty::OutlivesPredicate(sup_type, sub_region) =
|
||||||
|
deeply_normalize_ty(outlives, origin.clone())
|
||||||
|
.map_err(|NoSolution| (outlives, origin.clone()))?
|
||||||
|
.no_bound_vars()
|
||||||
|
.expect("started with no bound vars, should end with no bound vars");
|
||||||
|
|
||||||
debug!(?sup_type, ?sub_region, ?origin);
|
debug!(?sup_type, ?sub_region, ?origin);
|
||||||
|
|
||||||
let outlives = &mut TypeOutlives::new(
|
let outlives = &mut TypeOutlives::new(
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||||
use rustc_infer::infer::{InferCtxt, RegionResolutionError};
|
use rustc_infer::infer::{InferCtxt, RegionResolutionError};
|
||||||
|
use rustc_middle::traits::query::NoSolution;
|
||||||
use rustc_middle::traits::ObligationCause;
|
use rustc_middle::traits::ObligationCause;
|
||||||
|
|
||||||
pub trait InferCtxtRegionExt<'tcx> {
|
pub trait InferCtxtRegionExt<'tcx> {
|
||||||
@ -24,15 +25,14 @@ impl<'tcx> InferCtxtRegionExt<'tcx> for InferCtxt<'tcx> {
|
|||||||
let ty = self.resolve_vars_if_possible(ty);
|
let ty = self.resolve_vars_if_possible(ty);
|
||||||
|
|
||||||
if self.next_trait_solver() {
|
if self.next_trait_solver() {
|
||||||
crate::solve::deeply_normalize_with_skipped_universes(
|
crate::solve::deeply_normalize(
|
||||||
self.at(
|
self.at(
|
||||||
&ObligationCause::dummy_with_span(origin.span()),
|
&ObligationCause::dummy_with_span(origin.span()),
|
||||||
outlives_env.param_env,
|
outlives_env.param_env,
|
||||||
),
|
),
|
||||||
ty,
|
ty,
|
||||||
vec![None; ty.outer_exclusive_binder().as_usize()],
|
|
||||||
)
|
)
|
||||||
.map_err(|_| ty)
|
.map_err(|_| NoSolution)
|
||||||
} else {
|
} else {
|
||||||
Ok(ty)
|
Ok(ty)
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let outlives_env = OutlivesEnvironment::new(full_env);
|
let outlives_env = OutlivesEnvironment::new(full_env);
|
||||||
let _ = infcx.process_registered_region_obligations::<!>(&outlives_env, |ty, _| Ok(ty));
|
let _ = infcx.process_registered_region_obligations(&outlives_env, |ty, _| Ok(ty));
|
||||||
|
|
||||||
let region_data =
|
let region_data =
|
||||||
infcx.inner.borrow_mut().unwrap_region_constraints().region_constraint_data().clone();
|
infcx.inner.borrow_mut().unwrap_region_constraints().region_constraint_data().clone();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// compile-flags: -Znext-solver
|
// compile-flags: -Znext-solver
|
||||||
//~^ ERROR cannot normalize `<T as Default>::Id`
|
//~^ ERROR cannot normalize `<T as Default>::Id: '_`
|
||||||
|
|
||||||
#![feature(specialization)]
|
#![feature(specialization)]
|
||||||
//~^ WARN the feature `specialization` is incomplete
|
//~^ WARN the feature `specialization` is incomplete
|
||||||
|
@ -8,7 +8,7 @@ LL | #![feature(specialization)]
|
|||||||
= help: consider using `min_specialization` instead, which is more stable and complete
|
= help: consider using `min_specialization` instead, which is more stable and complete
|
||||||
= 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: '_`
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
error[E0282]: type annotations needed
|
||||||
--> $DIR/specialization-transmute.rs:14:23
|
--> $DIR/specialization-transmute.rs:14:23
|
||||||
|
Loading…
Reference in New Issue
Block a user