recompute opaque type origin

This commit is contained in:
lcnr 2023-06-09 14:48:45 +02:00
parent dcc9028c0c
commit 2278365889
4 changed files with 22 additions and 38 deletions

View file

@ -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

View file

@ -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

View file

@ -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,
) )
} }

View file

@ -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