Clean up leftovers from eager hidden type merging

This commit is contained in:
Oli Scherer 2022-01-26 15:10:01 +00:00
parent 38f50d1ecb
commit edaf9625fb
6 changed files with 34 additions and 109 deletions

View File

@ -18,7 +18,9 @@ use rustc_index::vec::{Idx, IndexVec};
use rustc_infer::infer::canonical::QueryRegionConstraints;
use rustc_infer::infer::outlives::env::RegionBoundPairs;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{InferCtxt, LateBoundRegionConversionTime, NllRegionVariableOrigin};
use rustc_infer::infer::{
InferCtxt, InferOk, LateBoundRegionConversionTime, NllRegionVariableOrigin,
};
use rustc_middle::mir::tcx::PlaceTy;
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::AssertKind;
@ -194,31 +196,24 @@ pub(crate) fn type_check<'mir, 'tcx>(
let opaque_type_values = opaque_type_values
.into_iter()
.filter_map(|(opaque_type_key, decl)| {
let def_id = body.source.def_id().expect_local();
let body_id = cx.tcx().hir().local_def_id_to_hir_id(def_id);
let cause = ObligationCause::misc(body.span, body_id);
let hidden = cx
.fully_perform_op(
Locations::All(body.span),
ConstraintCategory::OpaqueType,
CustomTypeOp::new(
|infcx| {
let res = decl
.hidden_type(infcx, &cause, param_env)
.map_err(|e| e.0)?;
infcx.register_member_constraints(
param_env,
opaque_type_key,
res.value.ty,
res.value.span,
);
Ok(res)
},
|| "opaque_type_map".to_string(),
),
)
.unwrap();
let mut hidden_type = infcx.resolve_vars_if_possible(hidden.ty);
cx.fully_perform_op(
Locations::All(body.span),
ConstraintCategory::OpaqueType,
CustomTypeOp::new(
|infcx| {
infcx.register_member_constraints(
param_env,
opaque_type_key,
decl.hidden_type.ty,
decl.hidden_type.span,
);
Ok(InferOk { value: (), obligations: vec![] })
},
|| "opaque_type_map".to_string(),
),
)
.unwrap();
let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type.ty);
trace!(
"finalized opaque type {:?} to {:#?}",
opaque_type_key,
@ -226,7 +221,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
);
if hidden_type.has_infer_types_or_consts() {
infcx.tcx.sess.delay_span_bug(
hidden.span,
decl.hidden_type.span,
&format!("could not resolve {:#?}", hidden_type.kind()),
);
hidden_type = infcx.tcx.ty_error();
@ -263,7 +258,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
);
None
} else {
Some((opaque_type_key, (hidden_type, hidden.span, decl.origin)))
Some((opaque_type_key, (hidden_type, decl.hidden_type.span, decl.origin)))
}
})
.collect();

View File

