Skip to content

Commit 83da9a8

Browse files
committed
Directly construct Inherited.
1 parent 35a0961 commit 83da9a8

File tree

4 files changed

+151
-176
lines changed

4 files changed

+151
-176
lines changed

compiler/rustc_hir_typeck/src/inherited.rs

+7-32
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
44
use rustc_hir as hir;
55
use rustc_hir::def_id::LocalDefId;
66
use rustc_hir::HirIdMap;
7-
use rustc_infer::infer;
87
use rustc_infer::infer::{DefiningAnchor, InferCtxt, InferOk, TyCtxtInferExt};
98
use rustc_middle::ty::visit::TypeVisitableExt;
109
use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -73,40 +72,16 @@ impl<'tcx> Deref for Inherited<'tcx> {
7372
}
7473
}
7574

76-
/// A temporary returned by `Inherited::build(...)`. This is necessary
77-
/// for multiple `InferCtxt` to share the same `typeck_results`
78-
/// without using `Rc` or something similar.
79-
pub struct InheritedBuilder<'tcx> {
80-
infcx: infer::InferCtxtBuilder<'tcx>,
81-
typeck_results: RefCell<ty::TypeckResults<'tcx>>,
82-
}
83-
8475
impl<'tcx> Inherited<'tcx> {
85-
pub fn build(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> InheritedBuilder<'tcx> {
76+
pub fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
8677
let hir_owner = tcx.hir().local_def_id_to_hir_id(def_id).owner;
8778

88-
InheritedBuilder {
89-
infcx: tcx
90-
.infer_ctxt()
91-
.ignoring_regions()
92-
.with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)),
93-
typeck_results: RefCell::new(ty::TypeckResults::new(hir_owner)),
94-
}
95-
}
96-
}
97-
98-
impl<'tcx> InheritedBuilder<'tcx> {
99-
pub fn enter<F, R>(mut self, f: F) -> R
100-
where
101-
F: FnOnce(&Inherited<'tcx>) -> R,
102-
{
103-
f(&Inherited::new(self.infcx.build(), self.typeck_results))
104-
}
105-
}
106-
107-
impl<'tcx> Inherited<'tcx> {
108-
fn new(infcx: InferCtxt<'tcx>, typeck_results: RefCell<ty::TypeckResults<'tcx>>) -> Self {
109-
let tcx = infcx.tcx;
79+
let infcx = tcx
80+
.infer_ctxt()
81+
.ignoring_regions()
82+
.with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id))
83+
.build();
84+
let typeck_results = RefCell::new(ty::TypeckResults::new(hir_owner));
11085

11186
Inherited {
11287
typeck_results,

compiler/rustc_hir_typeck/src/lib.rs

+112-111
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,14 @@ mod rvalue_scopes;
4545
mod upvar;
4646
mod writeback;
4747

48-
pub use diverges::Diverges;
49-
pub use expectation::Expectation;
50-
pub use fn_ctxt::*;
51-
pub use inherited::{Inherited, InheritedBuilder};
48+
pub use fn_ctxt::FnCtxt;
49+
pub use inherited::Inherited;
5250

5351
use crate::check::check_fn;
5452
use crate::coercion::DynamicCoerceMany;
53+
use crate::diverges::Diverges;
54+
use crate::expectation::Expectation;
55+
use crate::fn_ctxt::RawTy;
5556
use crate::gather_locals::GatherLocalsVisitor;
5657
use rustc_data_structures::unord::UnordSet;
5758
use rustc_errors::{
@@ -206,135 +207,135 @@ fn typeck_with_fallback<'tcx>(
206207
});
207208
let body = tcx.hir().body(body_id);
208209

209-
let typeck_results = Inherited::build(tcx, def_id).enter(|inh| {
210-
let param_env = tcx.param_env(def_id);
211-
let param_env = if tcx.has_attr(def_id.to_def_id(), sym::rustc_do_not_const_check) {
212-
param_env.without_const()
210+
let param_env = tcx.param_env(def_id);
211+
let param_env = if tcx.has_attr(def_id.to_def_id(), sym::rustc_do_not_const_check) {
212+
param_env.without_const()
213+
} else {
214+
param_env
215+
};
216+
let inh = Inherited::new(tcx, def_id);
217+
let mut fcx = FnCtxt::new(&inh, param_env, def_id);
218+
219+
if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
220+
let fn_sig = if rustc_hir_analysis::collect::get_infer_ret_ty(&decl.output).is_some() {
221+
fcx.astconv().ty_of_fn(id, header.unsafety, header.abi, decl, None, None)
213222
} else {
214-
param_env
223+
tcx.fn_sig(def_id).subst_identity()
215224
};
216-
let mut fcx = FnCtxt::new(&inh, param_env, def_id);
217225

218-
if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
219-
let fn_sig = if rustc_hir_analysis::collect::get_infer_ret_ty(&decl.output).is_some() {
220-
fcx.astconv().ty_of_fn(id, header.unsafety, header.abi, decl, None, None)
221-
} else {
222-
tcx.fn_sig(def_id).subst_identity()
223-
};
226+
check_abi(tcx, id, span, fn_sig.abi());
224227

225-
check_abi(tcx, id, span, fn_sig.abi());
228+
// Compute the function signature from point of view of inside the fn.
229+
let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
230+
let fn_sig = fcx.normalize(body.value.span, fn_sig);
226231

227-
// Compute the function signature from point of view of inside the fn.
228-
let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
229-
let fn_sig = fcx.normalize(body.value.span, fn_sig);
230-
231-
check_fn(&mut fcx, fn_sig, decl, def_id, body, None);
232-
} else {
233-
let expected_type = body_ty
234-
.and_then(|ty| match ty.kind {
235-
hir::TyKind::Infer => Some(fcx.astconv().ast_ty_to_ty(ty)),
236-
_ => None,
237-
})
238-
.unwrap_or_else(|| match tcx.hir().get(id) {
239-
Node::AnonConst(_) => match tcx.hir().get(tcx.hir().parent_id(id)) {
240-
Node::Expr(&hir::Expr {
241-
kind: hir::ExprKind::ConstBlock(ref anon_const),
242-
..
243-
}) if anon_const.hir_id == id => fcx.next_ty_var(TypeVariableOrigin {
244-
kind: TypeVariableOriginKind::TypeInference,
245-
span,
246-
}),
247-
Node::Ty(&hir::Ty {
248-
kind: hir::TyKind::Typeof(ref anon_const), ..
249-
}) if anon_const.hir_id == id => fcx.next_ty_var(TypeVariableOrigin {
232+
check_fn(&mut fcx, fn_sig, decl, def_id, body, None);
233+
} else {
234+
let expected_type = body_ty
235+
.and_then(|ty| match ty.kind {
236+
hir::TyKind::Infer => Some(fcx.astconv().ast_ty_to_ty(ty)),
237+
_ => None,
238+
})
239+
.unwrap_or_else(|| match tcx.hir().get(id) {
240+
Node::AnonConst(_) => match tcx.hir().get(tcx.hir().parent_id(id)) {
241+
Node::Expr(&hir::Expr {
242+
kind: hir::ExprKind::ConstBlock(ref anon_const),
243+
..
244+
}) if anon_const.hir_id == id => fcx.next_ty_var(TypeVariableOrigin {
245+
kind: TypeVariableOriginKind::TypeInference,
246+
span,
247+
}),
248+
Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(ref anon_const), .. })
249+
if anon_const.hir_id == id =>
250+
{
251+
fcx.next_ty_var(TypeVariableOrigin {
250252
kind: TypeVariableOriginKind::TypeInference,
251253
span,
252-
}),
253-
Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), .. })
254-
| Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), .. }) => {
255-
let operand_ty =
256-
asm.operands.iter().find_map(|(op, _op_sp)| match op {
257-
hir::InlineAsmOperand::Const { anon_const }
258-
if anon_const.hir_id == id =>
259-
{
260-
// Inline assembly constants must be integers.
261-
Some(fcx.next_int_var())
262-
}
263-
hir::InlineAsmOperand::SymFn { anon_const }
264-
if anon_const.hir_id == id =>
265-
{
266-
Some(fcx.next_ty_var(TypeVariableOrigin {
267-
kind: TypeVariableOriginKind::MiscVariable,
268-
span,
269-
}))
270-
}
271-
_ => None,
272-
});
273-
operand_ty.unwrap_or_else(fallback)
274-
}
275-
_ => fallback(),
276-
},
254+
})
255+
}
256+
Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), .. })
257+
| Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), .. }) => {
258+
let operand_ty = asm.operands.iter().find_map(|(op, _op_sp)| match op {
259+
hir::InlineAsmOperand::Const { anon_const }
260+
if anon_const.hir_id == id =>
261+
{
262+
// Inline assembly constants must be integers.
263+
Some(fcx.next_int_var())
264+
}
265+
hir::InlineAsmOperand::SymFn { anon_const }
266+
if anon_const.hir_id == id =>
267+
{
268+
Some(fcx.next_ty_var(TypeVariableOrigin {
269+
kind: TypeVariableOriginKind::MiscVariable,
270+
span,
271+
}))
272+
}
273+
_ => None,
274+
});
275+
operand_ty.unwrap_or_else(fallback)
276+
}
277277
_ => fallback(),
278-
});
278+
},
279+
_ => fallback(),
280+
});
279281

