Skip to content

Commit c190f66

Browse files
Moved GatherLocalsVisitor to its own file
1 parent 3e77064 commit c190f66

File tree

2 files changed

+126
-112
lines changed

2 files changed

+126
-112
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
use crate::check::{FnCtxt, LocalTy, UserType};
2+
use rustc_hir as hir;
3+
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
4+
use rustc_hir::PatKind;
5+
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
6+
use rustc_middle::ty::Ty;
7+
use rustc_span::Span;
8+
use rustc_trait_selection::traits;
9+
10+
pub(super) struct GatherLocalsVisitor<'a, 'tcx> {
11+
fcx: &'a FnCtxt<'a, 'tcx>,
12+
parent_id: hir::HirId,
13+
}
14+
15+
impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
16+
pub(super) fn new(fcx: &'a FnCtxt<'a, 'tcx>, parent_id: hir::HirId) -> Self {
17+
Self { fcx, parent_id }
18+
}
19+
20+
fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
21+
match ty_opt {
22+
None => {
23+
// Infer the variable's type.
24+
let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
25+
kind: TypeVariableOriginKind::TypeInference,
26+
span,
27+
});
28+
self.fcx
29+
.locals
30+
.borrow_mut()
31+
.insert(nid, LocalTy { decl_ty: var_ty, revealed_ty: var_ty });
32+
var_ty
33+
}
34+
Some(typ) => {
35+
// Take type that the user specified.
36+
self.fcx.locals.borrow_mut().insert(nid, typ);
37+
typ.revealed_ty
38+
}
39+
}
40+
}
41+
}
42+
43+
impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
44+
type Map = intravisit::ErasedMap<'tcx>;
45+
46+
fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
47+
NestedVisitorMap::None
48+
}
49+
50+
// Add explicitly-declared locals.
51+
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
52+
let local_ty = match local.ty {
53+
Some(ref ty) => {
54+
let o_ty = self.fcx.to_ty(&ty);
55+
56+
let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
57+
self.fcx.instantiate_opaque_types_from_value(self.parent_id, &o_ty, ty.span)
58+
} else {
59+
o_ty
60+
};
61+
62+
let c_ty = self
63+
.fcx
64+
.inh
65+
.infcx
66+
.canonicalize_user_type_annotation(&UserType::Ty(revealed_ty));
67+
debug!(
68+
"visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
69+
ty.hir_id, o_ty, revealed_ty, c_ty
70+
);
71+
self.fcx
72+
.typeck_results
73+
.borrow_mut()
74+
.user_provided_types_mut()
75+
.insert(ty.hir_id, c_ty);
76+
77+
Some(LocalTy { decl_ty: o_ty, revealed_ty })
78+
}
79+
None => None,
80+
};
81+
self.assign(local.span, local.hir_id, local_ty);
82+
83+
debug!(
84+
"local variable {:?} is assigned type {}",
85+
local.pat,
86+
self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&local.hir_id).unwrap().decl_ty)
87+
);
88+
intravisit::walk_local(self, local);
89+
}
90+
91+
// Add pattern bindings.
92+
fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
93+
if let PatKind::Binding(_, _, ident, _) = p.kind {
94+
let var_ty = self.assign(p.span, p.hir_id, None);
95+
96+
if !self.fcx.tcx.features().unsized_locals {
97+
self.fcx.require_type_is_sized(var_ty, p.span, traits::VariableType(p.hir_id));
98+
}
99+
100+
debug!(
101+
"pattern binding {} is assigned to {} with type {:?}",
102+
ident,
103+
self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&p.hir_id).unwrap().decl_ty),
104+
var_ty
105+
);
106+
}
107+
intravisit::walk_pat(self, p);
108+
}
109+
110+
// Don't descend into the bodies of nested closures.
111+
fn visit_fn(
112+
&mut self,
113+
_: intravisit::FnKind<'tcx>,
114+
_: &'tcx hir::FnDecl<'tcx>,
115+
_: hir::BodyId,
116+
_: Span,
117+
_: hir::HirId,
118+
) {
119+
}
120+
}

compiler/rustc_typeck/src/check/mod.rs

Lines changed: 6 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ mod compare_method;
7272
pub mod demand;
7373
pub mod dropck;
7474
mod expr;
75+
mod gather_locals;
7576
mod generator_interior;
7677
pub mod intrinsic;
7778
pub mod method;
@@ -87,6 +88,7 @@ pub mod writeback;
8788
use crate::astconv::{
8889
AstConv, ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, PathSeg,
8990
};
91+
use crate::check::gather_locals::GatherLocalsVisitor;
9092
use crate::check::util::MaybeInProgressTables;
9193
use rustc_ast as ast;
9294
use rustc_ast::util::parser::ExprPrecedence;
@@ -98,9 +100,9 @@ use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder,
98100
use rustc_hir as hir;
99101
use rustc_hir::def::{CtorOf, DefKind, Res};
100102
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
101-
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
103+
use rustc_hir::intravisit::Visitor;
102104
use rustc_hir::lang_items::LangItem;
103-
use rustc_hir::{ExprKind, GenericArg, HirIdMap, ItemKind, Node, PatKind, QPath};
105+
use rustc_hir::{ExprKind, GenericArg, HirIdMap, ItemKind, Node, QPath};
104106
use rustc_index::bit_set::BitSet;
105107
use rustc_index::vec::Idx;
106108
use rustc_infer::infer;
@@ -997,7 +999,7 @@ fn typeck_with_fallback<'tcx>(
997999
};
9981000

