diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2017-07-05 08:42:13 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2017-07-05 08:42:13 -0700 |
| commit | fd95db25b367d5d61ee9bc86b928c529747b3622 (patch) | |
| tree | f93755558c3f91addb568e1f5aa4f2a4799589f5 /src/librustc/middle | |
| parent | d316874c87e25669895c306658e15aa3746d66ab (diff) | |
| parent | 692b5722363be2de18a27b46db59950124a5101d (diff) | |
| download | rust-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.rs | 28 | ||||
| -rw-r--r-- | src/librustc/middle/expr_use_visitor.rs | 9 | ||||
| -rw-r--r-- | src/librustc/middle/intrinsicck.rs | 27 | ||||
| -rw-r--r-- | src/librustc/middle/mem_categorization.rs | 92 | ||||
| -rw-r--r-- | src/librustc/middle/resolve_lifetime.rs | 3 |
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(), |