280-
let expected_type = fcx.normalize(body.value.span, expected_type);
281-
fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
282+
let expected_type = fcx.normalize(body.value.span, expected_type);
283+
fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
282284

283-
// Gather locals in statics (because of block expressions).
284-
GatherLocalsVisitor::new(&fcx).visit_body(body);
285+
// Gather locals in statics (because of block expressions).
286+
GatherLocalsVisitor::new(&fcx).visit_body(body);
285287

286-
fcx.check_expr_coercable_to_type(&body.value, expected_type, None);
288+
fcx.check_expr_coercable_to_type(&body.value, expected_type, None);
287289

288-
fcx.write_ty(id, expected_type);
289-
};
290+
fcx.write_ty(id, expected_type);
291+
};
290292

291-
fcx.type_inference_fallback();
292-
293-
// Even though coercion casts provide type hints, we check casts after fallback for
294-
// backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
295-
fcx.check_casts();
296-
fcx.select_obligations_where_possible(|_| {});
297-
298-
// Closure and generator analysis may run after fallback
299-
// because they don't constrain other type variables.
300-
// Closure analysis only runs on closures. Therefore they only need to fulfill non-const predicates (as of now)
301-
let prev_constness = fcx.param_env.constness();
302-
fcx.param_env = fcx.param_env.without_const();
303-
fcx.closure_analyze(body);
304-
fcx.param_env = fcx.param_env.with_constness(prev_constness);
305-
assert!(fcx.deferred_call_resolutions.borrow().is_empty());
306-
// Before the generator analysis, temporary scopes shall be marked to provide more
307-
// precise information on types to be captured.
308-
fcx.resolve_rvalue_scopes(def_id.to_def_id());
309-
310-
for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
311-
let ty = fcx.normalize(span, ty);
312-
fcx.require_type_is_sized(ty, span, code);
313-
}
293+
fcx.type_inference_fallback();
294+
295+
// Even though coercion casts provide type hints, we check casts after fallback for
296+
// backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
297+
fcx.check_casts();
298+
fcx.select_obligations_where_possible(|_| {});
299+
300+
// Closure and generator analysis may run after fallback
301+
// because they don't constrain other type variables.
302+
// Closure analysis only runs on closures. Therefore they only need to fulfill non-const predicates (as of now)
303+
let prev_constness = fcx.param_env.constness();
304+
fcx.param_env = fcx.param_env.without_const();
305+
fcx.closure_analyze(body);
306+
fcx.param_env = fcx.param_env.with_constness(prev_constness);
307+
assert!(fcx.deferred_call_resolutions.borrow().is_empty());
308+
// Before the generator analysis, temporary scopes shall be marked to provide more
309+
// precise information on types to be captured.
310+
fcx.resolve_rvalue_scopes(def_id.to_def_id());
311+
312+
for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
313+
let ty = fcx.normalize(span, ty);
314+
fcx.require_type_is_sized(ty, span, code);
315+
}
314316