9991001
// Gather locals in statics (because of block expressions).
1000-
GatherLocalsVisitor { fcx: &fcx, parent_id: id }.visit_body(body);
1002+
GatherLocalsVisitor::new(&fcx, id).visit_body(body);
10011003

10021004
fcx.check_expr_coercable_to_type(&body.value, revealed_ty, None);
10031005

@@ -1097,114 +1099,6 @@ fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
10971099
}
10981100
}
10991101

1100-
struct GatherLocalsVisitor<'a, 'tcx> {
1101-
fcx: &'a FnCtxt<'a, 'tcx>,
1102-
parent_id: hir::HirId,
1103-
}
1104-
1105-
impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
1106-
fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
1107-
match ty_opt {
1108-
None => {
1109-
// Infer the variable's type.
1110-
let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
1111-
kind: TypeVariableOriginKind::TypeInference,
1112-
span,
1113-
});
1114-
self.fcx
1115-
.locals
1116-
.borrow_mut()
1117-
.insert(nid, LocalTy { decl_ty: var_ty, revealed_ty: var_ty });
1118-
var_ty
1119-
}
1120-
Some(typ) => {
1121-
// Take type that the user specified.
1122-
self.fcx.locals.borrow_mut().insert(nid, typ);
1123-
typ.revealed_ty
1124-
}
1125-
}
1126-
}
1127-
}
1128-
1129-
impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
1130-
type Map = intravisit::ErasedMap<'tcx>;
1131-
1132-
fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
1133-
NestedVisitorMap::None
1134-
}
1135-
1136-
// Add explicitly-declared locals.
1137-
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
1138-
let local_ty = match local.ty {
1139-
Some(ref ty) => {
1140-
let o_ty = self.fcx.to_ty(&ty);
1141-
1142-
let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
1143-
self.fcx.instantiate_opaque_types_from_value(self.parent_id, &o_ty, ty.span)
1144-
} else {
1145-
o_ty
1146-
};
1147-
1148-
let c_ty = self
1149-
.fcx
1150-
.inh
1151-
.infcx
1152-
.canonicalize_user_type_annotation(&UserType::Ty(revealed_ty));
1153-
debug!(
1154-
"visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
1155-
ty.hir_id, o_ty, revealed_ty, c_ty
1156-
);
1157-
self.fcx
1158-
.typeck_results
1159-
.borrow_mut()
1160-
.user_provided_types_mut()
1161-
.insert(ty.hir_id, c_ty);
1162-
1163-
Some(LocalTy { decl_ty: o_ty, revealed_ty })
1164-
}
1165-
None => None,
1166-
};
1167-
self.assign(local.span, local.hir_id, local_ty);
1168-
1169-
debug!(
1170-
"local variable {:?} is assigned type {}",
1171-
local.pat,
1172-
self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&local.hir_id).unwrap().decl_ty)
1173-
);
1174-
intravisit::walk_local(self, local);
1175-
}
1176-
1177-
// Add pattern bindings.
1178-
fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
1179-
if let PatKind::Binding(_, _, ident, _) = p.kind {
1180-
let var_ty = self.assign(p.span, p.hir_id, None);
1181-
1182-
if !self.fcx.tcx.features().unsized_locals {
1183-
self.fcx.require_type_is_sized(var_ty, p.span, traits::VariableType(p.hir_id));
1184-
}
1185-
1186-
debug!(
1187-
"pattern binding {} is assigned to {} with type {:?}",
1188-
ident,
1189-
self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&p.hir_id).unwrap().decl_ty),
1190-
var_ty
1191-
);
1192-
}
1193-
intravisit::walk_pat(self, p);
1194-
}
1195-
1196-
// Don't descend into the bodies of nested closures.
1197-
fn visit_fn(
1198-
&mut self,
1199-
_: intravisit::FnKind<'tcx>,
1200-
_: &'tcx hir::FnDecl<'tcx>,
1201-
_: hir::BodyId,
1202-
_: Span,
1203-
_: hir::HirId,
1204-
) {
1205-
}
1206-
}
1207-
12081102
/// When `check_fn` is invoked on a generator (i.e., a body that
12091103
/// includes yield), it returns back some information about the yield
12101104
/// points.
@@ -1285,7 +1179,7 @@ fn check_fn<'a, 'tcx>(
12851179

12861180
let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id).to_def_id()).expect_local();
12871181
let outer_hir_id = hir.local_def_id_to_hir_id(outer_def_id);
1288-
GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id }.visit_body(body);
1182+
GatherLocalsVisitor::new(&fcx, outer_hir_id).visit_body(body);
12891183

12901184
// C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
12911185
// (as it's created inside the body itself, not passed in from outside).

0 commit comments

Comments
 (0)