Skip to content

Commit 8d5de0b

Browse files
author
Alexander Regueiro
committed
Handle locals in closures properly.
1 parent 2181895 commit 8d5de0b

File tree

5 files changed

+83
-123
lines changed

5 files changed

+83
-123
lines changed

src/librustc/hir/def_id.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ impl DefIndexAddressSpace {
215215
}
216216
}
217217

218-
/// A DefId identifies a particular *definition*, by combining a crate
218+
/// A `DefId` identifies a particular *definition*, by combining a crate
219219
/// index and a def index.
220220
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
221221
pub struct DefId {

src/librustc/hir/lowering.rs

+59-97
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ pub struct LoweringContext<'a> {
139139
type_def_lifetime_params: DefIdMap<usize>,
140140

141141
current_hir_id_owner: Vec<(DefIndex, u32)>,
142-
current_impl_trait_owner: Vec<DefId>,
143142
item_local_id_counters: NodeMap<u32>,
144143
node_id_to_hir_id: IndexVec<NodeId, hir::HirId>,
145144
}
@@ -233,7 +232,6 @@ pub fn lower_crate(
233232
anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
234233
type_def_lifetime_params: DefIdMap(),
235234
current_hir_id_owner: vec![(CRATE_DEF_INDEX, 0)],
236-
current_impl_trait_owner: vec![],
237235
item_local_id_counters: NodeMap(),
238236
node_id_to_hir_id: IndexVec::new(),
239237
is_generator: false,
@@ -392,17 +390,6 @@ impl<'a> LoweringContext<'a> {
392390
}
393391

394392
impl<'lcx, 'interner> ItemLowerer<'lcx, 'interner> {
395-
fn with_impl_trait_owner<F, T>(&mut self, def_id: DefId, f: F) -> T
396-
where
397-
F: FnOnce(&mut Self) -> T,
398-
{
399-
self.lctx.current_impl_trait_owner.push(def_id);
400-
let ret = f(self);
401-
self.lctx.current_impl_trait_owner.pop();
402-
403-
ret
404-
}
405-
406393
fn with_trait_impl_ref<F>(&mut self, trait_impl_ref: &Option<TraitRef>, f: F)
407394
where
408395
F: FnOnce(&mut Self),
@@ -440,12 +427,7 @@ impl<'a> LoweringContext<'a> {
440427

441428
self.lctx.with_parent_impl_lifetime_defs(&item_generics, |this| {
442429
let this = &mut ItemLowerer { lctx: this };
443-
if let ItemKind::Fn(..) = item.node {
444-
let fn_def_id = this.lctx.resolver.definitions().local_def_id(item.id);
445-
this.with_impl_trait_owner(fn_def_id, |this| {
446-
visit::walk_item(this, item)
447-
});
448-
} else if let ItemKind::Impl(.., ref opt_trait_ref, _, _) = item.node {
430+
if let ItemKind::Impl(.., ref opt_trait_ref, _, _) = item.node {
449431
this.with_trait_impl_ref(opt_trait_ref, |this| {
450432
visit::walk_item(this, item)
451433
});
@@ -573,17 +555,6 @@ impl<'a> LoweringContext<'a> {
573555
ret
574556
}
575557

576-
fn with_impl_trait_owner<F, T>(&mut self, def_id: DefId, f: F) -> T
577-
where
578-
F: FnOnce(&mut LoweringContext) -> T,
579-
{
580-
self.current_impl_trait_owner.push(def_id);
581-
let ret = f(self);
582-
self.current_impl_trait_owner.pop();
583-
584-
ret
585-
}
586-
587558
/// This method allocates a new HirId for the given NodeId and stores it in
588559
/// the LoweringContext's NodeId => HirId map.
589560
/// Take care not to call this method if the resulting HirId is then not
@@ -1939,15 +1910,15 @@ impl<'a> LoweringContext<'a> {
19391910
visitor.visit_ty(ty);
19401911
}
19411912
}
1942-
let impl_trait_owner_id = self.current_impl_trait_owner.last().map(|id| *id);
1913+
let parent_def_id = DefId::local(self.current_hir_id_owner.last().unwrap().0);
19431914
(P(hir::Local {
19441915
id: node_id,
19451916
hir_id,
19461917
ty: l.ty
19471918
.as_ref()
19481919
.map(|t| self.lower_ty(t,
19491920
if self.sess.features_untracked().impl_trait_in_bindings {
1950-
ImplTraitContext::Existential(impl_trait_owner_id)
1921+
ImplTraitContext::Existential(Some(parent_def_id))
19511922
} else {
19521923
ImplTraitContext::Disallowed
19531924
}
@@ -2213,8 +2184,7 @@ impl<'a> LoweringContext<'a> {
22132184
span, Some(fn_def_id), return_impl_trait_id, |this| {
22142185
let output_ty = match output {
22152186
FunctionRetTy::Ty(ty) => {
2216-
let impl_trait_owner_id = *this.current_impl_trait_owner.last().unwrap();
2217-
this.lower_ty(ty, ImplTraitContext::Existential(Some(impl_trait_owner_id)))
2187+
this.lower_ty(ty, ImplTraitContext::Existential(Some(fn_def_id)))
22182188
}
22192189
FunctionRetTy::Default(span) => {
22202190
let LoweredNodeId { node_id, hir_id } = this.next_id();
@@ -2738,33 +2708,31 @@ impl<'a> LoweringContext<'a> {
27382708
}
27392709
ItemKind::Fn(ref decl, header, ref generics, ref body) => {
27402710
let fn_def_id = self.resolver.definitions().local_def_id(id);
2741-
self.with_impl_trait_owner(fn_def_id, |this| {
2742-
this.with_new_scopes(|this| {
2743-
// Note: we don't need to change the return type from `T` to
2744-
// `impl Future<Output = T>` here because lower_body
2745-
// only cares about the input argument patterns in the function
2746-
// declaration (decl), not the return types.
2747-
let body_id = this.lower_async_body(decl, header.asyncness, body);
2748-
2749-
let (generics, fn_decl) = this.add_in_band_defs(
2750-
generics,
2751-
fn_def_id,
2752-
AnonymousLifetimeMode::PassThrough,
2753-
|this, idty| this.lower_fn_decl(
2754-
decl,
2755-
Some((fn_def_id, idty)),
2756-
true,
2757-
header.asyncness.opt_return_id()
2758-
),
2759-
);
2711+
self.with_new_scopes(|this| {
2712+
// Note: we don't need to change the return type from `T` to
2713+
// `impl Future<Output = T>` here because lower_body
2714+
// only cares about the input argument patterns in the function
2715+
// declaration (decl), not the return types.
2716+
let body_id = this.lower_async_body(decl, header.asyncness, body);
2717+
2718+
let (generics, fn_decl) = this.add_in_band_defs(
2719+
generics,
2720+
fn_def_id,
2721+
AnonymousLifetimeMode::PassThrough,
2722+
|this, idty| this.lower_fn_decl(
2723+
decl,
2724+
Some((fn_def_id, idty)),
2725+
true,
2726+
header.asyncness.opt_return_id()
2727+
),
2728+
);
27602729

2761-
hir::ItemKind::Fn(
2762-
fn_decl,
2763-
this.lower_fn_header(header),
2764-
generics,
2765-
body_id,
2766-
)
2767-
})
2730+
hir::ItemKind::Fn(
2731+
fn_decl,
2732+
this.lower_fn_header(header),
2733+
generics,
2734+
body_id,
2735+
)
27682736
})
27692737
}
27702738
ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)),
@@ -3083,33 +3051,29 @@ impl<'a> LoweringContext<'a> {
30833051
),
30843052
),
30853053
TraitItemKind::Method(ref sig, None) => {
3086-
self.with_impl_trait_owner(trait_item_def_id, |this| {
3087-
let names = this.lower_fn_args_to_names(&sig.decl);
3088-
let (generics, sig) = this.lower_method_sig(
3089-
&i.generics,
3090-
sig,
3091-
trait_item_def_id,
3092-
false,
3093-
None,
3094-
);
3095-
(generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Required(names)))
3096-
})
3054+
let names = self.lower_fn_args_to_names(&sig.decl);
3055+
let (generics, sig) = self.lower_method_sig(
3056+
&i.generics,
3057+
sig,
3058+
trait_item_def_id,
3059+
false,
3060+
None,
3061+
);
3062+
(generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Required(names)))
30973063
}
30983064
TraitItemKind::Method(ref sig, Some(ref body)) => {
3099-
self.with_impl_trait_owner(trait_item_def_id, |this| {
3100-
let body_id = this.lower_body(Some(&sig.decl), |this| {
3101-
let body = this.lower_block(body, false);
3102-
this.expr_block(body, ThinVec::new())
3103-
});
3104-
let (generics, sig) = this.lower_method_sig(
3105-
&i.generics,
3106-
sig,
3107-
trait_item_def_id,
3108-
false,
3109-
None,
3110-
);
3111-
(generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Provided(body_id)))
3112-
})
3065+
let body_id = self.lower_body(Some(&sig.decl), |this| {
3066+
let body = this.lower_block(body, false);
3067+
this.expr_block(body, ThinVec::new())
3068+
});
3069+
let (generics, sig) = self.lower_method_sig(
3070+
&i.generics,
3071+
sig,
3072+
trait_item_def_id,
3073+
false,
3074+
None,
3075+
);
3076+
(generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Provided(body_id)))
31133077
}
31143078
TraitItemKind::Type(ref bounds, ref default) => (
31153079
self.lower_generics(&i.generics, ImplTraitContext::Disallowed),
@@ -3175,18 +3139,16 @@ impl<'a> LoweringContext<'a> {
31753139
)
31763140
}
31773141
ImplItemKind::Method(ref sig, ref body) => {
3178-
self.with_impl_trait_owner(impl_item_def_id, |this| {
3179-
let body_id = this.lower_async_body(&sig.decl, sig.header.asyncness, body);
3180-
let impl_trait_return_allow = !this.is_in_trait_impl;
3181-
let (generics, sig) = this.lower_method_sig(
3182-
&i.generics,
3183-
sig,
3184-
impl_item_def_id,
3185-
impl_trait_return_allow,
3186-
sig.header.asyncness.opt_return_id(),
3187-
);
3188-
(generics, hir::ImplItemKind::Method(sig, body_id))
3189-
})
3142+
let body_id = self.lower_async_body(&sig.decl, sig.header.asyncness, body);
3143+
let impl_trait_return_allow = !self.is_in_trait_impl;
3144+
let (generics, sig) = self.lower_method_sig(
3145+
&i.generics,
3146+
sig,
3147+
impl_item_def_id,
3148+
impl_trait_return_allow,
3149+
sig.header.asyncness.opt_return_id(),
3150+
);
3151+
(generics, hir::ImplItemKind::Method(sig, body_id))
31903152
}
31913153
ImplItemKind::Type(ref ty) => (
31923154
self.lower_generics(&i.generics, ImplTraitContext::Disallowed),

src/librustc/infer/opaque_types/mod.rs

+5-8
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
9898
///
9999
/// # Parameters
100100
///
101-
/// - `parent_def_id` -- we will only instantiate opaque types
102-
/// with this parent. This is typically the def-id of the function
103-
/// in whose return type opaque types are being instantiated.
101+
/// - `parent_def_id` -- the def-id of the function in which the opaque type
102+
/// is defined
104103
/// - `body_id` -- the body-id with which the resulting obligations should
105104
/// be associated
106105
/// - `param_env` -- the in-scope parameter environment to be used for
@@ -113,11 +112,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
113112
param_env: ty::ParamEnv<'tcx>,
114113
value: &T,
115114
) -> InferOk<'tcx, (T, OpaqueTypeMap<'tcx>)> {
116-
debug!(
117-
"instantiate_opaque_types(value={:?},
118-
parent_def_id={:?}, body_id={:?},
119-
param_env={:?})",
120-
value, parent_def_id, body_id, param_env,
115+
debug!("instantiate_opaque_types(value={:?}, parent_def_id={:?}, body_id={:?}, \
116+
param_env={:?})",
117+
value, parent_def_id, body_id, param_env,
121118
);
122119
let mut instantiator = Instantiator {
123120
infcx: self,

src/librustc_mir/borrow_check/nll/type_check/mod.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -898,7 +898,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
898898
locations: Locations,
899899
category: ConstraintCategory,
900900
) -> Fallible<()> {
901-
if let Err(terr) = self.sub_types(sub, sup, locations) {
901+
if let Err(terr) = self.sub_types(sub, sup, locations, category) {
902902
if let TyKind::Opaque(..) = sup.sty {
903903
return self.eq_opaque_type_and_type(sub, sup, locations, category);
904904
} else {
@@ -954,18 +954,19 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
954954
let infcx = self.infcx;
955955
let tcx = infcx.tcx;
956956
let param_env = self.param_env;
957-
let mir_def_id = self.mir_def_id;
957+
let parent_def_id = infcx.tcx.closure_base_def_id(self.mir_def_id);
958958
let opaque_type_map =
959959
self.fully_perform_op(
960960
locations,
961+
category,
961962
CustomTypeOp::new(
962963
|infcx| {
963964
let mut obligations = ObligationAccumulator::default();
964965

965966
let dummy_body_id = ObligationCause::dummy().body_id;
966967
let (output_ty, opaque_type_map) =
967968
obligations.add(infcx.instantiate_opaque_types(
968-
mir_def_id,
969+
parent_def_id,
969970
dummy_body_id,
970971
param_env,
971972
&anon_ty,
@@ -1028,7 +1029,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
10281029
for (opaque_def_id, opaque_decl) in opaque_type_map {
10291030
self.fully_perform_op(
10301031
locations,
1031-
category,
1032+
ConstraintCategory::OpaqueType,
10321033
CustomTypeOp::new(
10331034
|_cx| {
10341035
infcx.constrain_opaque_type(

src/librustc_typeck/check/mod.rs

+13-13
Original file line numberDiff line numberDiff line change
@@ -821,8 +821,8 @@ fn has_typeck_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
821821
}
822822

823823
fn used_trait_imports<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
824-
def_id: DefId)
825-
-> Lrc<DefIdSet> {
824+
def_id: DefId)
825+
-> Lrc<DefIdSet> {
826826
tcx.typeck_tables_of(def_id).used_trait_imports.clone()
827827
}
828828

@@ -870,7 +870,6 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
870870
fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
871871

872872
let revealed_ty = if tcx.features().impl_trait_in_bindings {
873-
fcx.require_type_is_sized(expected_type, body.value.span, traits::SizedReturnType);
874873
fcx.instantiate_opaque_types_from_value(
875874
id,
876875
&expected_type
@@ -965,7 +964,6 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
965964
let local_ty = match local.ty {
966965
Some(ref ty) => {
967966
let o_ty = self.fcx.to_ty(&ty);
968-
debug!("visit_local: ty.hir_id={:?} o_ty={:?} c_ty={:?}", ty.hir_id, o_ty, 1);
969967

970968
let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
971969
self.fcx.instantiate_opaque_types_from_value(
@@ -977,6 +975,8 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
977975
};
978976

979977
let c_ty = self.fcx.inh.infcx.canonicalize_response(&revealed_ty);
978+
debug!("visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
979+
ty.hir_id, o_ty, revealed_ty, c_ty);
980980
self.fcx.tables.borrow_mut().user_provided_tys_mut().insert(ty.hir_id, c_ty);
981981

982982
Some(LocalTy { decl_ty: o_ty, revealed_ty })
@@ -1074,7 +1074,9 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
10741074
fcx.yield_ty = Some(yield_ty);
10751075
}
10761076

1077-
GatherLocalsVisitor { fcx: &fcx, parent_id: fn_id, }.visit_body(body);
1077+
let outer_def_id = fcx.tcx.closure_base_def_id(fcx.tcx.hir.local_def_id(fn_id));
1078+
let outer_node_id = fcx.tcx.hir.as_local_node_id(outer_def_id).unwrap();
1079+
GatherLocalsVisitor { fcx: &fcx, parent_id: outer_node_id, }.visit_body(body);
10781080

10791081
// Add formal parameters.
10801082
for (arg_ty, arg) in fn_sig.inputs().iter().zip(&body.arguments) {
@@ -2265,19 +2267,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
22652267
/// `InferCtxt::instantiate_opaque_types` for more details.
22662268
fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
22672269
&self,
2268-
fn_id: ast::NodeId,
2270+
parent_id: ast::NodeId,
22692271
value: &T,
22702272
) -> T {
2271-
let fn_def_id = self.tcx.hir.local_def_id(fn_id);
2272-
debug!(
2273-
"instantiate_opaque_types_from_value(fn_def_id={:?}, value={:?})",
2274-
fn_def_id,
2275-
value
2276-
);
2273+
let parent_def_id = self.tcx.hir.local_def_id(parent_id);
2274+
debug!("instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
2275+
parent_def_id,
2276+
value);
22772277

22782278
let (value, opaque_type_map) = self.register_infer_ok_obligations(
22792279
self.instantiate_opaque_types(
2280-
fn_def_id,
2280+
parent_def_id,
22812281
self.body_id,
22822282
self.param_env,
22832283
value,

0 commit comments

Comments
 (0)