]> git.lizzy.rs Git - rust.git/commitdiff
typeck/expr.rs: extract out check_expr_path.
authorMazdak Farrokhzad <twingoow@gmail.com>
Fri, 14 Jun 2019 23:56:10 +0000 (01:56 +0200)
committerMazdak Farrokhzad <twingoow@gmail.com>
Fri, 14 Jun 2019 23:56:10 +0000 (01:56 +0200)
src/librustc_typeck/check/expr.rs

index 4e6282161417b83b8e08a49237d4ae9469a0fde8..cb626da0294bbf052f940f7d6ad7c188a33cd520 100644 (file)
@@ -47,7 +47,6 @@ pub(super) fn check_expr_kind(
         );
 
         let tcx = self.tcx;
-        let id = expr.hir_id;
         match expr.node {
             ExprKind::Box(ref subexpr) => {
                 self.check_expr_box(subexpr, expected)
@@ -68,63 +67,7 @@ pub(super) fn check_expr_kind(
                 self.check_expr_addr_of(mutbl, oprnd, expected, expr)
             }
             ExprKind::Path(ref qpath) => {
-                let (res, opt_ty, segs) = self.resolve_ty_and_res_ufcs(qpath, expr.hir_id,
-                    expr.span);
-                let ty = match res {
-                    Res::Err => {
-                        self.set_tainted_by_errors();
-                        tcx.types.err
-                    }
-                    Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => {
-                        report_unexpected_variant_res(tcx, res, expr.span, qpath);
-                        tcx.types.err
-                    }
-                    _ => self.instantiate_value_path(segs, opt_ty, res, expr.span, id).0,
-                };
-
-                if let ty::FnDef(..) = ty.sty {
-                    let fn_sig = ty.fn_sig(tcx);
-                    if !tcx.features().unsized_locals {
-                        // We want to remove some Sized bounds from std functions,
-                        // but don't want to expose the removal to stable Rust.
-                        // i.e., we don't want to allow
-                        //
-                        // ```rust
-                        // drop as fn(str);
-                        // ```
-                        //
-                        // to work in stable even if the Sized bound on `drop` is relaxed.
-                        for i in 0..fn_sig.inputs().skip_binder().len() {
-                            // We just want to check sizedness, so instead of introducing
-                            // placeholder lifetimes with probing, we just replace higher lifetimes
-                            // with fresh vars.
-                            let input = self.replace_bound_vars_with_fresh_vars(
-                                expr.span,
-                                infer::LateBoundRegionConversionTime::FnCall,
-                                &fn_sig.input(i)).0;
-                            self.require_type_is_sized_deferred(input, expr.span,
-                                                                traits::SizedArgumentType);
-                        }
-                    }
-                    // Here we want to prevent struct constructors from returning unsized types.
-                    // There were two cases this happened: fn pointer coercion in stable
-                    // and usual function call in presense of unsized_locals.
-                    // Also, as we just want to check sizedness, instead of introducing
-                    // placeholder lifetimes with probing, we just replace higher lifetimes
-                    // with fresh vars.
-                    let output = self.replace_bound_vars_with_fresh_vars(
-                        expr.span,
-                        infer::LateBoundRegionConversionTime::FnCall,
-                        &fn_sig.output()).0;
-                    self.require_type_is_sized_deferred(output, expr.span, traits::SizedReturnType);
-                }
-
-                // We always require that the type provided as the value for
-                // a type parameter outlives the moment of instantiation.
-                let substs = self.tables.borrow().node_substs(expr.hir_id);
-                self.add_wf_bounds(substs, expr);
-
-                ty
+                self.check_expr_path(qpath, expr)
             }
             ExprKind::InlineAsm(_, ref outputs, ref inputs) => {
                 for expr in outputs.iter().chain(inputs.iter()) {
@@ -722,4 +665,64 @@ fn check_expr_addr_of(
             self.tcx.mk_ref(region, tm)
         }
     }
+
+    fn check_expr_path(&self, qpath: &hir::QPath, expr: &'tcx hir::Expr) -> Ty<'tcx> {
+        let tcx = self.tcx;
+        let (res, opt_ty, segs) = self.resolve_ty_and_res_ufcs(qpath, expr.hir_id, expr.span);
+        let ty = match res {
+            Res::Err => {
+                self.set_tainted_by_errors();
+                tcx.types.err
+            }
+            Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => {
+                report_unexpected_variant_res(tcx, res, expr.span, qpath);
+                tcx.types.err
+            }
+            _ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0,
+        };
+
+        if let ty::FnDef(..) = ty.sty {
+            let fn_sig = ty.fn_sig(tcx);
+            if !tcx.features().unsized_locals {
+                // We want to remove some Sized bounds from std functions,
+                // but don't want to expose the removal to stable Rust.
+                // i.e., we don't want to allow
+                //
+                // ```rust
+                // drop as fn(str);
+                // ```
+                //
+                // to work in stable even if the Sized bound on `drop` is relaxed.
+                for i in 0..fn_sig.inputs().skip_binder().len() {
+                    // We just want to check sizedness, so instead of introducing
+                    // placeholder lifetimes with probing, we just replace higher lifetimes
+                    // with fresh vars.
+                    let input = self.replace_bound_vars_with_fresh_vars(
+                        expr.span,
+                        infer::LateBoundRegionConversionTime::FnCall,
+                        &fn_sig.input(i)).0;
+                    self.require_type_is_sized_deferred(input, expr.span,
+                                                        traits::SizedArgumentType);
+                }
+            }
+            // Here we want to prevent struct constructors from returning unsized types.
+            // There were two cases this happened: fn pointer coercion in stable
+            // and usual function call in presense of unsized_locals.
+            // Also, as we just want to check sizedness, instead of introducing
+            // placeholder lifetimes with probing, we just replace higher lifetimes
+            // with fresh vars.
+            let output = self.replace_bound_vars_with_fresh_vars(
+                expr.span,
+                infer::LateBoundRegionConversionTime::FnCall,
+                &fn_sig.output()).0;
+            self.require_type_is_sized_deferred(output, expr.span, traits::SizedReturnType);
+        }
+
+        // We always require that the type provided as the value for
+        // a type parameter outlives the moment of instantiation.
+        let substs = self.tables.borrow().node_substs(expr.hir_id);
+        self.add_wf_bounds(substs, expr);
+
+        ty
+    }
 }