]> git.lizzy.rs Git - rust.git/commitdiff
Thread more argument info down from `Hir` into the `mir::LocalDecls`.
authorFelix S. Klock II <pnkfelix@pnkfx.org>
Thu, 7 Jun 2018 15:05:58 +0000 (17:05 +0200)
committerFelix S. Klock II <pnkfelix@pnkfx.org>
Tue, 19 Jun 2018 17:38:37 +0000 (19:38 +0200)
Namely, we thread down the `HirId` of the explicit type of the
argument.  In the case of the special `self` variable with an implicit
type, we also thread down a description of its structure (`self`/`mut
self`/`&self`/`&mut self`).

src/librustc_mir/build/mod.rs

index e04e04c9f56fda7a373baf71ad6193d59e9751cb..85671414618038781c9e4c2f81dcedf885e2112a 100644 (file)
@@ -70,11 +70,11 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t
                     // HACK(eddyb) Avoid having RustCall on closures,
                     // as it adds unnecessary (and wrong) auto-tupling.
                     abi = Abi::Rust;
-                    Some(ArgInfo(liberated_closure_env_ty(tcx, id, body_id), None))
+                    Some(ArgInfo(liberated_closure_env_ty(tcx, id, body_id), None, None, None))
                 }
                 ty::TyGenerator(..) => {
                     let gen_ty = tcx.body_tables(body_id).node_id_to_type(fn_hir_id);
-                    Some(ArgInfo(gen_ty, None))
+                    Some(ArgInfo(gen_ty, None, None, None))
                 }
                 _ => None,
             };
@@ -91,7 +91,23 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t
                     .iter()
                     .enumerate()
                     .map(|(index, arg)| {
-                        ArgInfo(fn_sig.inputs()[index], Some(&*arg.pat))
+                        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(owner_id) {
+                            let ty_hir_id = fn_decl.inputs[index].hir_id;
+                            let ty_span = tcx.hir.span(tcx.hir.hir_to_node_id(ty_hir_id));
+                            opt_ty_info = Some(ty_span);
+                            self_arg = if index == 0 && fn_decl.has_implicit_self {
+                                Some(ImplicitSelfBinding)
+                            } else {
+                                None
+                            };
+                        } else {
+                            opt_ty_info = None;
+                            self_arg = None;
+                        }
+                        ArgInfo(fn_sig.inputs()[index], opt_ty_info, Some(&*arg.pat), self_arg)
                     });
 
             let arguments = implicit_argument.into_iter().chain(explicit_arguments);
@@ -433,7 +449,12 @@ fn should_abort_on_panic<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
 ///////////////////////////////////////////////////////////////////////////
 /// the main entry point for building MIR for a function
 
-struct ArgInfo<'gcx>(Ty<'gcx>, Option<&'gcx hir::Pat>);
+struct ImplicitSelfBinding;
+
+struct ArgInfo<'gcx>(Ty<'gcx>,
+                     Option<Span>,
+                     Option<&'gcx hir::Pat>,
+                     Option<ImplicitSelfBinding>);
 
 fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
                                    fn_id: ast::NodeId,
@@ -650,7 +671,7 @@ fn args_and_body(&mut self,
                      -> BlockAnd<()>
     {
         // Allocate locals for the function arguments
-        for &ArgInfo(ty, pattern) in arguments.iter() {
+        for &ArgInfo(ty, _, pattern, _) in arguments.iter() {
             // If this is a simple binding pattern, give the local a nice name for debuginfo.
             let mut name = None;
             if let Some(pat) = pattern {
@@ -676,10 +697,11 @@ fn args_and_body(&mut self,
 
         let mut scope = None;
         // Bind the argument patterns
-        for (index, &ArgInfo(ty, pattern)) in arguments.iter().enumerate() {
+        for (index, arg_info) in arguments.iter().enumerate() {
             // Function arguments always get the first Local indices after the return place
             let local = Local::new(index + 1);
             let place = Place::Local(local);
+            let &ArgInfo(ty, opt_ty_info, pattern, ref self_binding) = arg_info;
 
             if let Some(pattern) = pattern {
                 let pattern = self.hir.pattern_from_hir(pattern);
@@ -688,6 +710,14 @@ fn args_and_body(&mut self,
                     // Don't introduce extra copies for simple bindings
                     PatternKind::Binding { mutability, var, mode: BindingMode::ByValue, .. } => {
                         self.local_decls[local].mutability = mutability;
+                        self.local_decls[local].is_user_variable =
+                            if let Some(ImplicitSelfBinding) = self_binding {
+                                Some(ClearCrossCrate::Set(BindingForm::ImplicitSelf))
+                            } else {
+                                let binding_mode = ty::BindingMode::BindByValue(mutability.into());
+                                Some(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
+                                    binding_mode, opt_ty_info })))
+                            };
                         self.var_indices.insert(var, LocalsForNode::One(local));
                     }
                     _ => {