315-
fcx.select_obligations_where_possible(|_| {});
317+
fcx.select_obligations_where_possible(|_| {});
316318

317-
debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());
319+
debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());
318320

319-
// This must be the last thing before `report_ambiguity_errors`.
320-
fcx.resolve_generator_interiors(def_id.to_def_id());
321+
// This must be the last thing before `report_ambiguity_errors`.
322+
fcx.resolve_generator_interiors(def_id.to_def_id());
321323

322-
debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());
324+
debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());
323325

324-
if let None = fcx.infcx.tainted_by_errors() {
325-
fcx.report_ambiguity_errors();
326-
}
326+
if let None = fcx.infcx.tainted_by_errors() {
327+
fcx.report_ambiguity_errors();
328+
}
327329

328-
if let None = fcx.infcx.tainted_by_errors() {
329-
fcx.check_transmutes();
330-
}
330+
if let None = fcx.infcx.tainted_by_errors() {
331+
fcx.check_transmutes();
332+
}
331333

332-
fcx.check_asms();
334+
fcx.check_asms();
333335

334-
fcx.infcx.skip_region_resolution();
336+
fcx.infcx.skip_region_resolution();
335337

336-
fcx.resolve_type_vars_in_body(body)
337-
});
338+
let typeck_results = fcx.resolve_type_vars_in_body(body);
338339

