recompute opaque type origin
This commit is contained in:
parent
dcc9028c0c
commit
2278365889
4 changed files with 22 additions and 38 deletions
|
@ -61,7 +61,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
pub(crate) fn infer_opaque_types(
|
pub(crate) fn infer_opaque_types(
|
||||||
&self,
|
&self,
|
||||||
infcx: &InferCtxt<'tcx>,
|
infcx: &InferCtxt<'tcx>,
|
||||||
opaque_ty_decls: FxIndexMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>,
|
opaque_ty_decls: FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
|
||||||
) -> FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> {
|
) -> FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> {
|
||||||
let mut result: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> = FxIndexMap::default();
|
let mut result: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> = FxIndexMap::default();
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
.collect();
|
.collect();
|
||||||
debug!(?member_constraints);
|
debug!(?member_constraints);
|
||||||
|
|
||||||
for (opaque_type_key, (concrete_type, origin)) in opaque_ty_decls {
|
for (opaque_type_key, concrete_type) in opaque_ty_decls {
|
||||||
let substs = opaque_type_key.substs;
|
let substs = opaque_type_key.substs;
|
||||||
debug!(?concrete_type, ?substs);
|
debug!(?concrete_type, ?substs);
|
||||||
|
|
||||||
|
@ -143,7 +143,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
let ty = infcx.infer_opaque_definition_from_instantiation(
|
let ty = infcx.infer_opaque_definition_from_instantiation(
|
||||||
opaque_type_key,
|
opaque_type_key,
|
||||||
universal_concrete_type,
|
universal_concrete_type,
|
||||||
origin,
|
|
||||||
);
|
);
|
||||||
// Sometimes two opaque types are the same only after we remap the generic parameters
|
// Sometimes two opaque types are the same only after we remap the generic parameters
|
||||||
// back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to `(X, Y)`
|
// back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to `(X, Y)`
|
||||||
|
@ -215,7 +214,6 @@ pub trait InferCtxtExt<'tcx> {
|
||||||
&self,
|
&self,
|
||||||
opaque_type_key: OpaqueTypeKey<'tcx>,
|
opaque_type_key: OpaqueTypeKey<'tcx>,
|
||||||
instantiated_ty: OpaqueHiddenType<'tcx>,
|
instantiated_ty: OpaqueHiddenType<'tcx>,
|
||||||
origin: OpaqueTyOrigin,
|
|
||||||
) -> Ty<'tcx>;
|
) -> Ty<'tcx>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +246,6 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||||
&self,
|
&self,
|
||||||
opaque_type_key: OpaqueTypeKey<'tcx>,
|
opaque_type_key: OpaqueTypeKey<'tcx>,
|
||||||
instantiated_ty: OpaqueHiddenType<'tcx>,
|
instantiated_ty: OpaqueHiddenType<'tcx>,
|
||||||
origin: OpaqueTyOrigin,
|
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
if let Some(e) = self.tainted_by_errors() {
|
if let Some(e) = self.tainted_by_errors() {
|
||||||
return self.tcx.ty_error(e);
|
return self.tcx.ty_error(e);
|
||||||
|
@ -258,18 +255,16 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||||
.remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false)
|
.remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false)
|
||||||
.ty;
|
.ty;
|
||||||
|
|
||||||
if let Err(guar) = check_opaque_type_parameter_valid(
|
if let Err(guar) =
|
||||||
self.tcx,
|
check_opaque_type_parameter_valid(self.tcx, opaque_type_key, instantiated_ty.span)
|
||||||
opaque_type_key,
|
{
|
||||||
origin,
|
|
||||||
instantiated_ty.span,
|
|
||||||
) {
|
|
||||||
return self.tcx.ty_error(guar);
|
return self.tcx.ty_error(guar);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs`
|
// Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs`
|
||||||
// on stable and we'd break that.
|
// on stable and we'd break that.
|
||||||
let OpaqueTyOrigin::TyAlias { .. } = origin else {
|
let opaque_ty_hir = self.tcx.hir().expect_item(opaque_type_key.def_id);
|
||||||
|
let OpaqueTyOrigin::TyAlias { .. } = opaque_ty_hir.expect_opaque_ty().origin else {
|
||||||
return definition_ty;
|
return definition_ty;
|
||||||
};
|
};
|
||||||
let def_id = opaque_type_key.def_id;
|
let def_id = opaque_type_key.def_id;
|
||||||
|
@ -347,10 +342,10 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||||
fn check_opaque_type_parameter_valid(
|
fn check_opaque_type_parameter_valid(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
opaque_type_key: OpaqueTypeKey<'_>,
|
opaque_type_key: OpaqueTypeKey<'_>,
|
||||||
origin: OpaqueTyOrigin,
|
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
match origin {
|
let opaque_ty_hir = tcx.hir().expect_item(opaque_type_key.def_id);
|
||||||
|
match opaque_ty_hir.expect_opaque_ty().origin {
|
||||||
// No need to check return position impl trait (RPIT)
|
// No need to check return position impl trait (RPIT)
|
||||||
// because for type and const parameters they are correct
|
// because for type and const parameters they are correct
|
||||||
// by construction: we convert
|
// by construction: we convert
|
||||||
|
|
|
@ -7,7 +7,6 @@ use std::{fmt, iter, mem};
|
||||||
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
|
|
||||||
use hir::OpaqueTyOrigin;
|
|
||||||
use rustc_data_structures::frozen::Frozen;
|
use rustc_data_structures::frozen::Frozen;
|
||||||
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
||||||
use rustc_errors::ErrorGuaranteed;
|
use rustc_errors::ErrorGuaranteed;
|
||||||
|
@ -241,7 +240,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
||||||
hidden_type.ty = infcx.tcx.ty_error(reported);
|
hidden_type.ty = infcx.tcx.ty_error(reported);
|
||||||
}
|
}
|
||||||
|
|
||||||
(opaque_type_key, (hidden_type, decl.origin))
|
(opaque_type_key, hidden_type)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -878,8 +877,7 @@ struct BorrowCheckContext<'a, 'tcx> {
|
||||||
pub(crate) struct MirTypeckResults<'tcx> {
|
pub(crate) struct MirTypeckResults<'tcx> {
|
||||||
pub(crate) constraints: MirTypeckRegionConstraints<'tcx>,
|
pub(crate) constraints: MirTypeckRegionConstraints<'tcx>,
|
||||||
pub(crate) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
|
pub(crate) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
|
||||||
pub(crate) opaque_type_values:
|
pub(crate) opaque_type_values: FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
|
||||||
FxIndexMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A collection of region constraints that must be satisfied for the
|
/// A collection of region constraints that must be satisfied for the
|
||||||
|
|
|
@ -33,9 +33,6 @@ pub struct OpaqueTypeDecl<'tcx> {
|
||||||
/// There can be multiple, but they are all `lub`ed together at the end
|
/// There can be multiple, but they are all `lub`ed together at the end
|
||||||
/// to obtain the canonical hidden type.
|
/// to obtain the canonical hidden type.
|
||||||
pub hidden_type: OpaqueHiddenType<'tcx>,
|
pub hidden_type: OpaqueHiddenType<'tcx>,
|
||||||
|
|
||||||
/// The origin of the opaque type.
|
|
||||||
pub origin: hir::OpaqueTyOrigin,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> InferCtxt<'tcx> {
|
impl<'tcx> InferCtxt<'tcx> {
|
||||||
|
@ -108,7 +105,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
let process = |a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected| match *a.kind() {
|
let process = |a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected| match *a.kind() {
|
||||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) if def_id.is_local() => {
|
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) if def_id.is_local() => {
|
||||||
let def_id = def_id.expect_local();
|
let def_id = def_id.expect_local();
|
||||||
let origin = match self.defining_use_anchor {
|
match self.defining_use_anchor {
|
||||||
DefiningAnchor::Bind(_) => {
|
DefiningAnchor::Bind(_) => {
|
||||||
// Check that this is `impl Trait` type is
|
// Check that this is `impl Trait` type is
|
||||||
// declared by `parent_def_id` -- i.e., one whose
|
// declared by `parent_def_id` -- i.e., one whose
|
||||||
|
@ -144,9 +141,11 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
// let x = || foo(); // returns the Opaque assoc with `foo`
|
// let x = || foo(); // returns the Opaque assoc with `foo`
|
||||||
// }
|
// }
|
||||||
// ```
|
// ```
|
||||||
self.opaque_type_origin(def_id)?
|
if self.opaque_type_origin(def_id).is_none() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DefiningAnchor::Bubble => self.opaque_type_origin_unchecked(def_id),
|
DefiningAnchor::Bubble => {}
|
||||||
DefiningAnchor::Error => return None,
|
DefiningAnchor::Error => return None,
|
||||||
};
|
};
|
||||||
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }) = *b.kind() {
|
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }) = *b.kind() {
|
||||||
|
@ -170,7 +169,6 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
cause.clone(),
|
cause.clone(),
|
||||||
param_env,
|
param_env,
|
||||||
b,
|
b,
|
||||||
origin,
|
|
||||||
a_is_expected,
|
a_is_expected,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -524,7 +522,6 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
cause: ObligationCause<'tcx>,
|
cause: ObligationCause<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
hidden_ty: Ty<'tcx>,
|
hidden_ty: Ty<'tcx>,
|
||||||
origin: hir::OpaqueTyOrigin,
|
|
||||||
a_is_expected: bool,
|
a_is_expected: bool,
|
||||||
) -> InferResult<'tcx, ()> {
|
) -> InferResult<'tcx, ()> {
|
||||||
// Ideally, we'd get the span where *this specific `ty` came
|
// Ideally, we'd get the span where *this specific `ty` came
|
||||||
|
@ -544,11 +541,11 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
ty::PredicateKind::Ambiguous,
|
ty::PredicateKind::Ambiguous,
|
||||||
)]
|
)]
|
||||||
} else {
|
} else {
|
||||||
let prev = self.inner.borrow_mut().opaque_types().register(
|
let prev = self
|
||||||
opaque_type_key,
|
.inner
|
||||||
OpaqueHiddenType { ty: hidden_ty, span },
|
.borrow_mut()
|
||||||
origin,
|
.opaque_types()
|
||||||
);
|
.register(opaque_type_key, OpaqueHiddenType { ty: hidden_ty, span });
|
||||||
if let Some(prev) = prev {
|
if let Some(prev) = prev {
|
||||||
self.at(&cause, param_env)
|
self.at(&cause, param_env)
|
||||||
.eq_exp(DefineOpaqueTypes::Yes, a_is_expected, prev, hidden_ty)?
|
.eq_exp(DefineOpaqueTypes::Yes, a_is_expected, prev, hidden_ty)?
|
||||||
|
@ -579,15 +576,11 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
hidden_ty: Ty<'tcx>,
|
hidden_ty: Ty<'tcx>,
|
||||||
) -> InferResult<'tcx, ()> {
|
) -> InferResult<'tcx, ()> {
|
||||||
assert!(self.next_trait_solver());
|
assert!(self.next_trait_solver());
|
||||||
let origin = self
|
|
||||||
.opaque_type_origin(opaque_type_key.def_id)
|
|
||||||
.expect("should be called for defining usages only");
|
|
||||||
self.register_hidden_type(
|
self.register_hidden_type(
|
||||||
opaque_type_key,
|
opaque_type_key,
|
||||||
ObligationCause::dummy(),
|
ObligationCause::dummy(),
|
||||||
param_env,
|
param_env,
|
||||||
hidden_ty,
|
hidden_ty,
|
||||||
origin,
|
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use rustc_data_structures::undo_log::UndoLogs;
|
use rustc_data_structures::undo_log::UndoLogs;
|
||||||
use rustc_hir::OpaqueTyOrigin;
|
|
||||||
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty};
|
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty};
|
||||||
use rustc_span::DUMMY_SP;
|
use rustc_span::DUMMY_SP;
|
||||||
|
|
||||||
|
@ -60,14 +59,13 @@ impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
key: OpaqueTypeKey<'tcx>,
|
key: OpaqueTypeKey<'tcx>,
|
||||||
hidden_type: OpaqueHiddenType<'tcx>,
|
hidden_type: OpaqueHiddenType<'tcx>,
|
||||||
origin: OpaqueTyOrigin,
|
|
||||||
) -> Option<Ty<'tcx>> {
|
) -> Option<Ty<'tcx>> {
|
||||||
if let Some(decl) = self.storage.opaque_types.get_mut(&key) {
|
if let Some(decl) = self.storage.opaque_types.get_mut(&key) {
|
||||||
let prev = std::mem::replace(&mut decl.hidden_type, hidden_type);
|
let prev = std::mem::replace(&mut decl.hidden_type, hidden_type);
|
||||||
self.undo_log.push(UndoLog::OpaqueTypes(key, Some(prev)));
|
self.undo_log.push(UndoLog::OpaqueTypes(key, Some(prev)));
|
||||||
return Some(prev.ty);
|
return Some(prev.ty);
|
||||||
}
|
}
|
||||||
let decl = OpaqueTypeDecl { hidden_type, origin };
|
let decl = OpaqueTypeDecl { hidden_type };
|
||||||
self.storage.opaque_types.insert(key, decl);
|
self.storage.opaque_types.insert(key, decl);
|
||||||
self.undo_log.push(UndoLog::OpaqueTypes(key, None));
|
self.undo_log.push(UndoLog::OpaqueTypes(key, None));
|
||||||
None
|
None
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue