about summary refs log tree commit diff
path: root/src/librustc/middle
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2017-07-05 08:42:13 -0700
committerAlex Crichton <alex@alexcrichton.com>2017-07-05 08:42:13 -0700
commitfd95db25b367d5d61ee9bc86b928c529747b3622 (patch)
treef93755558c3f91addb568e1f5aa4f2a4799589f5 /src/librustc/middle
parentd316874c87e25669895c306658e15aa3746d66ab (diff)
parent692b5722363be2de18a27b46db59950124a5101d (diff)
downloadrust-fd95db25b367d5d61ee9bc86b928c529747b3622.tar.gz
rust-fd95db25b367d5d61ee9bc86b928c529747b3622.zip
Merge remote-tracking branch 'origin/master' into proc_macro_api
Diffstat (limited to 'src/librustc/middle')
-rw-r--r--src/librustc/middle/effect.rs28
-rw-r--r--src/librustc/middle/expr_use_visitor.rs9
-rw-r--r--src/librustc/middle/intrinsicck.rs27
-rw-r--r--src/librustc/middle/mem_categorization.rs92
-rw-r--r--src/librustc/middle/resolve_lifetime.rs3
5 files changed, 69 insertions, 90 deletions
diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs
index 74e1225f394..eab5a8f9103 100644
--- a/src/librustc/middle/effect.rs
+++ b/src/librustc/middle/effect.rs
@@ -12,7 +12,7 @@
 //! `unsafe`.
 use self::RootUnsafeContext::*;
 
-use ty::{self, Ty, TyCtxt};
+use ty::{self, TyCtxt};
 use lint;
 
 use syntax::ast;
@@ -40,14 +40,6 @@ enum RootUnsafeContext {
     UnsafeBlock(ast::NodeId),
 }
 
-fn type_is_unsafe_function(ty: Ty) -> bool {
-    match ty.sty {
-        ty::TyFnDef(.., f) |
-        ty::TyFnPtr(f) => f.unsafety() == hir::Unsafety::Unsafe,
-        _ => false,
-    }
-}
-
 struct EffectCheckVisitor<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     tables: &'a ty::TypeckTables<'tcx>,
