]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_typeck/mem_categorization.rs
Rollup merge of #68504 - tmiasko:check-pass, r=alexcrichton
[rust.git] / src / librustc_typeck / mem_categorization.rs
index 84e5d234da9d7d01b62b78c8fa20e29d13418f75..d3d0aa2e5807fc8b99d9896575488135c3d33e76 100644 (file)
 //! result of `*x'`, effectively, where `x'` is a `Categorization::Upvar` reference
 //! tied to `x`. The type of `x'` will be a borrowed pointer.
 
-use rustc::hir;
-use rustc::hir::PatKind;
-use rustc::hir::def_id::DefId;
-use rustc::hir::def::{Res, DefKind};
 use rustc::infer::InferCtxt;
 use rustc::ty::adjustment;
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::fold::TypeFoldable;
-
-use syntax_pos::Span;
-
+use rustc::ty::{self, Ty, TyCtxt};
 use rustc_data_structures::fx::FxIndexMap;
+use rustc_hir as hir;
+use rustc_hir::def::{DefKind, Res};
+use rustc_hir::def_id::DefId;
+use rustc_hir::PatKind;
+use rustc_span::Span;
 
 #[derive(Clone, Debug)]
 pub enum PlaceBase {
@@ -105,11 +103,9 @@ impl<'tcx> Place<'tcx> {
     /// The types are in the reverse order that they are applied. So if
     /// `x: &*const u32` and the `Place` is `**x`, then the types returned are
     ///`*const u32` then `&*const u32`.
-    crate fn deref_tys(&self) -> impl Iterator<Item=Ty<'tcx>> + '_ {
-        self.projections.iter().rev().filter_map(|proj| if let Projection::Deref(deref_ty) = *proj {
-            Some(deref_ty)
-        } else {
-            None
+    crate fn deref_tys(&self) -> impl Iterator<Item = Ty<'tcx>> + '_ {
+        self.projections.iter().rev().filter_map(|proj| {
+            if let Projection::Deref(deref_ty) = *proj { Some(deref_ty) } else { None }
         })
     }
 }
@@ -119,14 +115,22 @@ impl<'tcx> Place<'tcx> {
     fn span(&self) -> Span;
 }
 
-impl HirNode for hir::Expr {
-    fn hir_id(&self) -> hir::HirId { self.hir_id }
-    fn span(&self) -> Span { self.span }
+impl HirNode for hir::Expr<'_> {
+    fn hir_id(&self) -> hir::HirId {
+        self.hir_id
+    }
+    fn span(&self) -> Span {
+        self.span
+    }
 }
 
-impl HirNode for hir::Pat {
-    fn hir_id(&self) -> hir::HirId { self.hir_id }
-    fn span(&self) -> Span { self.span }
+impl HirNode for hir::Pat<'_> {
+    fn hir_id(&self) -> hir::HirId {
+        self.hir_id
+    }
+    fn span(&self) -> Span {
+        self.span
+    }
 }
 
 #[derive(Clone)]
@@ -161,16 +165,13 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         self.infcx.tcx
     }
 
-    crate fn type_is_copy_modulo_regions(
-        &self,
-        ty: Ty<'tcx>,
-        span: Span,
-    ) -> bool {
+    crate fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>, span: Span) -> bool {
         self.infcx.type_is_copy_modulo_regions(self.param_env, ty, span)
     }
 
     fn resolve_vars_if_possible<T>(&self, value: &T) -> T
-        where T: TypeFoldable<'tcx>
+    where
+        T: TypeFoldable<'tcx>,
     {
         self.infcx.resolve_vars_if_possible(value)
     }
@@ -179,10 +180,11 @@ fn is_tainted_by_errors(&self) -> bool {
         self.infcx.is_tainted_by_errors()
     }
 
-    fn resolve_type_vars_or_error(&self,
-                                  id: hir::HirId,
-                                  ty: Option<Ty<'tcx>>)
-                                  -> McResult<Ty<'tcx>> {
+    fn resolve_type_vars_or_error(
+        &self,
+        id: hir::HirId,
+        ty: Option<Ty<'tcx>>,
+    ) -> McResult<Ty<'tcx>> {
         match ty {
             Some(ty) => {
                 let ty = self.resolve_vars_if_possible(&ty);
@@ -196,8 +198,11 @@ fn resolve_type_vars_or_error(&self,
             // FIXME
             None if self.is_tainted_by_errors() => Err(()),
             None => {
-                bug!("no type for node {}: {} in mem_categorization",
-                     id, self.tcx().hir().node_to_string(id));
+                bug!(
+                    "no type for node {}: {} in mem_categorization",
+                    id,
+                    self.tcx().hir().node_to_string(id)
+                );
             }
         }
     }
@@ -206,11 +211,11 @@ fn resolve_type_vars_or_error(&self,
         self.resolve_type_vars_or_error(hir_id, self.tables.node_type_opt(hir_id))
     }
 
-    fn expr_ty(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
+    fn expr_ty(&self, expr: &hir::Expr<'_>) -> McResult<Ty<'tcx>> {
         self.resolve_type_vars_or_error(expr.hir_id, self.tables.expr_ty_opt(expr))
     }
 
-    crate fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
+    crate fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> McResult<Ty<'tcx>> {
         self.resolve_type_vars_or_error(expr.hir_id, self.tables.expr_ty_adjusted_opt(expr))
     }
 
@@ -224,7 +229,7 @@ fn expr_ty(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
     ///   implicit deref patterns attached (e.g., it is really
     ///   `&Some(x)`). In that case, we return the "outermost" type
     ///   (e.g., `&Option<T>).
-    crate fn pat_ty_adjusted(&self, pat: &hir::Pat) -> McResult<Ty<'tcx>> {
+    crate fn pat_ty_adjusted(&self, pat: &hir::Pat<'_>) -> McResult<Ty<'tcx>> {
         // Check for implicit `&` types wrapping the pattern; note
         // that these are never attached to binding patterns, so
         // actually this is somewhat "disjoint" from the code below
@@ -239,9 +244,8 @@ fn expr_ty(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
         self.pat_ty_unadjusted(pat)
     }
 
-
     /// Like `pat_ty`, but ignores implicit `&` patterns.
-    fn pat_ty_unadjusted(&self, pat: &hir::Pat) -> McResult<Ty<'tcx>> {
+    fn pat_ty_unadjusted(&self, pat: &hir::Pat<'_>) -> McResult<Ty<'tcx>> {
         let base_ty = self.node_ty(pat.hir_id)?;
         debug!("pat_ty(pat={:?}) base_ty={:?}", pat, base_ty);
 
@@ -249,10 +253,8 @@ fn pat_ty_unadjusted(&self, pat: &hir::Pat) -> McResult<Ty<'tcx>> {
         // and if so, figures out what the type *being borrowed* is.
         let ret_ty = match pat.kind {
             PatKind::Binding(..) => {
-                let bm = *self.tables
-                              .pat_binding_modes()
-                              .get(pat.hir_id)
-                              .expect("missing binding mode");
+                let bm =
+                    *self.tables.pat_binding_modes().get(pat.hir_id).expect("missing binding mode");
 
                 if let ty::BindByReference(_) = bm {
                     // a bind-by-ref means that the base_ty will be the type of the ident itself,
@@ -276,12 +278,12 @@ fn pat_ty_unadjusted(&self, pat: &hir::Pat) -> McResult<Ty<'tcx>> {
         Ok(ret_ty)
     }
 
-    crate fn cat_expr(&self, expr: &hir::Expr) -> McResult<Place<'tcx>> {
+    crate fn cat_expr(&self, expr: &hir::Expr<'_>) -> McResult<Place<'tcx>> {
         // This recursion helper avoids going through *too many*
         // adjustments, since *only* non-overloaded deref recurses.
         fn helper<'a, 'tcx>(
             mc: &MemCategorizationContext<'a, 'tcx>,
-            expr: &hir::Expr,
+            expr: &hir::Expr<'_>,
             adjustments: &[adjustment::Adjustment<'tcx>],
         ) -> McResult<Place<'tcx>> {
             match adjustments.split_last() {
@@ -295,18 +297,23 @@ fn helper<'a, 'tcx>(
         helper(self, expr, self.tables.expr_adjustments(expr))
     }
 
-    crate fn cat_expr_adjusted(&self, expr: &hir::Expr,
-                             previous: Place<'tcx>,
-                             adjustment: &adjustment::Adjustment<'tcx>)
-                             -> McResult<Place<'tcx>> {
+    crate fn cat_expr_adjusted(
+        &self,
+        expr: &hir::Expr<'_>,
+        previous: Place<'tcx>,
+        adjustment: &adjustment::Adjustment<'tcx>,
+    ) -> McResult<Place<'tcx>> {
         self.cat_expr_adjusted_with(expr, || Ok(previous), adjustment)
     }
 
-    fn cat_expr_adjusted_with<F>(&self, expr: &hir::Expr,
-                                 previous: F,
-                                 adjustment: &adjustment::Adjustment<'tcx>)
-                                 -> McResult<Place<'tcx>>
-        where F: FnOnce() -> McResult<Place<'tcx>>
+    fn cat_expr_adjusted_with<F>(
+        &self,
+        expr: &hir::Expr<'_>,
+        previous: F,
+        adjustment: &adjustment::Adjustment<'tcx>,
+    ) -> McResult<Place<'tcx>>
+    where
+        F: FnOnce() -> McResult<Place<'tcx>>,
     {
         debug!("cat_expr_adjusted_with({:?}): {:?}", adjustment, expr);
         let target = self.resolve_vars_if_possible(&adjustment.target);
@@ -314,10 +321,9 @@ fn cat_expr_adjusted_with<F>(&self, expr: &hir::Expr,
             adjustment::Adjust::Deref(overloaded) => {
                 // Equivalent to *expr or something similar.
                 let base = if let Some(deref) = overloaded {
-                    let ref_ty = self.tcx().mk_ref(deref.region, ty::TypeAndMut {
-                        ty: target,
-                        mutbl: deref.mutbl,
-                    });
+                    let ref_ty = self
+                        .tcx()
+                        .mk_ref(deref.region, ty::TypeAndMut { ty: target, mutbl: deref.mutbl });
                     self.cat_rvalue(expr.hir_id, expr.span, ref_ty)
                 } else {
                     previous()?
@@ -325,21 +331,21 @@ fn cat_expr_adjusted_with<F>(&self, expr: &hir::Expr,
                 self.cat_deref(expr, base)
             }
 
-            adjustment::Adjust::NeverToAny |
-            adjustment::Adjust::Pointer(_) |
-            adjustment::Adjust::Borrow(_) => {
+            adjustment::Adjust::NeverToAny
+            | adjustment::Adjust::Pointer(_)
+            adjustment::Adjust::Borrow(_) => {
                 // Result is an rvalue.
                 Ok(self.cat_rvalue(expr.hir_id, expr.span, target))
             }
         }
     }
 
-    crate fn cat_expr_unadjusted(&self, expr: &hir::Expr) -> McResult<Place<'tcx>> {
+    crate fn cat_expr_unadjusted(&self, expr: &hir::Expr<'_>) -> McResult<Place<'tcx>> {
         debug!("cat_expr: id={} expr={:?}", expr.hir_id, expr);
 
         let expr_ty = self.expr_ty(expr)?;
         match expr.kind {
-            hir::ExprKind::Unary(hir::UnDeref, ref e_base) => {
+            hir::ExprKind::Unary(hir::UnOp::UnDeref, ref e_base) => {
                 if self.tables.is_method_call(expr) {
                     self.cat_overloaded_place(expr, e_base)
                 } else {
@@ -350,10 +356,7 @@ fn cat_expr_adjusted_with<F>(&self, expr: &hir::Expr,
 
             hir::ExprKind::Field(ref base, _) => {
                 let base = self.cat_expr(&base)?;
-                debug!("cat_expr(cat_field): id={} expr={:?} base={:?}",
-                       expr.hir_id,
-                       expr,
-                       base);
+                debug!("cat_expr(cat_field): id={} expr={:?} base={:?}", expr.hir_id, expr, base);
                 Ok(self.cat_projection(expr, base, expr_ty))
             }
 
@@ -376,34 +379,44 @@ fn cat_expr_adjusted_with<F>(&self, expr: &hir::Expr,
                 self.cat_res(expr.hir_id, expr.span, expr_ty, res)
             }
 
-            hir::ExprKind::Type(ref e, _) => {
-                self.cat_expr(&e)
-            }
-
-            hir::ExprKind::AddrOf(..) | hir::ExprKind::Call(..) |
-            hir::ExprKind::Assign(..) | hir::ExprKind::AssignOp(..) |
-            hir::ExprKind::Closure(..) | hir::ExprKind::Ret(..) |
-            hir::ExprKind::Unary(..) | hir::ExprKind::Yield(..) |
-            hir::ExprKind::MethodCall(..) | hir::ExprKind::Cast(..) | hir::ExprKind::DropTemps(..) |
-            hir::ExprKind::Array(..) | hir::ExprKind::Tup(..) |
-            hir::ExprKind::Binary(..) |
-            hir::ExprKind::Block(..) | hir::ExprKind::Loop(..) | hir::ExprKind::Match(..) |
-            hir::ExprKind::Lit(..) | hir::ExprKind::Break(..) |
-            hir::ExprKind::Continue(..) | hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) |
-            hir::ExprKind::InlineAsm(..) | hir::ExprKind::Box(..) | hir::ExprKind::Err => {
-                Ok(self.cat_rvalue(expr.hir_id, expr.span, expr_ty))
-            }
+            hir::ExprKind::Type(ref e, _) => self.cat_expr(&e),
+
+            hir::ExprKind::AddrOf(..)
+            | hir::ExprKind::Call(..)
+            | hir::ExprKind::Assign(..)
+            | hir::ExprKind::AssignOp(..)
+            | hir::ExprKind::Closure(..)
+            | hir::ExprKind::Ret(..)
+            | hir::ExprKind::Unary(..)
+            | hir::ExprKind::Yield(..)
+            | hir::ExprKind::MethodCall(..)
+            | hir::ExprKind::Cast(..)
+            | hir::ExprKind::DropTemps(..)
+            | hir::ExprKind::Array(..)
+            | hir::ExprKind::Tup(..)
+            | hir::ExprKind::Binary(..)
+            | hir::ExprKind::Block(..)
+            | hir::ExprKind::Loop(..)
+            | hir::ExprKind::Match(..)
+            | hir::ExprKind::Lit(..)
+            | hir::ExprKind::Break(..)
+            | hir::ExprKind::Continue(..)
+            | hir::ExprKind::Struct(..)
+            | hir::ExprKind::Repeat(..)
+            | hir::ExprKind::InlineAsm(..)
+            | hir::ExprKind::Box(..)
+            | hir::ExprKind::Err => Ok(self.cat_rvalue(expr.hir_id, expr.span, expr_ty)),
         }
     }
 
-    crate fn cat_res(&self,
-                   hir_id: hir::HirId,
-                   span: Span,
-                   expr_ty: Ty<'tcx>,
-                   res: Res)
-                   -> McResult<Place<'tcx>> {
-        debug!("cat_res: id={:?} expr={:?} def={:?}",
-               hir_id, expr_ty, res);
+    crate fn cat_res(
+        &self,
+        hir_id: hir::HirId,
+        span: Span,
+        expr_ty: Ty<'tcx>,
+        res: Res,
+    ) -> McResult<Place<'tcx>> {
+        debug!("cat_res: id={:?} expr={:?} def={:?}", hir_id, expr_ty, res);
 
         match res {
             Res::Def(DefKind::Ctor(..), _)
@@ -412,19 +425,15 @@ fn cat_expr_adjusted_with<F>(&self, expr: &hir::Expr,
             | Res::Def(DefKind::AssocConst, _)
             | Res::Def(DefKind::Fn, _)
             | Res::Def(DefKind::Method, _)
-            | Res::SelfCtor(..) => {
-                Ok(self.cat_rvalue(hir_id, span, expr_ty))
-            }
+            | Res::SelfCtor(..) => Ok(self.cat_rvalue(hir_id, span, expr_ty)),
 
-            Res::Def(DefKind::Static, _) => {
-                Ok(Place {
-                    hir_id,
-                    span,
-                    ty: expr_ty,
-                    base: PlaceBase::StaticItem,
-                    projections: Vec::new(),
-                })
-            }
+            Res::Def(DefKind::Static, _) => Ok(Place {
+                hir_id,
+                span,
+                ty: expr_ty,
+                base: PlaceBase::StaticItem,
+                projections: Vec::new(),
+            }),
 
             Res::Local(var_id) => {
                 if self.upvars.map_or(false, |upvars| upvars.contains_key(&var_id)) {
@@ -440,7 +449,7 @@ fn cat_expr_adjusted_with<F>(&self, expr: &hir::Expr,
                 }
             }
 
-            def => span_bug!(span, "unexpected definition in memory categorization: {:?}", def)
+            def => span_bug!(span, "unexpected definition in memory categorization: {:?}", def),
         }
     }
 
@@ -477,13 +486,8 @@ fn cat_upvar(
 
     crate fn cat_rvalue(&self, hir_id: hir::HirId, span: Span, expr_ty: Ty<'tcx>) -> Place<'tcx> {
         debug!("cat_rvalue hir_id={:?}, expr_ty={:?}, span={:?}", hir_id, expr_ty, span);
-        let ret = Place {
-            hir_id,
-            span,
-            base: PlaceBase::Rvalue,
-            projections: Vec::new(),
-            ty: expr_ty,
-        };
+        let ret =
+            Place { hir_id, span, base: PlaceBase::Rvalue, projections: Vec::new(), ty: expr_ty };
         debug!("cat_rvalue ret={:?}", ret);
         ret
     }
@@ -509,8 +513,8 @@ fn cat_upvar(
 
     fn cat_overloaded_place(
         &self,
-        expr: &hir::Expr,
-        base: &hir::Expr,
+        expr: &hir::Expr<'_>,
+        base: &hir::Expr<'_>,
     ) -> McResult<Place<'tcx>> {
         debug!("cat_overloaded_place(expr={:?}, base={:?})", expr, base);
 
@@ -522,22 +526,15 @@ fn cat_overloaded_place(
 
         let (region, mutbl) = match base_ty.kind {
             ty::Ref(region, _, mutbl) => (region, mutbl),
-            _ => span_bug!(expr.span, "cat_overloaded_place: base is not a reference")
+            _ => span_bug!(expr.span, "cat_overloaded_place: base is not a reference"),
         };
-        let ref_ty = self.tcx().mk_ref(region, ty::TypeAndMut {
-            ty: place_ty,
-            mutbl,
-        });
+        let ref_ty = self.tcx().mk_ref(region, ty::TypeAndMut { ty: place_ty, mutbl });
 
         let base = self.cat_rvalue(expr.hir_id, expr.span, ref_ty);
         self.cat_deref(expr, base)
     }
 
-    fn cat_deref(
-        &self,
-        node: &impl HirNode,
-        base_place: Place<'tcx>,
-    ) -> McResult<Place<'tcx>> {
+    fn cat_deref(&self, node: &impl HirNode, base_place: Place<'tcx>) -> McResult<Place<'tcx>> {
         debug!("cat_deref: base_place={:?}", base_place);
 
         let base_ty = base_place.ty;
@@ -562,15 +559,27 @@ fn cat_deref(
         Ok(ret)
     }
 
-    crate fn cat_pattern<F>(&self, place: Place<'tcx>, pat: &hir::Pat, mut op: F) -> McResult<()>
-        where F: FnMut(&Place<'tcx>, &hir::Pat),
+    crate fn cat_pattern<F>(
+        &self,
+        place: Place<'tcx>,
+        pat: &hir::Pat<'_>,
+        mut op: F,
+    ) -> McResult<()>
+    where
+        F: FnMut(&Place<'tcx>, &hir::Pat<'_>),
     {
         self.cat_pattern_(place, pat, &mut op)
     }
 
     // FIXME(#19596) This is a workaround, but there should be a better way to do this
-    fn cat_pattern_<F>(&self, mut place: Place<'tcx>, pat: &hir::Pat, op: &mut F) -> McResult<()>
-        where F: FnMut(&Place<'tcx>, &hir::Pat)
+    fn cat_pattern_<F>(
+        &self,
+        mut place: Place<'tcx>,
+        pat: &hir::Pat<'_>,
+        op: &mut F,
+    ) -> McResult<()>
+    where
+        F: FnMut(&Place<'tcx>, &hir::Pat<'_>),
     {
         // Here, `place` is the `Place` being matched and pat is the pattern it
         // is being matched against.
@@ -613,12 +622,7 @@ fn cat_pattern_<F>(&self, mut place: Place<'tcx>, pat: &hir::Pat, op: &mut F) ->
         // Then we see that to get the same result, we must start with
         // `deref { deref { place_foo }}` instead of `place_foo` since the pattern is now `Some(x,)`
         // and not `&&Some(x,)`, even though its assigned type is that of `&&Some(x,)`.
-        for _ in 0..self.tables
-                        .pat_adjustments()
-                        .get(pat.hir_id)
-                        .map(|v| v.len())
-                        .unwrap_or(0)
-        {
+        for _ in 0..self.tables.pat_adjustments().get(pat.hir_id).map(|v| v.len()).unwrap_or(0) {
             debug!("cat_pattern: applying adjustment to place={:?}", place);
             place = self.cat_deref(pat, place)?;
         }
@@ -637,8 +641,7 @@ fn cat_pattern_<F>(&self, mut place: Place<'tcx>, pat: &hir::Pat, op: &mut F) ->
         op(&place, pat);
 
         match pat.kind {
-            PatKind::TupleStruct(_, ref subpats, _)
-            | PatKind::Tuple(ref subpats, _) => {
+            PatKind::TupleStruct(_, ref subpats, _) | PatKind::Tuple(ref subpats, _) => {
                 // S(p1, ..., pN) or (p1, ..., pN)
                 for subpat in subpats.iter() {
                     let subpat_ty = self.pat_ty_adjusted(&subpat)?;
@@ -647,7 +650,7 @@ fn cat_pattern_<F>(&self, mut place: Place<'tcx>, pat: &hir::Pat, op: &mut F) ->
                 }
             }
 
-            PatKind::Struct(_, ref field_pats, _) => {
+            PatKind::Struct(_, field_pats, _) => {
                 // S { f1: p1, ..., fN: pN }
                 for fp in field_pats {
                     let field_ty = self.pat_ty_adjusted(&fp.pat)?;
@@ -656,7 +659,7 @@ fn cat_pattern_<F>(&self, mut place: Place<'tcx>, pat: &hir::Pat, op: &mut F) ->
                 }
             }
 
-            PatKind::Or(ref pats) => {
+            PatKind::Or(pats) => {
                 for pat in pats {
                     self.cat_pattern_(place.clone(), &pat, op)?;
                 }
@@ -674,7 +677,7 @@ fn cat_pattern_<F>(&self, mut place: Place<'tcx>, pat: &hir::Pat, op: &mut F) ->
                 self.cat_pattern_(subplace, &subpat, op)?;
             }
 
-            PatKind::Slice(ref before, ref slice, ref after) => {
+            PatKind::Slice(before, ref slice, after) => {
                 let element_ty = match place.ty.builtin_index() {
                     Some(ty) => ty,
                     None => {
@@ -696,8 +699,11 @@ fn cat_pattern_<F>(&self, mut place: Place<'tcx>, pat: &hir::Pat, op: &mut F) ->
                 }
             }
 
-            PatKind::Path(_) | PatKind::Binding(.., None) |
-            PatKind::Lit(..) | PatKind::Range(..) | PatKind::Wild => {
+            PatKind::Path(_)
+            | PatKind::Binding(.., None)
+            | PatKind::Lit(..)
+            | PatKind::Range(..)
+            | PatKind::Wild => {
                 // always ok
             }
         }