diff options
| author | Camille GILLOT <gillot.camille@gmail.com> | 2022-08-27 12:21:02 +0200 |
|---|---|---|
| committer | Camille GILLOT <gillot.camille@gmail.com> | 2022-09-13 19:18:23 +0200 |
| commit | 445841cda32cf9fb95528cfe8d126d0a0e0cb608 (patch) | |
| tree | dc88d651294afb045b86981bbfc6300f7f2a7c57 | |
| parent | f76594a0bc0be37d92d9182aa1e7eb1f9e25d54c (diff) | |
| download | rust-445841cda32cf9fb95528cfe8d126d0a0e0cb608.tar.gz rust-445841cda32cf9fb95528cfe8d126d0a0e0cb608.zip | |
Compute explicit MIR params on THIR.
| -rw-r--r-- | compiler/rustc_middle/src/thir.rs | 25 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/matches/mod.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/mod.rs | 65 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/cx/mod.rs | 48 | ||||
| -rw-r--r-- | src/test/ui/thir-tree.stdout | 1 |
5 files changed, 86 insertions, 55 deletions
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index c50f8b0eebe..0214610f687 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -78,6 +78,22 @@ thir_with_elements! { blocks: BlockId => Block => "b{}", exprs: ExprId => Expr<'tcx> => "e{}", stmts: StmtId => Stmt<'tcx> => "s{}", + params: ParamId => Param<'tcx> => "p{}", +} + +/// Description of a type-checked function parameter. +#[derive(Clone, Debug, HashStable)] +pub struct Param<'tcx> { + /// The pattern that appears in the parameter list. + pub pat: Box<Pat<'tcx>>, + /// The possibly inferred type. + pub ty: Ty<'tcx>, + /// Span of the explicitly provided type, or None if inferred for closures. + pub ty_span: Option<Span>, + /// Whether this param is `self`, and how it is bound. + pub self_kind: Option<hir::ImplicitSelfKind>, + /// HirId for lints. + pub hir_id: hir::HirId, } #[derive(Copy, Clone, Debug, HashStable)] @@ -548,6 +564,15 @@ impl<'tcx> Pat<'tcx> { pub fn wildcard_from_ty(ty: Ty<'tcx>) -> Self { Pat { ty, span: DUMMY_SP, kind: PatKind::Wild } } + + pub fn simple_ident(&self) -> Option<Symbol> { + match self.kind { + PatKind::Binding { name, mode: BindingMode::ByValue, subpattern: None, .. } => { + Some(name) + } + _ => None, + } + } } #[derive(Clone, Debug, HashStable)] diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 505273033a4..b1cb9b9f084 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -568,7 +568,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { _ => { let place_builder = unpack!(block = self.as_place_builder(block, initializer)); - self.place_into_pattern(block, irrefutable_pat, place_builder, true) + self.place_into_pattern(block, &irrefutable_pat, place_builder, true) } } } diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index b70a4a5d0f8..d44263b4e1b 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -1,7 +1,6 @@ pub(crate) use crate::build::expr::as_constant::lit_to_mir_constant; use crate::build::expr::as_place::PlaceBuilder; use crate::build::scope::DropKind; -use crate::thir::pattern::pat_from_hir; use rustc_apfloat::ieee::{Double, Single}; use rustc_apfloat::Float; use rustc_data_structures::fx::FxHashMap; @@ -9,7 +8,6 @@ use rustc_data_structures::sorted_map::SortedIndexMultiMap; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::lang_items::LangItem; use rustc_hir::{GeneratorKind, ImplicitSelfKind, Node}; use rustc_index::vec::{Idx, IndexVec}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; @@ -18,8 +16,7 @@ use rustc_middle::middle::region; use rustc_middle::mir::interpret::ConstValue; use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::*; -use rustc_middle::thir::{BindingMode, Expr, ExprId, LintLevel, LocalVarId, PatKind, Thir}; -use rustc_middle::ty::subst::Subst; +use rustc_middle::thir::{BindingMode, Expr, ExprId, LintLevel, LocalVarId, Param, PatKind, Thir}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable, TypeckResults}; use rustc_span::symbol::sym; use rustc_span::Span; @@ -449,10 +446,10 @@ macro_rules! unpack { /////////////////////////////////////////////////////////////////////////// /// the main entry point for building MIR for a function -struct ArgInfo<'tcx>( +struct ArgInfo<'thir, 'tcx>( Ty<'tcx>, Option<Span>, - Option<&'tcx hir::Param<'tcx>>, + Option<&'thir Param<'tcx>>, Option<ImplicitSelfKind>, ); @@ -510,38 +507,8 @@ fn construct_fn<'tcx>( _ => vec![], }; - let explicit_arguments = body.params.iter().enumerate().map(|(index, arg)| { - let owner_id = tcx.hir().body_owner(body_id); - let opt_ty_info; - let self_arg; - if let Some(ref fn_decl) = tcx.hir().fn_decl_by_hir_id(owner_id) { - opt_ty_info = fn_decl - .inputs - .get(index) - // Make sure that inferred closure args have no type span - .and_then(|ty| if arg.pat.span != ty.span { Some(ty.span) } else { None }); - self_arg = if index == 0 && fn_decl.implicit_self.has_implicit_self() { - Some(fn_decl.implicit_self) - } else { - None - }; - } else { - opt_ty_info = None; - self_arg = None; - } - - // C-variadic fns also have a `VaList` input that's not listed in `fn_sig` - // (as it's created inside the body itself, not passed in from outside). - let ty = if fn_sig.c_variadic && index == fn_sig.inputs().len() { - let va_list_did = tcx.require_lang_item(LangItem::VaList, Some(arg.span)); - - tcx.bound_type_of(va_list_did).subst(tcx, &[tcx.lifetimes.re_erased.into()]) - } else { - fn_sig.inputs()[index] - }; - - ArgInfo(ty, opt_ty_info, Some(&arg), self_arg) - }); + let explicit_arguments = + thir.params.iter().map(|arg| ArgInfo(arg.ty, arg.ty_span, Some(&arg), arg.self_kind)); let arguments = implicit_argument.into_iter().chain(explicit_arguments); @@ -852,7 +819,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, mut block: BasicBlock, fn_def_id: LocalDefId, - arguments: &[ArgInfo<'tcx>], + arguments: &[ArgInfo<'_, 'tcx>], argument_scope: region::Scope, expr: &Expr<'tcx>, ) -> BlockAnd<()> { @@ -863,9 +830,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let arg_local = self.local_decls.push(LocalDecl::with_source_info(ty, source_info)); // If this is a simple binding pattern, give debuginfo a nice name. - if let Some(arg) = arg_opt && let Some(ident) = arg.pat.simple_ident() { + if let Some(arg) = arg_opt && let Some(name) = arg.pat.simple_ident() { self.var_debug_info.push(VarDebugInfo { - name: ident.name, + name, source_info, value: VarDebugInfoContents::Place(arg_local.into()), }); @@ -955,15 +922,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let Some(arg) = arg_opt else { continue; }; - let pat = match tcx.hir().get(arg.pat.hir_id) { - Node::Pat(pat) => pat, - node => bug!("pattern became {:?}", node), - }; - let pattern = pat_from_hir(tcx, self.param_env, self.typeck_results, pat); let original_source_scope = self.source_scope; - let span = pattern.span; + let span = arg.pat.span; self.set_correct_source_scope_for_arg(arg.hir_id, original_source_scope, span); - match pattern.kind { + match arg.pat.kind { // Don't introduce extra copies for simple bindings PatKind::Binding { mutability, @@ -995,15 +957,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { scope = self.declare_bindings( scope, expr.span, - &pattern, + &arg.pat, matches::ArmHasGuard(false), Some((Some(&place), span)), ); let place_builder = PlaceBuilder::from(local); - unpack!( - block = - self.place_into_pattern(block, pattern.as_ref(), place_builder, false) - ); + unpack!(block = self.place_into_pattern(block, &arg.pat, place_builder, false)); } } self.source_scope = original_source_scope; diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index ae53df1f9b9..8526af75576 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -9,11 +9,12 @@ use rustc_data_structures::steal::Steal; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::lang_items::LangItem; use rustc_hir::HirId; use rustc_hir::Node; use rustc_middle::middle::region; use rustc_middle::thir::*; -use rustc_middle::ty::{self, RvalueScopes, TyCtxt}; +use rustc_middle::ty::{self, RvalueScopes, Subst, TyCtxt}; use rustc_span::Span; pub(crate) fn thir_body<'tcx>( @@ -27,6 +28,13 @@ pub(crate) fn thir_body<'tcx>( return Err(reported); } let expr = cx.mirror_expr(&body.value); + + let owner_id = hir.local_def_id_to_hir_id(owner_def.did); + if let Some(ref fn_decl) = hir.fn_decl_by_hir_id(owner_id) { + let explicit_params = cx.explicit_params(owner_id, fn_decl, body); + cx.thir.params = explicit_params.collect(); + } + Ok((tcx.alloc_steal_thir(cx.thir), expr)) } @@ -85,6 +93,44 @@ impl<'tcx> Cx<'tcx> { }; pat_from_hir(self.tcx, self.param_env, self.typeck_results(), p) } + + fn explicit_params<'a>( + &'a mut self, + owner_id: HirId, + fn_decl: &'tcx hir::FnDecl<'tcx>, + body: &'tcx hir::Body<'tcx>, + ) -> impl Iterator<Item = Param<'tcx>> + 'a { + let fn_sig = self.typeck_results.liberated_fn_sigs()[owner_id]; + + body.params.iter().enumerate().map(move |(index, param)| { + let ty_span = fn_decl + .inputs + .get(index) + // Make sure that inferred closure args have no type span + .and_then(|ty| if param.pat.span != ty.span { Some(ty.span) } else { None }); + + let self_kind = if index == 0 && fn_decl.implicit_self.has_implicit_self() { + Some(fn_decl.implicit_self) + } else { + None + }; + + // C-variadic fns also have a `VaList` input that's not listed in `fn_sig` + // (as it's created inside the body itself, not passed in from outside). + let ty = if fn_decl.c_variadic && index == fn_decl.inputs.len() { + let va_list_did = self.tcx.require_lang_item(LangItem::VaList, Some(param.span)); + + self.tcx + .bound_type_of(va_list_did) + .subst(self.tcx, &[self.tcx.lifetimes.re_erased.into()]) + } else { + fn_sig.inputs()[index] + }; + + let pat = self.pattern_from_hir(param.pat); + Param { pat, ty, ty_span, self_kind, hir_id: param.hir_id } + }) + } } impl<'tcx> UserAnnotatedTyHelpers<'tcx> for Cx<'tcx> { diff --git a/src/test/ui/thir-tree.stdout b/src/test/ui/thir-tree.stdout index 960b7f7f4dd..5fcdfca18d6 100644 --- a/src/test/ui/thir-tree.stdout +++ b/src/test/ui/thir-tree.stdout @@ -54,5 +54,6 @@ Thir { }, ], stmts: [], + params: [], } |