@ -146,13 +146,13 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
})
}
fn take_opaque_types_for_query_response(&self) -> Vec<(OpaqueTypeKey<'tcx>, Vec<Ty<'tcx>>)> {
fn take_opaque_types_for_query_response(&self) -> Vec<(OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
self.inner
.borrow_mut()
.opaque_type_storage
.take_opaque_types()
.into_iter()
.map(|(k, v)| (k, v.hidden_types.into_iter().map(|ht| ht.ty).collect()))
.map(|(k, v)| (k, v.hidden_type.ty))
.collect()
}
@ -497,14 +497,11 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
let mut obligations = vec![];
// Carry all newly resolved opaque types to the caller's scope
for (key, tys) in &query_response.value.opaque_types {
for &(key, ty) in &query_response.value.opaque_types {
let substs = substitute_value(self.tcx, &result_subst, key.substs);
let opaque = self.tcx.mk_opaque(key.def_id, substs);
for &ty in tys {
let ty = substitute_value(self.tcx, &result_subst, ty);
obligations
.extend(self.handle_opaque_type(opaque, ty, cause, param_env)?.obligations);
}
let ty = substitute_value(self.tcx, &result_subst, ty);
obligations.extend(self.handle_opaque_type(opaque, ty, cause, param_env)?.obligations);
}
Ok(InferOk { value: result_subst, obligations })

View File

@ -6,7 +6,6 @@ use rustc_data_structures::sync::Lrc;
use rustc_data_structures::vec_map::VecMap;
use rustc_hir as hir;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::fold::BottomUpFolder;
use rustc_middle::ty::subst::{GenericArgKind, Subst};
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitor};
@ -33,61 +32,12 @@ pub struct OpaqueTypeDecl<'tcx> {
/// The hidden types that have been inferred for this opaque type.
/// There can be multiple, but they are all `lub`ed together at the end
/// to obtain the canonical hidden type.
pub hidden_types: Vec<OpaqueHiddenType<'tcx>>,
pub hidden_type: OpaqueHiddenType<'tcx>,
/// The origin of the opaque type.
pub origin: hir::OpaqueTyOrigin,
}
impl<'tcx> OpaqueTypeDecl<'tcx> {
pub fn hidden_type(
&self,
infcx: &InferCtxt<'_, 'tcx>,
cause: &ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> Result<
InferOk<'tcx, OpaqueHiddenType<'tcx>>,
(TypeError<'tcx>, OpaqueHiddenType<'tcx>, OpaqueHiddenType<'tcx>),
> {
let mut value = self.hidden_types[0];
let mut obligations = vec![];
let mut error: Option<(_, _, OpaqueHiddenType<'tcx>)> = None;
for &next in self.hidden_types[1..].iter() {
// FIXME: make use of the spans to get nicer diagnostics!
let res = match infcx.at(cause, param_env).eq(value.ty, next.ty) {
Ok(res) => res,
Err(e) => {
// Try to improve the span. Sometimes we have dummy spans, sometimes we are pointing
// at an if/match instead of at the arm that gave us the type, but later spans point
// to the right thing.
if let Some((_, _, old)) = &mut error {
old.span = old.span.substitute_dummy(next.span);
// Shrink the span if possible
if old.span.contains(next.span) {
old.span = next.span;
}
} else {
let mut next = next;
next.span = next.span.substitute_dummy(cause.span(infcx.tcx));
error = Some((e, value, next));
}
continue;
}
};
obligations.extend(res.obligations);
value.span = value.span.substitute_dummy(next.span);
// Shrink the span if possible
if value.span.contains(next.span) {
value.span = next.span;
}
}
match error {
None => Ok(InferOk { value, obligations }),
Some(e) => Err(e),
}
}
}
#[derive(Copy, Clone, Debug, TypeFoldable)]
pub struct OpaqueHiddenType<'tcx> {
/// The span of this particular definition of the opaque type. So

View File

@ -20,7 +20,7 @@ impl<'tcx> OpaqueTypeStorage<'tcx> {
#[instrument(level = "debug")]
pub(crate) fn remove(&mut self, key: OpaqueTypeKey<'tcx>, idx: Option<OpaqueHiddenType<'tcx>>) {
if let Some(idx) = idx {
self.opaque_types.get_mut(&key).unwrap().hidden_types[0] = idx;
self.opaque_types.get_mut(&key).unwrap().hidden_type = idx;
} else {
match self.opaque_types.remove(&key) {
None => bug!("reverted opaque type inference that was never registered: {:?}", key),
@ -73,17 +73,15 @@ impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> {
&mut self,
key: OpaqueTypeKey<'tcx>,
opaque_type: Ty<'tcx>,
ty: OpaqueHiddenType<'tcx>,
hidden_type: OpaqueHiddenType<'tcx>,
origin: OpaqueTyOrigin,
) -> Option<Ty<'tcx>> {
if let Some(decl) = self.storage.opaque_types.get_mut(&key) {
assert_eq!(decl.hidden_types.len(), 1);
let prev = decl.hidden_types[0];
decl.hidden_types = vec![ty];
let prev = std::mem::replace(&mut decl.hidden_type, hidden_type);
self.undo_log.push(UndoLog::OpaqueTypes(key, Some(prev)));
return Some(prev.ty);
}
let decl = OpaqueTypeDecl { opaque_type, hidden_types: vec![ty], origin };
let decl = OpaqueTypeDecl { opaque_type, hidden_type, origin };
self.storage.opaque_types.insert(key, decl);
self.undo_log.push(UndoLog::OpaqueTypes(key, None));
None

View File

@ -180,7 +180,7 @@ pub struct QueryResponse<'tcx, R> {
pub certainty: Certainty,
/// List of opaque types for which we figured out a hidden type
/// during the evaluation of the query.
pub opaque_types: Vec<(OpaqueTypeKey<'tcx>, Vec<Ty<'tcx>>)>,
pub opaque_types: Vec<(OpaqueTypeKey<'tcx>, Ty<'tcx>)>,
pub value: R,
}

View File

@ -99,8 +99,6 @@ pub use diverges::Diverges;
pub use expectation::Expectation;
pub use fn_ctxt::*;
pub use inherited::{Inherited, InheritedBuilder};
use rustc_infer::traits::ObligationCause;
use traits::ObligationCauseCode::MiscObligation;
use crate::astconv::AstConv;
use crate::check::gather_locals::GatherLocalsVisitor;
@ -474,19 +472,6 @@ fn typeck_with_fallback<'tcx>(
fcx.require_type_is_sized(ty, span, code);
}
let opaque_types = fcx.infcx.inner.borrow_mut().opaque_type_storage.opaque_types();
for (_, decl) in opaque_types {
let cause = ObligationCause::new(body.value.span, id, MiscObligation);
if let Err((err, expected, actual)) =
decl.hidden_type(&fcx.infcx, &cause, fcx.param_env)
{
let cause = ObligationCause::new(actual.span, id, MiscObligation);
fcx.report_mismatched_types(&cause, expected.ty, actual.ty, err)
.span_label(expected.span, "type expected due to this")
.emit();
}
}
fcx.select_all_obligations_or_error();
if fn_sig.is_some() {