@@ -174,10 +166,11 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {
         match expr.node {
             hir::ExprMethodCall(..) => {
                 let def_id = self.tables.type_dependent_defs[&expr.id].def_id();
-                let base_type = self.tcx.type_of(def_id);
-                debug!("effect: method call case, base type is {:?}",
-                        base_type);
-                if type_is_unsafe_function(base_type) {
+                let sig = self.tcx.fn_sig(def_id);
+                debug!("effect: method call case, signature is {:?}",
+                        sig);
+
+                if sig.0.unsafety == hir::Unsafety::Unsafe {
                     self.require_unsafe(expr.span,
                                         "invocation of unsafe method")
                 }
@@ -186,8 +179,13 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {
                 let base_type = self.tables.expr_ty_adjusted(base);
                 debug!("effect: call case, base type is {:?}",
                         base_type);
-                if type_is_unsafe_function(base_type) {
-                    self.require_unsafe(expr.span, "call to unsafe function")
+                match base_type.sty {
+                    ty::TyFnDef(..) | ty::TyFnPtr(_) => {
+                        if base_type.fn_sig(self.tcx).unsafety() == hir::Unsafety::Unsafe {
+                            self.require_unsafe(expr.span, "call to unsafe function")
+                        }
+                    }
+                    _ => {}
                 }
             }
             hir::ExprUnary(hir::UnDeref, ref base) => {
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 58e77f40d98..259bd4f0999 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -816,7 +816,6 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
     fn walk_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &hir::Pat, match_mode: MatchMode) {
         debug!("walk_pat cmt_discr={:?} pat={:?}", cmt_discr, pat);
 
-        let tcx = self.tcx();
         let ExprUseVisitor { ref mc, ref mut delegate, param_env } = *self;
         return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |cmt_pat, pat| {
             if let PatKind::Binding(bmode, def_id, ..) = pat.node {
@@ -864,13 +863,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
             match def {
                 Def::Variant(variant_did) |
                 Def::VariantCtor(variant_did, ..) => {
-                    let enum_did = tcx.parent_def_id(variant_did).unwrap();
-                    let downcast_cmt = if tcx.adt_def(enum_did).is_univariant() {
-                        cmt_pat
-                    } else {
-                        let cmt_pat_ty = cmt_pat.ty;
-                        mc.cat_downcast(pat, cmt_pat, cmt_pat_ty, variant_did)
-                    };
+                    let downcast_cmt = mc.cat_downcast_if_needed(pat, cmt_pat, variant_did);
 
                     debug!("variant downcast_cmt={:?} pat={:?}", downcast_cmt, pat);
                     delegate.matched_pat(pat, downcast_cmt, match_mode);
diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs
index f180ae53b8a..fde207e4b2f 100644
--- a/src/librustc/middle/intrinsicck.rs
+++ b/src/librustc/middle/intrinsicck.rs
@@ -66,11 +66,8 @@ fn unpack_option_like<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
 impl<'a, 'tcx> ExprVisitor<'a, 'tcx> {
     fn def_id_is_transmute(&self, def_id: DefId) -> bool {
-        let intrinsic = match self.tcx.type_of(def_id).sty {
-            ty::TyFnDef(.., bfty) => bfty.abi() == RustIntrinsic,
-            _ => return false
-        };
-        intrinsic && self.tcx.item_name(def_id) == "transmute"
+        self.tcx.fn_sig(def_id).abi() == RustIntrinsic &&
+        self.tcx.item_name(def_id) == "transmute"
     }
 
     fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>) {
@@ -153,22 +150,14 @@ impl<'a, 'tcx> Visitor<'tcx> for ExprVisitor<'a, 'tcx> {
         } else {
             Def::Err
         };
-        match def {
-            Def::Fn(did) if self.def_id_is_transmute(did) => {
+        if let Def::Fn(did) = def {
+            if self.def_id_is_transmute(did) {
                 let typ = self.tables.node_id_to_type(expr.id);
-                let typ = self.tcx.lift_to_global(&typ).unwrap();
-                match typ.sty {
-                    ty::TyFnDef(.., sig) if sig.abi() == RustIntrinsic => {
-                        let from = sig.inputs().skip_binder()[0];
-                        let to = *sig.output().skip_binder();
-                        self.check_transmute(expr.span, from, to);
-                    }
-                    _ => {
-                        span_bug!(expr.span, "transmute wasn't a bare fn?!");
-                    }
-                }
+                let sig = typ.fn_sig(self.tcx);
+                let from = sig.inputs().skip_binder()[0];
+                let to = *sig.output().skip_binder();
+                self.check_transmute(expr.span, from, to);
             }
-            _ => {}
         }
 
         intravisit::walk_expr(self, expr);
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 259079cf160..5c741eccf83 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -1032,22 +1032,29 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
         ret
     }
 
-    pub fn cat_downcast<N:ast_node>(&self,
-                                    node: &N,
-                                    base_cmt: cmt<'tcx>,
-                                    downcast_ty: Ty<'tcx>,
-                                    variant_did: DefId)
-                                    -> cmt<'tcx> {
-        let ret = Rc::new(cmt_ {
-            id: node.id(),
-            span: node.span(),
-            mutbl: base_cmt.mutbl.inherit(),
-            cat: Categorization::Downcast(base_cmt, variant_did),
-            ty: downcast_ty,
-            note: NoteNone
-        });
-        debug!("cat_downcast ret={:?}", ret);
-        ret
+    pub fn cat_downcast_if_needed<N:ast_node>(&self,
+                                              node: &N,
+                                              base_cmt: cmt<'tcx>,
+                                              variant_did: DefId)
+                                              -> cmt<'tcx> {
+        // univariant enums do not need downcasts
+        let base_did = self.tcx.parent_def_id(variant_did).unwrap();
+        if !self.tcx.adt_def(base_did).is_univariant() {
+            let base_ty = base_cmt.ty;
+            let ret = Rc::new(cmt_ {
+                id: node.id(),
+                span: node.span(),
+                mutbl: base_cmt.mutbl.inherit(),
+                cat: Categorization::Downcast(base_cmt, variant_did),
+                ty: base_ty,
+                note: NoteNone
+            });
+            debug!("cat_downcast ret={:?}", ret);
+            ret
+        } else {
+            debug!("cat_downcast univariant={:?}", base_cmt);
+            base_cmt
+        }
     }
 
     pub fn cat_pattern<F>(&self, cmt: cmt<'tcx>, pat: &hir::Pat, mut op: F) -> McResult<()>
@@ -1109,45 +1116,23 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
 
         op(cmt.clone(), pat);
 
-        // Note: This goes up here (rather than within the PatKind::TupleStruct arm
-        // alone) because PatKind::Struct can also refer to variants.
-        let cmt = match pat.node {
-            PatKind::Path(hir::QPath::Resolved(_, ref path)) |
-            PatKind::TupleStruct(hir::QPath::Resolved(_, ref path), ..) |
-            PatKind::Struct(hir::QPath::Resolved(_, ref path), ..) => {
-                match path.def {
-                    Def::Err => {
-                        debug!("access to unresolvable pattern {:?}", pat);
-                        return Err(())
-                    }
-                    Def::Variant(variant_did) |
-                    Def::VariantCtor(variant_did, ..) => {
-                        // univariant enums do not need downcasts
-                        let enum_did = self.tcx.parent_def_id(variant_did).unwrap();
-                        if !self.tcx.adt_def(enum_did).is_univariant() {
-                            self.cat_downcast(pat, cmt.clone(), cmt.ty, variant_did)
-                        } else {
-                            cmt
-                        }
-                    }
-                    _ => cmt
-                }
-            }
-            _ => cmt
-        };
-
         match pat.node {
           PatKind::TupleStruct(ref qpath, ref subpats, ddpos) => {
             let def = self.tables.qpath_def(qpath, pat.id);
-            let expected_len = match def {
+            let (cmt, expected_len) = match def {
+                Def::Err => {
+                    debug!("access to unresolvable pattern {:?}", pat);
+                    return Err(())
+                }
                 Def::VariantCtor(def_id, CtorKind::Fn) => {
                     let enum_def = self.tcx.parent_def_id(def_id).unwrap();
-                    self.tcx.adt_def(enum_def).variant_with_id(def_id).fields.len()
+                    (self.cat_downcast_if_needed(pat, cmt, def_id),
+                     self.tcx.adt_def(enum_def).variant_with_id(def_id).fields.len())
                 }
                 Def::StructCtor(_, CtorKind::Fn) => {
                     match self.pat_ty(&pat)?.sty {
                         ty::TyAdt(adt_def, _) => {
-                            adt_def.struct_variant().fields.len()
+                            (cmt, adt_def.struct_variant().fields.len())
                         }
                         ref ty => {
                             span_bug!(pat.span, "tuple struct pattern unexpected type {:?}", ty);
@@ -1168,8 +1153,21 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
             }
           }
 
-          PatKind::Struct(_, ref field_pats, _) => {
+          PatKind::Struct(ref qpath, ref field_pats, _) => {
             // {f1: p1, ..., fN: pN}
+            let def = self.tables.qpath_def(qpath, pat.id);
+            let cmt = match def {
+                Def::Err => {
+                    debug!("access to unresolvable pattern {:?}", pat);
+                    return Err(())
+                },
+                Def::Variant(variant_did) |
+                Def::VariantCtor(variant_did, ..) => {
+                    self.cat_downcast_if_needed(pat, cmt, variant_did)
+                },
+                _ => cmt
+            };
+
             for fp in field_pats {
                 let field_ty = self.pat_ty(&fp.node.pat)?; // see (*2)
                 let cmt_field = self.cat_field(pat, cmt.clone(), fp.node.name, field_ty);
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index ce5d58f5800..b347a931851 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -28,6 +28,7 @@ use syntax::attr;
 use syntax::ptr::P;
 use syntax_pos::Span;
 use errors::DiagnosticBuilder;
+use util::common::ErrorReported;
 use util::nodemap::{NodeMap, NodeSet, FxHashSet, FxHashMap, DefIdMap};
 use rustc_back::slice;
 
@@ -255,7 +256,7 @@ const ROOT_SCOPE: ScopeRef<'static> = &Scope::Root;
 
 pub fn krate(sess: &Session,
              hir_map: &Map)
-             -> Result<NamedRegionMap, usize> {
+             -> Result<NamedRegionMap, ErrorReported> {
     let krate = hir_map.krate();
     let mut map = NamedRegionMap {
         defs: NodeMap(),