mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-02 10:04:23 +00:00
Clean up leftovers from eager hidden type merging
This commit is contained in:
parent
38f50d1ecb
commit
edaf9625fb
@ -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();
|
||||
|
@ -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 })
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user