339340
// Consistency check our TypeckResults instance can hold all ItemLocalIds
340341
// it will need to hold.

src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -369,10 +369,10 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
369369
Node::Item(item) => {
370370
if let ItemKind::Fn(_, _, body_id) = &item.kind
371371
&& let output_ty = return_ty(cx, item.owner_id)
372-
&& Inherited::build(cx.tcx, item.owner_id.def_id).enter(|inherited| {
373-
let fn_ctxt = FnCtxt::new(inherited, cx.param_env, item.owner_id.def_id);
374-
fn_ctxt.can_coerce(ty, output_ty)
375-
}) {
372+
&& let inherited = Inherited::new(cx.tcx, item.owner_id.def_id)
373+
&& let fn_ctxt = FnCtxt::new(&inherited, cx.param_env, item.owner_id.def_id)
374+
&& fn_ctxt.can_coerce(ty, output_ty)
375+
{
376376
if has_lifetime(output_ty) && has_lifetime(ty) {
377377
return false;
378378
}

src/tools/clippy/clippy_lints/src/transmute/utils.rs

+28-29
Original file line numberDiff line numberDiff line change
@@ -33,38 +33,37 @@ pub(super) fn check_cast<'tcx>(
3333
let hir_id = e.hir_id;
3434
let local_def_id = hir_id.owner.def_id;
3535

36-
Inherited::build(cx.tcx, local_def_id).enter(|inherited| {
37-
let fn_ctxt = FnCtxt::new(inherited, cx.param_env, local_def_id);
36+
let inherited = Inherited::new(cx.tcx, local_def_id);
37+
let fn_ctxt = FnCtxt::new(&inherited, cx.param_env, local_def_id);
3838

39-
// If we already have errors, we can't be sure we can pointer cast.
39+
// If we already have errors, we can't be sure we can pointer cast.
40+
assert!(
41+
!fn_ctxt.errors_reported_since_creation(),
42+
"Newly created FnCtxt contained errors"
43+
);
44+
45+
if let Ok(check) = cast::CastCheck::new(
46+
&fn_ctxt,
47+
e,
48+
from_ty,
49+
to_ty,
50+
// We won't show any error to the user, so we don't care what the span is here.
51+
DUMMY_SP,
52+
DUMMY_SP,
53+
hir::Constness::NotConst,
54+
) {
55+
let res = check.do_check(&fn_ctxt);
56+
57+
// do_check's documentation says that it might return Ok and create
58+
// errors in the fcx instead of returning Err in some cases. Those cases
59+
// should be filtered out before getting here.
4060
assert!(
4161
!fn_ctxt.errors_reported_since_creation(),
42-
"Newly created FnCtxt contained errors"
62+
"`fn_ctxt` contained errors after cast check!"
4363
);
4464

45-
if let Ok(check) = cast::CastCheck::new(
46-
&fn_ctxt,
47-
e,
48-
from_ty,
49-
to_ty,
50-
// We won't show any error to the user, so we don't care what the span is here.
51-
DUMMY_SP,
52-
DUMMY_SP,
53-
hir::Constness::NotConst,
54-
) {
55-
let res = check.do_check(&fn_ctxt);
56-
57-
// do_check's documentation says that it might return Ok and create
58-
// errors in the fcx instead of returning Err in some cases. Those cases
59-
// should be filtered out before getting here.
60-
assert!(
61-
!fn_ctxt.errors_reported_since_creation(),
62-
"`fn_ctxt` contained errors after cast check!"
63-
);
64-
65-
res.ok()
66-
} else {
67-
None
68-
}
69-
})
65+
res.ok()
66+
} else {
67+
None
68+
}
7069
}

0 commit comments

Comments
 (0)