Skip to content

Commit b2c1919

Browse files
committed
Store the DefId of the currently typechecked item in InferCtxt
This allows opaque type inference to check for defining uses without having to pass down that def id via function arguments to every method that could possibly cause an opaque type to be compared with a concrete type
1 parent 20371b9 commit b2c1919

File tree

7 files changed

+34
-32
lines changed

7 files changed

+34
-32
lines changed

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub(crate) use self::undo_log::{InferCtxtUndoLogs, Snapshot, UndoLog};
99

1010
use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine};
1111

12+
use hir::def_id::CRATE_DEF_ID;
1213
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1314
use rustc_data_structures::sync::Lrc;
1415
use rustc_data_structures::undo_log::Rollback;
@@ -292,6 +293,10 @@ impl<'tcx> InferCtxtInner<'tcx> {
292293
pub struct InferCtxt<'a, 'tcx> {
293294
pub tcx: TyCtxt<'tcx>,
294295

296+
/// The `DefId` of the item in whose context we are performing inference or typeck.
297+
/// It is used to check whether an opaque type use is a defining use.
298+
pub defining_use_anchor: LocalDefId,
299+
295300
/// During type-checking/inference of a body, `in_progress_typeck_results`
296301
/// contains a reference to the typeck results being built up, which are
297302
/// used for reading closure kinds/signatures as they are inferred,
@@ -550,6 +555,7 @@ impl<'tcx> fmt::Display for FixupError<'tcx> {
550555
pub struct InferCtxtBuilder<'tcx> {
551556
tcx: TyCtxt<'tcx>,
552557
fresh_typeck_results: Option<RefCell<ty::TypeckResults<'tcx>>>,
558+
defining_use_anchor: LocalDefId,
553559
}
554560

555561
pub trait TyCtxtInferExt<'tcx> {
@@ -558,15 +564,27 @@ pub trait TyCtxtInferExt<'tcx> {
558564

559565
impl TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
560566
fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
561-
InferCtxtBuilder { tcx: self, fresh_typeck_results: None }
567+
InferCtxtBuilder {
568+
tcx: self,
569+
defining_use_anchor: CRATE_DEF_ID,
570+
fresh_typeck_results: None,
571+
}
562572
}
563573
}
564574

565575
impl<'tcx> InferCtxtBuilder<'tcx> {
566576
/// Used only by `rustc_typeck` during body type-checking/inference,
567577
/// will initialize `in_progress_typeck_results` with fresh `TypeckResults`.
578+
/// Will also change the scope for opaque type defining use checks to the given owner.
568579
pub fn with_fresh_in_progress_typeck_results(mut self, table_owner: LocalDefId) -> Self {
569580
self.fresh_typeck_results = Some(RefCell::new(ty::TypeckResults::new(table_owner)));
581+
self.with_opaque_type_inference(table_owner)
582+
}
583+
584+
/// Whenever the `InferCtxt` should be able to handle defining uses of opaque types,
585+
/// you need to call this function. Otherwise the opaque type will be treated opaquely.
586+
pub fn with_opaque_type_inference(mut self, defining_use_anchor: LocalDefId) -> Self {
587+
self.defining_use_anchor = defining_use_anchor;
570588
self
571589
}
572590

@@ -594,10 +612,11 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
594612
}
595613

