Clean up leftovers from eager hidden type merging
This commit is contained in:
parent
38f50d1ecb
commit
edaf9625fb
6 changed files with 34 additions and 109 deletions
|
@ -18,7 +18,9 @@ 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::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
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::tcx::PlaceTy;
|
||||||
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
|
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
|
||||||
use rustc_middle::mir::AssertKind;
|
use rustc_middle::mir::AssertKind;
|
||||||
|
@ -194,31 +196,24 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
||||||
let opaque_type_values = opaque_type_values
|
let opaque_type_values = opaque_type_values
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|(opaque_type_key, decl)| {
|
.filter_map(|(opaque_type_key, decl)| {
|
||||||
let def_id = body.source.def_id().expect_local();
|
cx.fully_perform_op(
|
||||||
let body_id = cx.tcx().hir().local_def_id_to_hir_id(def_id);
|
Locations::All(body.span),
|
||||||
let cause = ObligationCause::misc(body.span, body_id);
|
ConstraintCategory::OpaqueType,
|
||||||
let hidden = cx
|
CustomTypeOp::new(
|
||||||
.fully_perform_op(
|
|infcx| {
|
||||||
Locations::All(body.span),
|
infcx.register_member_constraints(
|
||||||
ConstraintCategory::OpaqueType,
|
param_env,
|
||||||
CustomTypeOp::new(
|
opaque_type_key,
|
||||||
|infcx| {
|
decl.hidden_type.ty,
|
||||||
let res = decl
|
decl.hidden_type.span,
|
||||||
.hidden_type(infcx, &cause, param_env)
|
);
|
||||||
.map_err(|e| e.0)?;
|
Ok(InferOk { value: (), obligations: vec![] })
|
||||||
infcx.register_member_constraints(
|
},
|
||||||
param_env,
|
|| "opaque_type_map".to_string(),
|
||||||
opaque_type_key,
|
),
|
||||||
res.value.ty,
|
)
|
||||||
res.value.span,
|
.unwrap();
|
||||||
);
|
let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type.ty);
|
||||||
Ok(res)
|
|
||||||
},
|
|
||||||
|| "opaque_type_map".to_string(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let mut hidden_type = infcx.resolve_vars_if_possible(hidden.ty);
|
|
||||||
trace!(
|
trace!(
|
||||||
"finalized opaque type {:?} to {:#?}",
|
"finalized opaque type {:?} to {:#?}",
|
||||||
opaque_type_key,
|
opaque_type_key,
|
||||||
|
@ -226,7 +221,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
||||||
);
|
);
|
||||||
if hidden_type.has_infer_types_or_consts() {
|
if hidden_type.has_infer_types_or_consts() {
|
||||||
infcx.tcx.sess.delay_span_bug(
|
infcx.tcx.sess.delay_span_bug(
|
||||||
hidden.span,
|
decl.hidden_type.span,
|
||||||
&format!("could not resolve {:#?}", hidden_type.kind()),
|
&format!("could not resolve {:#?}", hidden_type.kind()),
|
||||||
);
|
);
|
||||||
hidden_type = infcx.tcx.ty_error();
|
hidden_type = infcx.tcx.ty_error();
|
||||||
|
@ -263,7 +258,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
||||||
);
|
);
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some((opaque_type_key, (hidden_type, hidden.span, decl.origin)))
|
Some((opaque_type_key, (hidden_type, decl.hidden_type.span, decl.origin)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
|
@ -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
|
self.inner
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.opaque_type_storage
|
.opaque_type_storage
|
||||||
.take_opaque_types()
|
.take_opaque_types()
|
||||||
.into_iter()
|
.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()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,14 +497,11 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
|
||||||
let mut obligations = vec![];
|
let mut obligations = vec![];
|
||||||
|
|
||||||
// Carry all newly resolved opaque types to the caller's scope
|
// 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 substs = substitute_value(self.tcx, &result_subst, key.substs);
|
||||||
let opaque = self.tcx.mk_opaque(key.def_id, substs);
|
let opaque = self.tcx.mk_opaque(key.def_id, substs);
|
||||||
for &ty in tys {
|
let ty = substitute_value(self.tcx, &result_subst, ty);
|
||||||
let ty = substitute_value(self.tcx, &result_subst, ty);
|
obligations.extend(self.handle_opaque_type(opaque, ty, cause, param_env)?.obligations);
|
||||||
obligations
|
|
||||||
.extend(self.handle_opaque_type(opaque, ty, cause, param_env)?.obligations);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(InferOk { value: result_subst, obligations })
|
Ok(InferOk { value: result_subst, obligations })
|
||||||
|
|
|
@ -6,7 +6,6 @@ use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_data_structures::vec_map::VecMap;
|
use rustc_data_structures::vec_map::VecMap;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_middle::traits::ObligationCause;
|
use rustc_middle::traits::ObligationCause;
|
||||||
use rustc_middle::ty::error::TypeError;
|
|
||||||
use rustc_middle::ty::fold::BottomUpFolder;
|
use rustc_middle::ty::fold::BottomUpFolder;
|
||||||
use rustc_middle::ty::subst::{GenericArgKind, Subst};
|
use rustc_middle::ty::subst::{GenericArgKind, Subst};
|
||||||
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitor};
|
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.
|
/// 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
|
/// 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_types: Vec<OpaqueHiddenType<'tcx>>,
|
pub hidden_type: OpaqueHiddenType<'tcx>,
|
||||||
|
|
||||||
/// The origin of the opaque type.
|
/// The origin of the opaque type.
|
||||||
pub origin: hir::OpaqueTyOrigin,
|
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)]
|
#[derive(Copy, Clone, Debug, TypeFoldable)]
|
||||||
pub struct OpaqueHiddenType<'tcx> {
|
pub struct OpaqueHiddenType<'tcx> {
|
||||||
/// The span of this particular definition of the opaque type. So
|
/// The span of this particular definition of the opaque type. So
|
||||||
|
|
|
@ -20,7 +20,7 @@ impl<'tcx> OpaqueTypeStorage<'tcx> {
|
||||||
#[instrument(level = "debug")]
|
#[instrument(level = "debug")]
|
||||||
pub(crate) fn remove(&mut self, key: OpaqueTypeKey<'tcx>, idx: Option<OpaqueHiddenType<'tcx>>) {
|
pub(crate) fn remove(&mut self, key: OpaqueTypeKey<'tcx>, idx: Option<OpaqueHiddenType<'tcx>>) {
|
||||||
if let Some(idx) = idx {
|
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 {
|
} else {
|
||||||
match self.opaque_types.remove(&key) {
|
match self.opaque_types.remove(&key) {
|
||||||
None => bug!("reverted opaque type inference that was never registered: {:?}", key),
|
None => bug!("reverted opaque type inference that was never registered: {:?}", key),
|
||||||
|
@ -73,17 +73,15 @@ impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
key: OpaqueTypeKey<'tcx>,
|
key: OpaqueTypeKey<'tcx>,
|
||||||
opaque_type: Ty<'tcx>,
|
opaque_type: Ty<'tcx>,
|
||||||
ty: OpaqueHiddenType<'tcx>,
|
hidden_type: OpaqueHiddenType<'tcx>,
|
||||||
origin: OpaqueTyOrigin,
|
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) {
|
||||||
assert_eq!(decl.hidden_types.len(), 1);
|
let prev = std::mem::replace(&mut decl.hidden_type, hidden_type);
|
||||||
let prev = decl.hidden_types[0];
|
|
||||||
decl.hidden_types = vec![ty];
|
|
||||||
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 { opaque_type, hidden_types: vec![ty], origin };
|
let decl = OpaqueTypeDecl { opaque_type, hidden_type, origin };
|
||||||
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
|
||||||
|
|
|
@ -180,7 +180,7 @@ pub struct QueryResponse<'tcx, R> {
|
||||||
pub certainty: Certainty,
|
pub certainty: Certainty,
|
||||||
/// List of opaque types for which we figured out a hidden type
|
/// List of opaque types for which we figured out a hidden type
|
||||||
/// during the evaluation of the query.
|
/// 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,
|
pub value: R,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,8 +99,6 @@ pub use diverges::Diverges;
|
||||||
pub use expectation::Expectation;
|
pub use expectation::Expectation;
|
||||||
pub use fn_ctxt::*;
|
pub use fn_ctxt::*;
|
||||||
pub use inherited::{Inherited, InheritedBuilder};
|
pub use inherited::{Inherited, InheritedBuilder};
|
||||||
use rustc_infer::traits::ObligationCause;
|
|
||||||
use traits::ObligationCauseCode::MiscObligation;
|
|
||||||
|
|
||||||
use crate::astconv::AstConv;
|
use crate::astconv::AstConv;
|
||||||
use crate::check::gather_locals::GatherLocalsVisitor;
|
use crate::check::gather_locals::GatherLocalsVisitor;
|
||||||
|
@ -474,19 +472,6 @@ fn typeck_with_fallback<'tcx>(
|
||||||
fcx.require_type_is_sized(ty, span, code);
|
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();
|
fcx.select_all_obligations_or_error();
|
||||||
|
|
||||||
if fn_sig.is_some() {
|
if fn_sig.is_some() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue