Skip to content

Commit 609a90d

Browse files
committed
Compute explicit MIR params on THIR.
1 parent 26037b1 commit 609a90d

File tree

5 files changed

+87
-53
lines changed

5 files changed

+87
-53
lines changed

compiler/rustc_middle/src/thir.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,22 @@ thir_with_elements! {
7878
blocks: BlockId => Block => "b{}",
7979
exprs: ExprId => Expr<'tcx> => "e{}",
8080
stmts: StmtId => Stmt<'tcx> => "s{}",
81+
params: ParamId => Param<'tcx> => "p{}",
82+
}
83+
84+
/// Description of a type-checked function parameter.
85+
#[derive(Clone, Debug, HashStable)]
86+
pub struct Param<'tcx> {
87+
/// The pattern that appears in the parameter list.
88+
pub pat: Pat<'tcx>,
89+
/// The possibly inferred type.
90+
pub ty: Ty<'tcx>,
91+
/// Span of the explicitly provided type, or None if inferred for closures.
92+
pub ty_span: Option<Span>,
93+
/// Whether this param is `self`, and how it is bound.
94+
pub self_kind: Option<hir::ImplicitSelfKind>,
95+
/// HirId for lints.
96+
pub hir_id: hir::HirId,
8197
}
8298

8399
#[derive(Copy, Clone, Debug, HashStable)]
@@ -548,6 +564,15 @@ impl<'tcx> Pat<'tcx> {
548564
pub fn wildcard_from_ty(ty: Ty<'tcx>) -> Self {
549565
Pat { ty, span: DUMMY_SP, kind: Box::new(PatKind::Wild) }
550566
}
567+
568+
pub fn simple_ident(&self) -> Option<Symbol> {
569+
match &*self.kind {
570+
PatKind::Binding { name, mode: BindingMode::ByValue, subpattern: None, .. } => {
571+
Some(*name)
572+
}
573+
_ => None,
574+
}
575+
}
551576
}
552577

553578
#[derive(Clone, Debug, HashStable)]

compiler/rustc_mir_build/src/build/matches/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -573,15 +573,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
573573

574574
_ => {
575575
let place_builder = unpack!(block = self.as_place_builder(block, initializer));
576-
self.place_into_pattern(block, irrefutable_pat, place_builder, true)
576+
self.place_into_pattern(block, &irrefutable_pat, place_builder, true)
577577
}
578578
}
579579
}
580580

581581
pub(crate) fn place_into_pattern(
582582
&mut self,
583583
block: BasicBlock,
584-
irrefutable_pat: Pat<'tcx>,
584+
irrefutable_pat: &Pat<'tcx>,
585585
initializer: PlaceBuilder<'tcx>,
586586
set_match_place: bool,
587587
) -> BlockAnd<()> {

compiler/rustc_mir_build/src/build/mod.rs

Lines changed: 12 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
pub(crate) use crate::build::expr::as_constant::lit_to_mir_constant;
22
use crate::build::expr::as_place::PlaceBuilder;
33
use crate::build::scope::DropKind;
4-
use crate::thir::pattern::pat_from_hir;
54
use rustc_apfloat::ieee::{Double, Single};
65
use rustc_apfloat::Float;
76
use rustc_data_structures::fx::FxHashMap;
87
use rustc_errors::ErrorGuaranteed;
98
use rustc_hir as hir;
109
use rustc_hir::def_id::{DefId, LocalDefId};
11-
use rustc_hir::lang_items::LangItem;
1210
use rustc_hir::{GeneratorKind, ImplicitSelfKind, Node};
1311
use rustc_index::vec::{Idx, IndexVec};
1412
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
@@ -17,8 +15,7 @@ use rustc_middle::middle::region;
1715
use rustc_middle::mir::interpret::ConstValue;
1816
use rustc_middle::mir::interpret::Scalar;
1917
use rustc_middle::mir::*;
20-
use rustc_middle::thir::{BindingMode, Expr, ExprId, LintLevel, LocalVarId, PatKind, Thir};
21-
use rustc_middle::ty::subst::Subst;
18+
use rustc_middle::thir::{BindingMode, Expr, ExprId, LintLevel, LocalVarId, Param, PatKind, Thir};
2219
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable, TypeckResults};
2320
use rustc_span::symbol::sym;
2421
use rustc_span::Span;
@@ -439,10 +436,10 @@ macro_rules! unpack {
439436
///////////////////////////////////////////////////////////////////////////
440437
/// the main entry point for building MIR for a function
441438
442-
struct ArgInfo<'tcx>(
439+
struct ArgInfo<'thir, 'tcx>(
443440
Ty<'tcx>,
444441
Option<Span>,
445-
Option<&'tcx hir::Param<'tcx>>,
442+
Option<&'thir Param<'tcx>>,
446443
Option<ImplicitSelfKind>,
447444
);
448445

@@ -500,38 +497,8 @@ fn construct_fn<'tcx>(
500497
_ => vec![],
501498
};
502499

503-
let explicit_arguments = body.params.iter().enumerate().map(|(index, arg)| {
504-
let owner_id = tcx.hir().body_owner(body_id);
505-
let opt_ty_info;
506-
let self_arg;
507-
if let Some(ref fn_decl) = tcx.hir().fn_decl_by_hir_id(owner_id) {
508-
opt_ty_info = fn_decl
509-
.inputs
510-
.get(index)
511-
// Make sure that inferred closure args have no type span
512-
.and_then(|ty| if arg.pat.span != ty.span { Some(ty.span) } else { None });
513-
self_arg = if index == 0 && fn_decl.implicit_self.has_implicit_self() {
514-
Some(fn_decl.implicit_self)
515-
} else {
516-
None
517-
};
518-
} else {
519-
opt_ty_info = None;
520-
self_arg = None;
521-
}
522-
523-
// C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
524-
// (as it's created inside the body itself, not passed in from outside).
525-
let ty = if fn_sig.c_variadic && index == fn_sig.inputs().len() {
526-
let va_list_did = tcx.require_lang_item(LangItem::VaList, Some(arg.span));
527-
528-
tcx.bound_type_of(va_list_did).subst(tcx, &[tcx.lifetimes.re_erased.into()])
529-
} else {
530-
fn_sig.inputs()[index]
531-
};
532-
533-
ArgInfo(ty, opt_ty_info, Some(&arg), self_arg)
534-
});
500+
let explicit_arguments =
501+
thir.params.iter().map(|arg| ArgInfo(arg.ty, arg.ty_span, Some(&arg), arg.self_kind));
535502

536503
let arguments = implicit_argument.into_iter().chain(explicit_arguments);
537504

@@ -842,7 +809,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
842809
&mut self,
843810
mut block: BasicBlock,
844811
fn_def_id: LocalDefId,
845-
arguments: &[ArgInfo<'tcx>],
812+
arguments: &[ArgInfo<'_, 'tcx>],
846813
argument_scope: region::Scope,
847814
expr: &Expr<'tcx>,
848815
) -> BlockAnd<()> {
@@ -853,9 +820,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
853820
let arg_local = self.local_decls.push(LocalDecl::with_source_info(ty, source_info));
854821

855822
// If this is a simple binding pattern, give debuginfo a nice name.
856-
if let Some(arg) = arg_opt && let Some(ident) = arg.pat.simple_ident() {
823+
if let Some(arg) = arg_opt && let Some(name) = arg.pat.simple_ident() {
857824
self.var_debug_info.push(VarDebugInfo {
858-
name: ident.name,
825+
name,
859826
source_info,
860827
value: VarDebugInfoContents::Place(arg_local.into()),
861828
});
@@ -943,15 +910,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
943910
let Some(arg) = arg_opt else {
944911
continue;
945912
};
946-
let pat = match tcx.hir().get(arg.pat.hir_id) {
947-
Node::Pat(pat) => pat,
948-
node => bug!("pattern became {:?}", node),
949-
};
950-
let pattern = pat_from_hir(tcx, self.param_env, self.typeck_results, pat);
951913
let original_source_scope = self.source_scope;
952-
let span = pattern.span;
914+
let span = arg.pat.span;
953915
self.set_correct_source_scope_for_arg(arg.hir_id, original_source_scope, span);
954-
match *pattern.kind {
916+
match *arg.pat.kind {
955917
// Don't introduce extra copies for simple bindings
956918
PatKind::Binding {
957919
mutability,
@@ -983,12 +945,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
983945
scope = self.declare_bindings(
984946
scope,
985947
expr.span,
986-
&pattern,
948+
&arg.pat,
987949
matches::ArmHasGuard(false),
988950
Some((Some(&place), span)),
989951
);
990952
let place_builder = PlaceBuilder::from(local);
991-
unpack!(block = self.place_into_pattern(block, pattern, place_builder, false));
953+
unpack!(block = self.place_into_pattern(block, &arg.pat, place_builder, false));
992954
}
993955
}
994956
self.source_scope = original_source_scope;

compiler/rustc_mir_build/src/thir/cx/mod.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ use rustc_data_structures::steal::Steal;
99
use rustc_errors::ErrorGuaranteed;
1010
use rustc_hir as hir;
1111
use rustc_hir::def_id::{DefId, LocalDefId};
12+
use rustc_hir::lang_items::LangItem;
1213
use rustc_hir::HirId;
1314
use rustc_hir::Node;
1415
use rustc_middle::middle::region;
1516
use rustc_middle::thir::*;
16-
use rustc_middle::ty::{self, RvalueScopes, TyCtxt};
17+
use rustc_middle::ty::{self, RvalueScopes, Subst, TyCtxt};
1718
use rustc_span::Span;
1819

1920
pub(crate) fn thir_body<'tcx>(
@@ -27,6 +28,13 @@ pub(crate) fn thir_body<'tcx>(
2728
return Err(reported);
2829
}
2930
let expr = cx.mirror_expr(&body.value);
31+
32+
let owner_id = hir.local_def_id_to_hir_id(owner_def.did);
33+
if let Some(ref fn_decl) = hir.fn_decl_by_hir_id(owner_id) {
34+
let explicit_params = cx.explicit_params(owner_id, fn_decl, body);
35+
cx.thir.params = explicit_params.collect();
36+
}
37+
3038
Ok((tcx.alloc_steal_thir(cx.thir), expr))
3139
}
3240

@@ -85,6 +93,44 @@ impl<'tcx> Cx<'tcx> {
8593
};
8694
pat_from_hir(self.tcx, self.param_env, self.typeck_results(), p)
8795
}
96+
97+
fn explicit_params<'a>(
98+
&'a mut self,
99+
owner_id: HirId,
100+
fn_decl: &'tcx hir::FnDecl<'tcx>,
101+
body: &'tcx hir::Body<'tcx>,
102+
) -> impl Iterator<Item = Param<'tcx>> + 'a {
103+
let fn_sig = self.typeck_results.liberated_fn_sigs()[owner_id];
104+
105+
body.params.iter().enumerate().map(move |(index, param)| {
106+
let ty_span = fn_decl
107+
.inputs
108+
.get(index)
109+
// Make sure that inferred closure args have no type span
110+
.and_then(|ty| if param.pat.span != ty.span { Some(ty.span) } else { None });
111+
112+
let self_kind = if index == 0 && fn_decl.implicit_self.has_implicit_self() {
113+
Some(fn_decl.implicit_self)
114+
} else {
115+
None
116+
};
117+
118+
// C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
119+
// (as it's created inside the body itself, not passed in from outside).
120+
let ty = if fn_decl.c_variadic && index == fn_decl.inputs.len() {
121+
let va_list_did = self.tcx.require_lang_item(LangItem::VaList, Some(param.span));
122+
123+
self.tcx
124+
.bound_type_of(va_list_did)
125+
.subst(self.tcx, &[self.tcx.lifetimes.re_erased.into()])
126+
} else {
127+
fn_sig.inputs()[index]
128+
};
129+
130+
let pat = self.pattern_from_hir(param.pat);
131+
Param { pat, ty, ty_span, self_kind, hir_id: param.hir_id }
132+
})
133+
}
88134
}
89135

90136
impl<'tcx> UserAnnotatedTyHelpers<'tcx> for Cx<'tcx> {

src/test/ui/thir-tree.stdout

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,6 @@ Thir {
5454
},
5555
],
5656
stmts: [],
57+
params: [],
5758
}
5859

0 commit comments

Comments
 (0)