Revert "Auto merge of #92306 - Aaron1011:opaque-type-op, r=oli-obk"
This reverts commit1f0a96862a
, reversing changes made tobf242bb119
.
This commit is contained in:
parent
7a71b7a99e
commit
2d8b8f3593
14 changed files with 71 additions and 231 deletions
|
@ -2,13 +2,9 @@ use rustc_errors::DiagnosticBuilder;
|
||||||
use rustc_infer::infer::canonical::Canonical;
|
use rustc_infer::infer::canonical::Canonical;
|
||||||
use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError;
|
use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError;
|
||||||
use rustc_infer::infer::region_constraints::Constraint;
|
use rustc_infer::infer::region_constraints::Constraint;
|
||||||
use rustc_infer::infer::region_constraints::RegionConstraintData;
|
|
||||||
use rustc_infer::infer::RegionVariableOrigin;
|
|
||||||
use rustc_infer::infer::{InferCtxt, RegionResolutionError, SubregionOrigin, TyCtxtInferExt as _};
|
use rustc_infer::infer::{InferCtxt, RegionResolutionError, SubregionOrigin, TyCtxtInferExt as _};
|
||||||
use rustc_infer::traits::{Normalized, ObligationCause, TraitEngine, TraitEngineExt};
|
use rustc_infer::traits::{Normalized, ObligationCause, TraitEngine, TraitEngineExt};
|
||||||
use rustc_middle::ty::error::TypeError;
|
use rustc_middle::ty::error::TypeError;
|
||||||
use rustc_middle::ty::RegionVid;
|
|
||||||
use rustc_middle::ty::UniverseIndex;
|
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::traits::query::type_op;
|
use rustc_trait_selection::traits::query::type_op;
|
||||||
|
@ -82,15 +78,6 @@ crate trait ToUniverseInfo<'tcx> {
|
||||||
fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx>;
|
fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ToUniverseInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
|
|
||||||
fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
|
|
||||||
UniverseInfo(UniverseInfoInner::TypeOp(Rc::new(crate::type_check::InstantiateOpaqueType {
|
|
||||||
base_universe: Some(base_universe),
|
|
||||||
..self
|
|
||||||
})))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> ToUniverseInfo<'tcx>
|
impl<'tcx> ToUniverseInfo<'tcx>
|
||||||
for Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::prove_predicate::ProvePredicate<'tcx>>>
|
for Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::prove_predicate::ProvePredicate<'tcx>>>
|
||||||
{
|
{
|
||||||
|
@ -131,12 +118,6 @@ impl<'tcx, F, G> ToUniverseInfo<'tcx> for Canonical<'tcx, type_op::custom::Custo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ToUniverseInfo<'tcx> for ! {
|
|
||||||
fn to_universe_info(self, _base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused_lifetimes)]
|
#[allow(unused_lifetimes)]
|
||||||
trait TypeOpInfo<'tcx> {
|
trait TypeOpInfo<'tcx> {
|
||||||
/// Returns an error to be reported if rerunning the type op fails to
|
/// Returns an error to be reported if rerunning the type op fails to
|
||||||
|
@ -147,7 +128,7 @@ trait TypeOpInfo<'tcx> {
|
||||||
|
|
||||||
fn nice_error(
|
fn nice_error(
|
||||||
&self,
|
&self,
|
||||||
mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
cause: ObligationCause<'tcx>,
|
cause: ObligationCause<'tcx>,
|
||||||
placeholder_region: ty::Region<'tcx>,
|
placeholder_region: ty::Region<'tcx>,
|
||||||
error_region: Option<ty::Region<'tcx>>,
|
error_region: Option<ty::Region<'tcx>>,
|
||||||
|
@ -194,7 +175,7 @@ trait TypeOpInfo<'tcx> {
|
||||||
debug!(?placeholder_region);
|
debug!(?placeholder_region);
|
||||||
|
|
||||||
let span = cause.span;
|
let span = cause.span;
|
||||||
let nice_error = self.nice_error(mbcx, cause, placeholder_region, error_region);
|
let nice_error = self.nice_error(tcx, cause, placeholder_region, error_region);
|
||||||
|
|
||||||
if let Some(nice_error) = nice_error {
|
if let Some(nice_error) = nice_error {
|
||||||
nice_error.buffer(&mut mbcx.errors_buffer);
|
nice_error.buffer(&mut mbcx.errors_buffer);
|
||||||
|
@ -223,16 +204,16 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
|
||||||
|
|
||||||
fn nice_error(
|
fn nice_error(
|
||||||
&self,
|
&self,
|
||||||
mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
cause: ObligationCause<'tcx>,
|
cause: ObligationCause<'tcx>,
|
||||||
placeholder_region: ty::Region<'tcx>,
|
placeholder_region: ty::Region<'tcx>,
|
||||||
error_region: Option<ty::Region<'tcx>>,
|
error_region: Option<ty::Region<'tcx>>,
|
||||||
) -> Option<DiagnosticBuilder<'tcx>> {
|
) -> Option<DiagnosticBuilder<'tcx>> {
|
||||||
mbcx.infcx.tcx.infer_ctxt().enter_with_canonical(
|
tcx.infer_ctxt().enter_with_canonical(
|
||||||
cause.span,
|
cause.span,
|
||||||
&self.canonical_query,
|
&self.canonical_query,
|
||||||
|ref infcx, key, _| {
|
|ref infcx, key, _| {
|
||||||
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
|
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(tcx);
|
||||||
type_op_prove_predicate_with_cause(infcx, &mut *fulfill_cx, key, cause);
|
type_op_prove_predicate_with_cause(infcx, &mut *fulfill_cx, key, cause);
|
||||||
try_extract_error_from_fulfill_cx(
|
try_extract_error_from_fulfill_cx(
|
||||||
fulfill_cx,
|
fulfill_cx,
|
||||||
|
@ -266,16 +247,16 @@ where
|
||||||
|
|
||||||
fn nice_error(
|
fn nice_error(
|
||||||
&self,
|
&self,
|
||||||
mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
cause: ObligationCause<'tcx>,
|
cause: ObligationCause<'tcx>,
|
||||||
placeholder_region: ty::Region<'tcx>,
|
placeholder_region: ty::Region<'tcx>,
|
||||||
error_region: Option<ty::Region<'tcx>>,
|
error_region: Option<ty::Region<'tcx>>,
|
||||||
) -> Option<DiagnosticBuilder<'tcx>> {
|
) -> Option<DiagnosticBuilder<'tcx>> {
|
||||||
mbcx.infcx.tcx.infer_ctxt().enter_with_canonical(
|
tcx.infer_ctxt().enter_with_canonical(
|
||||||
cause.span,
|
cause.span,
|
||||||
&self.canonical_query,
|
&self.canonical_query,
|
||||||
|ref infcx, key, _| {
|
|ref infcx, key, _| {
|
||||||
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
|
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(tcx);
|
||||||
|
|
||||||
let mut selcx = SelectionContext::new(infcx);
|
let mut selcx = SelectionContext::new(infcx);
|
||||||
|
|
||||||
|
@ -323,16 +304,16 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
|
||||||
|
|
||||||
fn nice_error(
|
fn nice_error(
|
||||||
&self,
|
&self,
|
||||||
mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
cause: ObligationCause<'tcx>,
|
cause: ObligationCause<'tcx>,
|
||||||
placeholder_region: ty::Region<'tcx>,
|
placeholder_region: ty::Region<'tcx>,
|
||||||
error_region: Option<ty::Region<'tcx>>,
|
error_region: Option<ty::Region<'tcx>>,
|
||||||
) -> Option<DiagnosticBuilder<'tcx>> {
|
) -> Option<DiagnosticBuilder<'tcx>> {
|
||||||
mbcx.infcx.tcx.infer_ctxt().enter_with_canonical(
|
tcx.infer_ctxt().enter_with_canonical(
|
||||||
cause.span,
|
cause.span,
|
||||||
&self.canonical_query,
|
&self.canonical_query,
|
||||||
|ref infcx, key, _| {
|
|ref infcx, key, _| {
|
||||||
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
|
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(tcx);
|
||||||
type_op_ascribe_user_type_with_span(infcx, &mut *fulfill_cx, key, Some(cause.span))
|
type_op_ascribe_user_type_with_span(infcx, &mut *fulfill_cx, key, Some(cause.span))
|
||||||
.ok()?;
|
.ok()?;
|
||||||
try_extract_error_from_fulfill_cx(
|
try_extract_error_from_fulfill_cx(
|
||||||
|
@ -346,39 +327,6 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
|
|
||||||
fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
|
||||||
// FIXME: This error message isn't great, but it doesn't show up in the existing UI tests,
|
|
||||||
// and is only the fallback when the nice error fails. Consider improving this some more.
|
|
||||||
tcx.sess.struct_span_err(span, "higher-ranked lifetime error for opaque type!")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn base_universe(&self) -> ty::UniverseIndex {
|
|
||||||
self.base_universe.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn nice_error(
|
|
||||||
&self,
|
|
||||||
mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
|
|
||||||
_cause: ObligationCause<'tcx>,
|
|
||||||
placeholder_region: ty::Region<'tcx>,
|
|
||||||
error_region: Option<ty::Region<'tcx>>,
|
|
||||||
) -> Option<DiagnosticBuilder<'tcx>> {
|
|
||||||
try_extract_error_from_region_constraints(
|
|
||||||
mbcx.infcx,
|
|
||||||
placeholder_region,
|
|
||||||
error_region,
|
|
||||||
self.region_constraints.as_ref().unwrap(),
|
|
||||||
// We're using the original `InferCtxt` that we
|
|
||||||
// started MIR borrowchecking with, so the region
|
|
||||||
// constraints have already been taken. Use the data from
|
|
||||||
// our `mbcx` instead.
|
|
||||||
|vid| mbcx.regioncx.var_infos[vid].origin,
|
|
||||||
|vid| mbcx.regioncx.var_infos[vid].universe,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(skip(fulfill_cx, infcx), level = "debug")]
|
#[instrument(skip(fulfill_cx, infcx), level = "debug")]
|
||||||
fn try_extract_error_from_fulfill_cx<'tcx>(
|
fn try_extract_error_from_fulfill_cx<'tcx>(
|
||||||
mut fulfill_cx: Box<dyn TraitEngine<'tcx> + 'tcx>,
|
mut fulfill_cx: Box<dyn TraitEngine<'tcx> + 'tcx>,
|
||||||
|
@ -386,30 +334,15 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
|
||||||
placeholder_region: ty::Region<'tcx>,
|
placeholder_region: ty::Region<'tcx>,
|
||||||
error_region: Option<ty::Region<'tcx>>,
|
error_region: Option<ty::Region<'tcx>>,
|
||||||
) -> Option<DiagnosticBuilder<'tcx>> {
|
) -> Option<DiagnosticBuilder<'tcx>> {
|
||||||
|
let tcx = infcx.tcx;
|
||||||
|
|
||||||
// We generally shouldn't have errors here because the query was
|
// We generally shouldn't have errors here because the query was
|
||||||
// already run, but there's no point using `delay_span_bug`
|
// already run, but there's no point using `delay_span_bug`
|
||||||
// when we're going to emit an error here anyway.
|
// when we're going to emit an error here anyway.
|
||||||
let _errors = fulfill_cx.select_all_or_error(infcx);
|
let _errors = fulfill_cx.select_all_or_error(infcx);
|
||||||
let region_constraints = infcx.with_region_constraints(|r| r.clone());
|
|
||||||
try_extract_error_from_region_constraints(
|
|
||||||
infcx,
|
|
||||||
placeholder_region,
|
|
||||||
error_region,
|
|
||||||
®ion_constraints,
|
|
||||||
|vid| infcx.region_var_origin(vid),
|
|
||||||
|vid| infcx.universe_of_region(infcx.tcx.mk_region(ty::ReVar(vid))),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn try_extract_error_from_region_constraints<'tcx>(
|
let (sub_region, cause) = infcx.with_region_constraints(|region_constraints| {
|
||||||
infcx: &InferCtxt<'_, 'tcx>,
|
debug!("{:#?}", region_constraints);
|
||||||
placeholder_region: ty::Region<'tcx>,
|
|
||||||
error_region: Option<ty::Region<'tcx>>,
|
|
||||||
region_constraints: &RegionConstraintData<'tcx>,
|
|
||||||
mut region_var_origin: impl FnMut(RegionVid) -> RegionVariableOrigin,
|
|
||||||
mut universe_of_region: impl FnMut(RegionVid) -> UniverseIndex,
|
|
||||||
) -> Option<DiagnosticBuilder<'tcx>> {
|
|
||||||
let (sub_region, cause) =
|
|
||||||
region_constraints.constraints.iter().find_map(|(constraint, cause)| {
|
region_constraints.constraints.iter().find_map(|(constraint, cause)| {
|
||||||
match *constraint {
|
match *constraint {
|
||||||
Constraint::RegSubReg(sub, sup) if sup == placeholder_region && sup != sub => {
|
Constraint::RegSubReg(sub, sup) if sup == placeholder_region && sup != sub => {
|
||||||
|
@ -417,11 +350,12 @@ fn try_extract_error_from_region_constraints<'tcx>(
|
||||||
}
|
}
|
||||||
// FIXME: Should this check the universe of the var?
|
// FIXME: Should this check the universe of the var?
|
||||||
Constraint::VarSubReg(vid, sup) if sup == placeholder_region => {
|
Constraint::VarSubReg(vid, sup) if sup == placeholder_region => {
|
||||||
Some((infcx.tcx.mk_region(ty::ReVar(vid)), cause.clone()))
|
Some((tcx.mk_region(ty::ReVar(vid)), cause.clone()))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
})?;
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
debug!(?sub_region, "cause = {:#?}", cause);
|
debug!(?sub_region, "cause = {:#?}", cause);
|
||||||
let nice_error = match (error_region, sub_region) {
|
let nice_error = match (error_region, sub_region) {
|
||||||
|
@ -429,7 +363,7 @@ fn try_extract_error_from_region_constraints<'tcx>(
|
||||||
infcx,
|
infcx,
|
||||||
RegionResolutionError::SubSupConflict(
|
RegionResolutionError::SubSupConflict(
|
||||||
vid,
|
vid,
|
||||||
region_var_origin(vid),
|
infcx.region_var_origin(vid),
|
||||||
cause.clone(),
|
cause.clone(),
|
||||||
error_region,
|
error_region,
|
||||||
cause.clone(),
|
cause.clone(),
|
||||||
|
@ -446,8 +380,8 @@ fn try_extract_error_from_region_constraints<'tcx>(
|
||||||
infcx,
|
infcx,
|
||||||
RegionResolutionError::UpperBoundUniverseConflict(
|
RegionResolutionError::UpperBoundUniverseConflict(
|
||||||
vid,
|
vid,
|
||||||
region_var_origin(vid),
|
infcx.region_var_origin(vid),
|
||||||
universe_of_region(vid),
|
infcx.universe_of_region(sub_region),
|
||||||
cause.clone(),
|
cause.clone(),
|
||||||
placeholder_region,
|
placeholder_region,
|
||||||
),
|
),
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(let_else)]
|
#![feature(let_else)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
#![feature(never_type)]
|
|
||||||
#![feature(stmt_expr_attributes)]
|
#![feature(stmt_expr_attributes)]
|
||||||
#![feature(trusted_step)]
|
#![feature(trusted_step)]
|
||||||
#![feature(try_blocks)]
|
#![feature(try_blocks)]
|
||||||
|
|
|
@ -44,7 +44,6 @@ mod reverse_sccs;
|
||||||
pub mod values;
|
pub mod values;
|
||||||
|
|
||||||
pub struct RegionInferenceContext<'tcx> {
|
pub struct RegionInferenceContext<'tcx> {
|
||||||
pub var_infos: VarInfos,
|
|
||||||
/// Contains the definition for every region variable. Region
|
/// Contains the definition for every region variable. Region
|
||||||
/// variables are identified by their index (`RegionVid`). The
|
/// variables are identified by their index (`RegionVid`). The
|
||||||
/// definition contains information about where the region came
|
/// definition contains information about where the region came
|
||||||
|
@ -267,7 +266,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// Create a RegionDefinition for each inference variable.
|
// Create a RegionDefinition for each inference variable.
|
||||||
let definitions: IndexVec<_, _> = var_infos
|
let definitions: IndexVec<_, _> = var_infos
|
||||||
.iter()
|
.into_iter()
|
||||||
.map(|info| RegionDefinition::new(info.universe, info.origin))
|
.map(|info| RegionDefinition::new(info.universe, info.origin))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -292,7 +291,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
Rc::new(member_constraints_in.into_mapped(|r| constraint_sccs.scc(r)));
|
Rc::new(member_constraints_in.into_mapped(|r| constraint_sccs.scc(r)));
|
||||||
|
|
||||||
let mut result = Self {
|
let mut result = Self {
|
||||||
var_infos,
|
|
||||||
definitions,
|
definitions,
|
||||||
liveness_constraints,
|
liveness_constraints,
|
||||||
constraints,
|
constraints,
|
||||||
|
|
|
@ -33,11 +33,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
) -> Fallible<R>
|
) -> Fallible<R>
|
||||||
where
|
where
|
||||||
Op: type_op::TypeOp<'tcx, Output = R>,
|
Op: type_op::TypeOp<'tcx, Output = R>,
|
||||||
Op::ErrorInfo: ToUniverseInfo<'tcx>,
|
Canonical<'tcx, Op>: ToUniverseInfo<'tcx>,
|
||||||
{
|
{
|
||||||
let old_universe = self.infcx.universe();
|
let old_universe = self.infcx.universe();
|
||||||
|
|
||||||
let TypeOpOutput { output, constraints, error_info } = op.fully_perform(self.infcx)?;
|
let TypeOpOutput { output, constraints, canonicalized_query } =
|
||||||
|
op.fully_perform(self.infcx)?;
|
||||||
|
|
||||||
if let Some(data) = &constraints {
|
if let Some(data) = &constraints {
|
||||||
self.push_region_constraints(locations, category, data);
|
self.push_region_constraints(locations, category, data);
|
||||||
|
@ -46,8 +47,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
let universe = self.infcx.universe();
|
let universe = self.infcx.universe();
|
||||||
|
|
||||||
if old_universe != universe {
|
if old_universe != universe {
|
||||||
let universe_info = match error_info {
|
let universe_info = match canonicalized_query {
|
||||||
Some(error_info) => error_info.to_universe_info(old_universe),
|
Some(canonicalized_query) => canonicalized_query.to_universe_info(old_universe),
|
||||||
None => UniverseInfo::other(),
|
None => UniverseInfo::other(),
|
||||||
};
|
};
|
||||||
for u in old_universe..universe {
|
for u in old_universe..universe {
|
||||||
|
|
|
@ -268,7 +268,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
|
||||||
TypeOpOutput {
|
TypeOpOutput {
|
||||||
output: self.infcx.tcx.ty_error(),
|
output: self.infcx.tcx.ty_error(),
|
||||||
constraints: None,
|
constraints: None,
|
||||||
error_info: None,
|
canonicalized_query: None,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Note: we need this in examples like
|
// Note: we need this in examples like
|
||||||
|
|
|
@ -17,7 +17,6 @@ use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_index::vec::{Idx, IndexVec};
|
use rustc_index::vec::{Idx, IndexVec};
|
||||||
use rustc_infer::infer::canonical::QueryRegionConstraints;
|
use rustc_infer::infer::canonical::QueryRegionConstraints;
|
||||||
use rustc_infer::infer::outlives::env::RegionBoundPairs;
|
use rustc_infer::infer::outlives::env::RegionBoundPairs;
|
||||||
use rustc_infer::infer::region_constraints::RegionConstraintData;
|
|
||||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||||
use rustc_infer::infer::{
|
use rustc_infer::infer::{
|
||||||
InferCtxt, InferOk, LateBoundRegionConversionTime, NllRegionVariableOrigin,
|
InferCtxt, InferOk, LateBoundRegionConversionTime, NllRegionVariableOrigin,
|
||||||
|
@ -40,11 +39,9 @@ use rustc_target::abi::VariantIdx;
|
||||||
use rustc_trait_selection::infer::InferCtxtExt as _;
|
use rustc_trait_selection::infer::InferCtxtExt as _;
|
||||||
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
|
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
|
||||||
use rustc_trait_selection::traits::query::type_op;
|
use rustc_trait_selection::traits::query::type_op;
|
||||||
use rustc_trait_selection::traits::query::type_op::custom::scrape_region_constraints;
|
|
||||||
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::Fallible;
|
use rustc_trait_selection::traits::query::Fallible;
|
||||||
use rustc_trait_selection::traits::{self, ObligationCause, PredicateObligation};
|
use rustc_trait_selection::traits::{self, ObligationCause};
|
||||||
|
|
||||||
use rustc_const_eval::transform::{
|
use rustc_const_eval::transform::{
|
||||||
check_consts::ConstCx, promote_consts::is_const_fn_in_array_repeat_expression,
|
check_consts::ConstCx, promote_consts::is_const_fn_in_array_repeat_expression,
|
||||||
|
@ -2640,32 +2637,3 @@ impl NormalizeLocation for Location {
|
||||||
Locations::Single(self)
|
Locations::Single(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Runs `infcx.instantiate_opaque_types`. Unlike other `TypeOp`s,
|
|
||||||
/// this is not canonicalized - it directly affects the main `InferCtxt`
|
|
||||||
/// that we use during MIR borrowchecking.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub(super) struct InstantiateOpaqueType<'tcx> {
|
|
||||||
pub base_universe: Option<ty::UniverseIndex>,
|
|
||||||
pub region_constraints: Option<RegionConstraintData<'tcx>>,
|
|
||||||
pub obligation: PredicateObligation<'tcx>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> {
|
|
||||||
type Output = ();
|
|
||||||
/// We use this type itself to store the information used
|
|
||||||
/// when reporting errors. Since this is not a query, we don't
|
|
||||||
/// re-run anything during error reporting - we just use the information
|
|
||||||
/// we saved to help extract an error from the already-existing region
|
|
||||||
/// constraints in our `InferCtxt`
|
|
||||||
type ErrorInfo = InstantiateOpaqueType<'tcx>;
|
|
||||||
|
|
||||||
fn fully_perform(mut self, infcx: &InferCtxt<'_, 'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>> {
|
|
||||||
let (mut output, region_constraints) = scrape_region_constraints(infcx, || {
|
|
||||||
Ok(InferOk { value: (), obligations: vec![self.obligation.clone()] })
|
|
||||||
})?;
|
|
||||||
self.region_constraints = Some(region_constraints);
|
|
||||||
output.error_info = Some(self);
|
|
||||||
Ok(output)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate};
|
use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate};
|
||||||
use rustc_infer::infer::NllRegionVariableOrigin;
|
use rustc_infer::infer::{InferOk, NllRegionVariableOrigin};
|
||||||
use rustc_infer::traits::ObligationCause;
|
use rustc_infer::traits::ObligationCause;
|
||||||
use rustc_middle::mir::ConstraintCategory;
|
use rustc_middle::mir::ConstraintCategory;
|
||||||
use rustc_middle::ty::relate::TypeRelation;
|
use rustc_middle::ty::relate::TypeRelation;
|
||||||
|
@ -9,7 +9,7 @@ use rustc_trait_selection::traits::query::Fallible;
|
||||||
|
|
||||||
use crate::constraints::OutlivesConstraint;
|
use crate::constraints::OutlivesConstraint;
|
||||||
use crate::diagnostics::UniverseInfo;
|
use crate::diagnostics::UniverseInfo;
|
||||||
use crate::type_check::{InstantiateOpaqueType, Locations, TypeChecker};
|
use crate::type_check::{CustomTypeOp, Locations, TypeChecker};
|
||||||
|
|
||||||
impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
/// Adds sufficient constraints to ensure that `a R b` where `R` depends on `v`:
|
/// Adds sufficient constraints to ensure that `a R b` where `R` depends on `v`:
|
||||||
|
@ -146,18 +146,21 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
|
||||||
.fully_perform_op(
|
.fully_perform_op(
|
||||||
self.locations,
|
self.locations,
|
||||||
self.category,
|
self.category,
|
||||||
InstantiateOpaqueType {
|
CustomTypeOp::new(
|
||||||
obligation: self.type_checker.infcx.opaque_ty_obligation(
|
|infcx| {
|
||||||
a,
|
Ok(InferOk {
|
||||||
b,
|
value: (),
|
||||||
a_is_expected,
|
obligations: vec![infcx.opaque_ty_obligation(
|
||||||
param_env,
|
a,
|
||||||
cause,
|
b,
|
||||||
),
|
a_is_expected,
|
||||||
// These fields are filled in during exectuion of the operation
|
param_env,
|
||||||
base_universe: None,
|
cause,
|
||||||
region_constraints: None,
|
)],
|
||||||
},
|
})
|
||||||
|
},
|
||||||
|
|| "register_opaque_type".to_string(),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#![feature(control_flow_enum)]
|
#![feature(control_flow_enum)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
#![feature(label_break_value)]
|
#![feature(label_break_value)]
|
||||||
#![feature(backtrace)]
|
|
||||||
#![recursion_limit = "512"] // For rustdoc
|
#![recursion_limit = "512"] // For rustdoc
|
||||||
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]
|
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ use crate::traits::engine::TraitEngineExt as _;
|
||||||
use crate::traits::query::type_op::TypeOpOutput;
|
use crate::traits::query::type_op::TypeOpOutput;
|
||||||
use crate::traits::query::Fallible;
|
use crate::traits::query::Fallible;
|
||||||
use crate::traits::TraitEngine;
|
use crate::traits::TraitEngine;
|
||||||
use rustc_infer::infer::region_constraints::RegionConstraintData;
|
|
||||||
use rustc_infer::traits::TraitEngineExt as _;
|
use rustc_infer::traits::TraitEngineExt as _;
|
||||||
use rustc_span::source_map::DUMMY_SP;
|
use rustc_span::source_map::DUMMY_SP;
|
||||||
|
|
||||||
|
@ -32,9 +31,6 @@ where
|
||||||
G: Fn() -> String,
|
G: Fn() -> String,
|
||||||
{
|
{
|
||||||
type Output = R;
|
type Output = R;
|
||||||
/// We can't do any custom error reporting for `CustomTypeOp`, so
|
|
||||||
/// we can use `!` to enforce that the implementation never provides it.
|
|
||||||
type ErrorInfo = !;
|
|
||||||
|
|
||||||
/// Processes the operation and all resulting obligations,
|
/// Processes the operation and all resulting obligations,
|
||||||
/// returning the final result along with any region constraints
|
/// returning the final result along with any region constraints
|
||||||
|
@ -44,7 +40,7 @@ where
|
||||||
info!("fully_perform({:?})", self);
|
info!("fully_perform({:?})", self);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(scrape_region_constraints(infcx, || (self.closure)(infcx))?.0)
|
scrape_region_constraints(infcx, || (self.closure)(infcx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,10 +55,10 @@ where
|
||||||
|
|
||||||
/// Executes `op` and then scrapes out all the "old style" region
|
/// Executes `op` and then scrapes out all the "old style" region
|
||||||
/// constraints that result, creating query-region-constraints.
|
/// constraints that result, creating query-region-constraints.
|
||||||
pub fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>(
|
fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>(
|
||||||
infcx: &InferCtxt<'_, 'tcx>,
|
infcx: &InferCtxt<'_, 'tcx>,
|
||||||
op: impl FnOnce() -> Fallible<InferOk<'tcx, R>>,
|
op: impl FnOnce() -> Fallible<InferOk<'tcx, R>>,
|
||||||
) -> Fallible<(TypeOpOutput<'tcx, Op>, RegionConstraintData<'tcx>)> {
|
) -> Fallible<TypeOpOutput<'tcx, Op>> {
|
||||||
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
|
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
|
||||||
|
|
||||||
// During NLL, we expect that nobody will register region
|
// During NLL, we expect that nobody will register region
|
||||||
|
@ -101,18 +97,12 @@ pub fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>(
|
||||||
);
|
);
|
||||||
|
|
||||||
if region_constraints.is_empty() {
|
if region_constraints.is_empty() {
|
||||||
Ok((
|
Ok(TypeOpOutput { output: value, constraints: None, canonicalized_query: None })
|
||||||
TypeOpOutput { output: value, constraints: None, error_info: None },
|
|
||||||
region_constraint_data,
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
Ok((
|
Ok(TypeOpOutput {
|
||||||
TypeOpOutput {
|
output: value,
|
||||||
output: value,
|
constraints: Some(Rc::new(region_constraints)),
|
||||||
constraints: Some(Rc::new(region_constraints)),
|
canonicalized_query: None,
|
||||||
error_info: None,
|
})
|
||||||
},
|
|
||||||
region_constraint_data,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ pub use rustc_middle::traits::query::type_op::*;
|
||||||
/// cannot be completed).
|
/// cannot be completed).
|
||||||
pub trait TypeOp<'tcx>: Sized + fmt::Debug {
|
pub trait TypeOp<'tcx>: Sized + fmt::Debug {
|
||||||
type Output;
|
type Output;
|
||||||
type ErrorInfo;
|
|
||||||
|
|
||||||
/// Processes the operation and all resulting obligations,
|
/// Processes the operation and all resulting obligations,
|
||||||
/// returning the final result along with any region constraints
|
/// returning the final result along with any region constraints
|
||||||
|
@ -42,8 +41,9 @@ pub struct TypeOpOutput<'tcx, Op: TypeOp<'tcx>> {
|
||||||
pub output: Op::Output,
|
pub output: Op::Output,
|
||||||
/// Any region constraints from performing the type op.
|
/// Any region constraints from performing the type op.
|
||||||
pub constraints: Option<Rc<QueryRegionConstraints<'tcx>>>,
|
pub constraints: Option<Rc<QueryRegionConstraints<'tcx>>>,
|
||||||
/// Used for error reporting to be able to rerun the query
|
/// The canonicalized form of the query.
|
||||||
pub error_info: Option<Op::ErrorInfo>,
|
/// This for error reporting to be able to rerun the query.
|
||||||
|
pub canonicalized_query: Option<Canonical<'tcx, Op>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "Query type ops" are type ops that are implemented using a
|
/// "Query type ops" are type ops that are implemented using a
|
||||||
|
@ -119,11 +119,10 @@ where
|
||||||
Q: QueryTypeOp<'tcx>,
|
Q: QueryTypeOp<'tcx>,
|
||||||
{
|
{
|
||||||
type Output = Q::QueryResponse;
|
type Output = Q::QueryResponse;
|
||||||
type ErrorInfo = Canonical<'tcx, ParamEnvAnd<'tcx, Q>>;
|
|
||||||
|
|
||||||
fn fully_perform(self, infcx: &InferCtxt<'_, 'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>> {
|
fn fully_perform(self, infcx: &InferCtxt<'_, 'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>> {
|
||||||
let mut region_constraints = QueryRegionConstraints::default();
|
let mut region_constraints = QueryRegionConstraints::default();
|
||||||
let (output, error_info, mut obligations, _) =
|
let (output, canonicalized_query, mut obligations, _) =
|
||||||
Q::fully_perform_into(self, infcx, &mut region_constraints)?;
|
Q::fully_perform_into(self, infcx, &mut region_constraints)?;
|
||||||
|
|
||||||
// Typically, instantiating NLL query results does not
|
// Typically, instantiating NLL query results does not
|
||||||
|
@ -161,6 +160,6 @@ where
|
||||||
let region_constraints =
|
let region_constraints =
|
||||||
if region_constraints.is_empty() { None } else { Some(Rc::new(region_constraints)) };
|
if region_constraints.is_empty() { None } else { Some(Rc::new(region_constraints)) };
|
||||||
|
|
||||||
Ok(TypeOpOutput { output, constraints: region_constraints, error_info })
|
Ok(TypeOpOutput { output, constraints: region_constraints, canonicalized_query })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,14 @@
|
||||||
error: implementation of `Hrtb` is not general enough
|
error: higher-ranked subtype error
|
||||||
--> $DIR/issue-88236-2.rs:17:5
|
--> $DIR/issue-88236-2.rs:17:5
|
||||||
|
|
|
|
||||||
LL | &()
|
LL | &()
|
||||||
| ^^^ implementation of `Hrtb` is not general enough
|
| ^^^
|
||||||
|
|
|
||||||
= note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`...
|
|
||||||
= note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1`
|
|
||||||
|
|
||||||
error: implementation of `Hrtb` is not general enough
|
error: higher-ranked subtype error
|
||||||
--> $DIR/issue-88236-2.rs:17:5
|
--> $DIR/issue-88236-2.rs:17:5
|
||||||
|
|
|
|
||||||
LL | &()
|
LL | &()
|
||||||
| ^^^ implementation of `Hrtb` is not general enough
|
| ^^^
|
||||||
|
|
|
||||||
= note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`...
|
|
||||||
= note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1`
|
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/issue-88236-2.rs:20:5
|
--> $DIR/issue-88236-2.rs:20:5
|
||||||
|
@ -29,23 +23,17 @@ help: to allow this `impl Trait` to capture borrowed data with lifetime `'b`, ad
|
||||||
LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> + 'b {
|
LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> + 'b {
|
||||||
| ++++
|
| ++++
|
||||||
|
|
||||||
error: implementation of `Hrtb` is not general enough
|
error: higher-ranked subtype error
|
||||||
--> $DIR/issue-88236-2.rs:20:5
|
--> $DIR/issue-88236-2.rs:20:5
|
||||||
|
|
|
|
||||||
LL | x
|
LL | x
|
||||||
| ^ implementation of `Hrtb` is not general enough
|
| ^
|
||||||
|
|
|
||||||
= note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`...
|
|
||||||
= note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1`
|
|
||||||
|
|
||||||
error: implementation of `Hrtb` is not general enough
|
error: higher-ranked subtype error
|
||||||
--> $DIR/issue-88236-2.rs:20:5
|
--> $DIR/issue-88236-2.rs:20:5
|
||||||
|
|
|
|
||||||
LL | x
|
LL | x
|
||||||
| ^ implementation of `Hrtb` is not general enough
|
| ^
|
||||||
|
|
|
||||||
= note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`...
|
|
||||||
= note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1`
|
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
#![feature(nll)]
|
|
||||||
|
|
||||||
trait MyTrait<T> {}
|
|
||||||
|
|
||||||
struct Foo;
|
|
||||||
impl<T> MyTrait<T> for Foo {}
|
|
||||||
|
|
||||||
fn bar<Input>() -> impl MyTrait<Input> {
|
|
||||||
Foo
|
|
||||||
}
|
|
||||||
|
|
||||||
fn foo() -> impl for<'a> MyTrait<&'a str> {
|
|
||||||
bar() //~ ERROR implementation of `MyTrait` is not general enough
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {}
|
|
|
@ -1,11 +0,0 @@
|
||||||
error: implementation of `MyTrait` is not general enough
|
|
||||||
--> $DIR/opaque-hrtb.rs:13:5
|
|
||||||
|
|
|
||||||
LL | bar()
|
|
||||||
| ^^^^^ implementation of `MyTrait` is not general enough
|
|
||||||
|
|
|
||||||
= note: `impl MyTrait<&'2 str>` must implement `MyTrait<&'1 str>`, for any lifetime `'1`...
|
|
||||||
= note: ...but it actually implements `MyTrait<&'2 str>`, for some specific lifetime `'2`
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
|
@ -1,26 +1,14 @@
|
||||||
error[E0308]: mismatched types
|
error: higher-ranked subtype error
|
||||||
--> $DIR/issue-57611-trait-alias.rs:20:9
|
|
||||||
|
|
|
||||||
LL | |x| x
|
|
||||||
| ^^^^^ one type is more general than the other
|
|
||||||
|
|
|
||||||
= note: expected type `for<'r> Fn<(&'r X,)>`
|
|
||||||
found type `Fn<(&X,)>`
|
|
||||||
note: this closure does not fulfill the lifetime requirements
|
|
||||||
--> $DIR/issue-57611-trait-alias.rs:20:9
|
--> $DIR/issue-57611-trait-alias.rs:20:9
|
||||||
|
|
|
|
||||||
LL | |x| x
|
LL | |x| x
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
error: implementation of `FnOnce` is not general enough
|
error: higher-ranked subtype error
|
||||||
--> $DIR/issue-57611-trait-alias.rs:20:9
|
--> $DIR/issue-57611-trait-alias.rs:20:9
|
||||||
|
|
|
|
||||||
LL | |x| x
|
LL | |x| x
|
||||||
| ^^^^^ implementation of `FnOnce` is not general enough
|
| ^^^^^
|
||||||
|
|
|
||||||
= note: closure with signature `fn(&'2 X) -> &X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
|
|
||||||
= note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue