liveness::generate(&mut cx, body, elements, flow_inits, move_data, location_table);
translate_outlives_facts(&mut cx);
- let mut opaque_type_values = cx.opaque_type_values;
-
- for (_, revealed_ty) in &mut opaque_type_values {
- *revealed_ty = infcx.resolve_vars_if_possible(*revealed_ty);
- if revealed_ty.has_infer_types_or_consts() {
- infcx.tcx.sess.delay_span_bug(
- body.span,
- &format!("could not resolve {:#?}", revealed_ty.kind()),
- );
- *revealed_ty = infcx.tcx.ty_error();
- }
- }
+ let opaque_type_values = mem::take(&mut infcx.inner.borrow_mut().opaque_types);
- opaque_type_values.retain(|(opaque_type_key, resolved_ty)| {
- let concrete_is_opaque = if let ty::Opaque(def_id, _) = resolved_ty.kind() {
- *def_id == opaque_type_key.def_id
- } else {
- false
- };
-
- if concrete_is_opaque {
- // We're using an opaque `impl Trait` type without
- // 'revealing' it. For example, code like this:
- //
- // type Foo = impl Debug;
- // fn foo1() -> Foo { ... }
- // fn foo2() -> Foo { foo1() }
- //
- // In `foo2`, we're not revealing the type of `Foo` - we're
- // just treating it as the opaque type.
- //
- // When this occurs, we do *not* want to try to equate
- // the concrete type with the underlying defining type
- // of the opaque type - this will always fail, since
- // the defining type of an opaque type is always
- // some other type (e.g. not itself)
- // Essentially, none of the normal obligations apply here -
- // we're just passing around some unknown opaque type,
- // without actually looking at the underlying type it
- // gets 'revealed' into
- debug!(
- "eq_opaque_type_and_type: non-defining use of {:?}",
- opaque_type_key.def_id,
- );
- }
- !concrete_is_opaque
- });
opaque_type_values
+ .into_iter()
+ .filter_map(|(opaque_type_key, decl)| {
+ let mut revealed_ty = infcx.resolve_vars_if_possible(decl.concrete_ty);
+ if revealed_ty.has_infer_types_or_consts() {
+ infcx.tcx.sess.delay_span_bug(
+ body.span,
+ &format!("could not resolve {:#?}", revealed_ty.kind()),
+ );
+ revealed_ty = infcx.tcx.ty_error();
+ }
+ let concrete_is_opaque = if let ty::Opaque(def_id, _) = revealed_ty.kind() {
+ *def_id == opaque_type_key.def_id
+ } else {
+ false
+ };
+
+ if concrete_is_opaque {
+ // We're using an opaque `impl Trait` type without
+ // 'revealing' it. For example, code like this:
+ //
+ // type Foo = impl Debug;
+ // fn foo1() -> Foo { ... }
+ // fn foo2() -> Foo { foo1() }
+ //
+ // In `foo2`, we're not revealing the type of `Foo` - we're
+ // just treating it as the opaque type.
+ //
+ // When this occurs, we do *not* want to try to equate
+ // the concrete type with the underlying defining type
+ // of the opaque type - this will always fail, since
+ // the defining type of an opaque type is always
+ // some other type (e.g. not itself)
+ // Essentially, none of the normal obligations apply here -
+ // we're just passing around some unknown opaque type,
+ // without actually looking at the underlying type it
+ // gets 'revealed' into
+ debug!(
+ "eq_opaque_type_and_type: non-defining use of {:?}",
+ opaque_type_key.def_id,
+ );
+ None
+ } else {
+ Some((opaque_type_key, revealed_ty))
+ }
+ })
+ .collect()
},
);
reported_errors: FxHashSet<(Ty<'tcx>, Span)>,
borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
universal_region_relations: &'a UniversalRegionRelations<'tcx>,
- opaque_type_values: VecMap<OpaqueTypeKey<'tcx>, Ty<'tcx>>,
}
struct BorrowCheckContext<'a, 'tcx> {
borrowck_context,
reported_errors: Default::default(),
universal_region_relations,
- opaque_type_values: VecMap::default(),
};
checker.check_user_type_annotations();
checker
let body = self.body;
let mir_def_id = body.source.def_id().expect_local();
- let mut opaque_type_values = VecMap::new();
-
debug!("eq_opaque_type_and_type: mir_def_id={:?}", mir_def_id);
- let opaque_type_map = self.fully_perform_op(
+ self.fully_perform_op(
locations,
category,
CustomTypeOp::new(
// to `Box<?T>`, returning an `opaque_type_map` mapping `{Foo<T> -> ?T}`.
// (Note that the key of the map is both the def-id of `Foo` along with
// any generic parameters.)
- let (output_ty, opaque_type_map) =
- obligations.add(infcx.instantiate_opaque_types(
- mir_def_id,
- dummy_body_id,
- param_env,
- anon_ty,
- locations.span(body),
- ));
+ let output_ty = obligations.add(infcx.instantiate_opaque_types(
+ mir_def_id,
+ dummy_body_id,
+ param_env,
+ anon_ty,
+ locations.span(body),
+ ));
debug!(
"eq_opaque_type_and_type: \
instantiated output_ty={:?} \
- opaque_type_map={:#?} \
revealed_ty={:?}",
- output_ty, opaque_type_map, revealed_ty
+ output_ty, revealed_ty
);
// Make sure that the inferred types are well-formed. I'm
.eq(output_ty, revealed_ty)?,
);
- for &(opaque_type_key, opaque_decl) in &opaque_type_map {
- opaque_type_values.insert(opaque_type_key, opaque_decl.concrete_ty);
- }
-
debug!("eq_opaque_type_and_type: equated");
- Ok(InferOk { value: opaque_type_map, obligations: obligations.into_vec() })
+ Ok(InferOk { value: (), obligations: obligations.into_vec() })
},
|| "input_output".to_string(),
),
)?;
- self.opaque_type_values.extend(opaque_type_values);
-
let universal_region_relations = self.universal_region_relations;
// Finally, if we instantiated the anon types successfully, we
// have to solve any bounds (e.g., `-> impl Iterator` needs to
// prove that `T: Iterator` where `T` is the type we
// instantiated it with).
+ let opaque_type_map = self.infcx.inner.borrow().opaque_types.clone();
for (opaque_type_key, opaque_decl) in opaque_type_map {
self.fully_perform_op(
locations,
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_infer::infer::error_reporting::unexpected_hidden_region_diagnostic;
use rustc_infer::infer::free_regions::FreeRegionRelations;
-use rustc_infer::infer::opaque_types::{OpaqueTypeDecl, OpaqueTypeMap};
+use rustc_infer::infer::opaque_types::OpaqueTypeDecl;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{self, InferCtxt, InferOk};
use rustc_middle::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor};
param_env: ty::ParamEnv<'tcx>,
value: T,
value_span: Span,
- ) -> InferOk<'tcx, (T, OpaqueTypeMap<'tcx>)>;
+ ) -> InferOk<'tcx, T>;
fn constrain_opaque_types<FRR: FreeRegionRelations<'tcx>>(&self, free_region_relations: &FRR);
param_env: ty::ParamEnv<'tcx>,
value: T,
value_span: Span,
- ) -> InferOk<'tcx, (T, OpaqueTypeMap<'tcx>)> {
+ ) -> InferOk<'tcx, T> {
debug!(
"instantiate_opaque_types(value={:?}, parent_def_id={:?}, body_id={:?}, \
param_env={:?}, value_span={:?})",
body_id,
param_env,
value_span,
- opaque_types: Default::default(),
obligations: vec![],
};
let value = instantiator.instantiate_opaque_types_in_map(value);
- InferOk { value: (value, instantiator.opaque_types), obligations: instantiator.obligations }
+ InferOk { value, obligations: instantiator.obligations }
}
/// Given the map `opaque_types` containing the opaque
body_id: hir::HirId,
param_env: ty::ParamEnv<'tcx>,
value_span: Span,
- opaque_types: OpaqueTypeMap<'tcx>,
obligations: Vec<PredicateObligation<'tcx>>,
}
// Use the same type variable if the exact same opaque type appears more
// than once in the return type (e.g., if it's passed to a type alias).
- if let Some(opaque_defn) = self.opaque_types.get(&opaque_type_key) {
+ if let Some(opaque_defn) = infcx.inner.borrow().opaque_types.get(&opaque_type_key) {
debug!("instantiate_opaque_types: returning concrete ty {:?}", opaque_defn.concrete_ty);
return opaque_defn.concrete_ty;
}
// Foo, impl Bar)`.
let definition_span = self.value_span;
- self.opaque_types.insert(
- OpaqueTypeKey { def_id, substs },
- OpaqueTypeDecl { opaque_type: ty, definition_span, concrete_ty: ty_var, origin },
- );
+ {
+ let mut infcx = self.infcx.inner.borrow_mut();
+ infcx.opaque_types.insert(
+ OpaqueTypeKey { def_id, substs },
+ OpaqueTypeDecl { opaque_type: ty, definition_span, concrete_ty: ty_var, origin },
+ );
+ infcx.opaque_types_vars.insert(ty_var, ty);
+ }
+
debug!("instantiate_opaque_types: ty_var={:?}", ty_var);
self.compute_opaque_type_obligations(opaque_type_key, span);