596614
pub fn enter<R>(&mut self, f: impl for<'a> FnOnce(InferCtxt<'a, 'tcx>) -> R) -> R {
597-
let InferCtxtBuilder { tcx, ref fresh_typeck_results } = *self;
615+
let InferCtxtBuilder { tcx, defining_use_anchor, ref fresh_typeck_results } = *self;
598616
let in_progress_typeck_results = fresh_typeck_results.as_ref();
599617
f(InferCtxt {
600618
tcx,
619+
defining_use_anchor,
601620
in_progress_typeck_results,
602621
inner: RefCell::new(InferCtxtInner::new()),
603622
lexical_region_resolutions: RefCell::new(None),

compiler/rustc_mir/src/borrow_check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ fn mir_borrowck<'tcx>(
105105
let (input_body, promoted) = tcx.mir_promoted(def);
106106
debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id()));
107107

108-
let opt_closure_req = tcx.infer_ctxt().enter(|infcx| {
108+
let opt_closure_req = tcx.infer_ctxt().with_opaque_type_inference(def.did).enter(|infcx| {
109109
let input_body: &Body<'_> = &input_body.borrow();
110110
let promoted: &IndexVec<_, _> = &promoted.borrow();
111111
do_mir_borrowck(&infcx, input_body, promoted)

compiler/rustc_mir/src/borrow_check/type_check/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1305,7 +1305,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
13051305
// (Note that the key of the map is both the def-id of `Foo` along with
13061306
// any generic parameters.)
13071307
let output_ty = obligations.add(infcx.instantiate_opaque_types(
1308-
mir_def_id,
13091308
dummy_body_id,
13101309
param_env,
13111310
anon_ty,

compiler/rustc_trait_selection/src/opaque_types.rs

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ pub enum GenerateMemberConstraints {
3232
pub trait InferCtxtExt<'tcx> {
3333
fn instantiate_opaque_types<T: TypeFoldable<'tcx>>(
3434
&self,
35-
parent_def_id: LocalDefId,
3635
body_id: hir::HirId,
3736
param_env: ty::ParamEnv<'tcx>,
3837
value: T,
@@ -94,25 +93,18 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
9493
/// - `value_span` -- the span where the value came from, used in error reporting
9594
fn instantiate_opaque_types<T: TypeFoldable<'tcx>>(
9695
&self,
97-
parent_def_id: LocalDefId,
9896
body_id: hir::HirId,
9997
param_env: ty::ParamEnv<'tcx>,
10098
value: T,
10199
value_span: Span,
102100
) -> InferOk<'tcx, T> {
103101
debug!(
104-
"instantiate_opaque_types(value={:?}, parent_def_id={:?}, body_id={:?}, \
102+
"instantiate_opaque_types(value={:?}, body_id={:?}, \
105103
param_env={:?}, value_span={:?})",
106-
value, parent_def_id, body_id, param_env, value_span,
104+
value, body_id, param_env, value_span,
107105
);
108-
let mut instantiator = Instantiator {
109-
infcx: self,
110-
parent_def_id,
111-
body_id,
112-
param_env,
113-
value_span,
114-
obligations: vec![],
115-
};
106+
let mut instantiator =
107+
Instantiator { infcx: self, body_id, param_env, value_span, obligations: vec![] };
116108
let value = instantiator.instantiate_opaque_types_in_map(value);
117109
InferOk { value, obligations: instantiator.obligations }
118110
}
@@ -857,7 +849,6 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
857849

858850
struct Instantiator<'a, 'tcx> {
859851
infcx: &'a InferCtxt<'a, 'tcx>,
860-
parent_def_id: LocalDefId,
861852
body_id: hir::HirId,
862853
param_env: ty::ParamEnv<'tcx>,
863854
value_span: Span,
@@ -910,7 +901,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
910901
// ```
911902
if let Some(def_id) = def_id.as_local() {
912903
let opaque_hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
913-
let parent_def_id = self.parent_def_id;
904+
let parent_def_id = self.infcx.defining_use_anchor;
914905
let def_scope_default = || {
915906
let opaque_parent_hir_id = tcx.hir().get_parent_item(opaque_hir_id);
916907
parent_def_id == tcx.hir().local_def_id(opaque_parent_hir_id)
@@ -922,14 +913,14 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
922913
impl_trait_fn: Some(parent),
923914
origin,
924915
..
925-
}) => (parent == self.parent_def_id.to_def_id(), origin),
916+
}) => (parent == parent_def_id.to_def_id(), origin),
926917
// Named `type Foo = impl Bar;`
927918
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
928919
impl_trait_fn: None,
929920
origin,
930921
..
931922
}) => (
932-
may_define_opaque_type(tcx, self.parent_def_id, opaque_hir_id),
923+
may_define_opaque_type(tcx, parent_def_id, opaque_hir_id),
933924
origin,
934925
),
935926
_ => (def_scope_default(), hir::OpaqueTyOrigin::TyAlias),

compiler/rustc_typeck/src/check/_match.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -593,11 +593,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
593593
orig_expected: Expectation<'tcx>,
594594
) -> Option<Span> {
595595
match (orig_expected, self.ret_coercion_impl_trait.map(|ty| (self.body_id.owner, ty))) {
596-
(Expectation::ExpectHasType(expected), Some((id, ty)))
596+
(Expectation::ExpectHasType(expected), Some((_id, ty)))
597597
if self.in_tail_expr && self.can_coerce(outer_ty, expected) =>
598598
{
599599
let impl_trait_ret_ty =
600-
self.infcx.instantiate_opaque_types(id, self.body_id, self.param_env, ty, span);
600+
self.infcx.instantiate_opaque_types(self.body_id, self.param_env, ty, span);
601601
assert!(
602602
impl_trait_ret_ty.obligations.is_empty(),
603603
"we should never get new obligations here"

compiler/rustc_typeck/src/check/check.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ pub(super) fn check_fn<'a, 'tcx>(
9595
let declared_ret_ty = fn_sig.output();
9696

9797
let revealed_ret_ty =
98-
fcx.instantiate_opaque_types_from_value(fn_id, declared_ret_ty, decl.output.span());
98+
fcx.instantiate_opaque_types_from_value(declared_ret_ty, decl.output.span());
9999
debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
100100
fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
101101
fcx.ret_type_span = Some(decl.output.span());
@@ -651,7 +651,7 @@ fn check_opaque_meets_bounds<'tcx>(
651651
let misc_cause = traits::ObligationCause::misc(span, hir_id);
652652

653653
let _ = inh.register_infer_ok_obligations(
654-
infcx.instantiate_opaque_types(def_id, hir_id, param_env, opaque_ty, span),
654+
infcx.instantiate_opaque_types(hir_id, param_env, opaque_ty, span),
655655
);
656656

657657
let opaque_type_map = infcx.inner.borrow().opaque_types.clone();

compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -362,20 +362,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
362362
/// Replaces the opaque types from the given value with type variables,
363363
/// and records the `OpaqueTypeMap` for later use during writeback. See
364364
/// `InferCtxt::instantiate_opaque_types` for more details.
365+
#[instrument(skip(self, value_span), level = "debug")]
365366
pub(in super::super) fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
366367
&self,
367-
parent_id: hir::HirId,
368368
value: T,
369369
value_span: Span,
370370
) -> T {
371-
let parent_def_id = self.tcx.hir().local_def_id(parent_id);
372-
debug!(
373-
"instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
374-
parent_def_id, value
375-
);
376-
377371
self.register_infer_ok_obligations(self.instantiate_opaque_types(
378-
parent_def_id,
379372
self.body_id,
380373
self.param_env,
381374
value,

0 commit comments

Comments
 (0)