]> git.proxmox.com Git - rustc.git/blame - src/librustc_typeck/coherence/unsafety.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.git] / src / librustc_typeck / coherence / unsafety.rs
CommitLineData
1a4d82fc
JJ
1// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11//! Unsafety checker: every impl either implements a trait defined in this
12//! crate or pertains to a type defined in this crate.
13
54a0048b
SL
14use rustc::ty::TyCtxt;
15use rustc::hir::intravisit;
16use rustc::hir;
1a4d82fc 17
54a0048b 18pub fn check(tcx: &TyCtxt) {
1a4d82fc 19 let mut orphan = UnsafetyChecker { tcx: tcx };
92a42be0 20 tcx.map.krate().visit_all_items(&mut orphan);
1a4d82fc
JJ
21}
22
23struct UnsafetyChecker<'cx, 'tcx:'cx> {
54a0048b 24 tcx: &'cx TyCtxt<'tcx>
1a4d82fc
JJ
25}
26
c34b1796 27impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> {
e9174d1e
SL
28 fn check_unsafety_coherence(&mut self, item: &'v hir::Item,
29 unsafety: hir::Unsafety,
30 polarity: hir::ImplPolarity) {
b039eaaf 31 match self.tcx.impl_trait_ref(self.tcx.map.local_def_id(item.id)) {
c34b1796
AL
32 None => {
33 // Inherent impl.
34 match unsafety {
e9174d1e
SL
35 hir::Unsafety::Normal => { /* OK */ }
36 hir::Unsafety::Unsafe => {
c34b1796
AL
37 span_err!(self.tcx.sess, item.span, E0197,
38 "inherent impls cannot be declared as unsafe");
1a4d82fc 39 }
c34b1796
AL
40 }
41 }
1a4d82fc 42
c34b1796 43 Some(trait_ref) => {
c1a9b12d 44 let trait_def = self.tcx.lookup_trait_def(trait_ref.def_id);
c34b1796 45 match (trait_def.unsafety, unsafety, polarity) {
e9174d1e
SL
46 (hir::Unsafety::Unsafe,
47 hir::Unsafety::Unsafe, hir::ImplPolarity::Negative) => {
c34b1796
AL
48 span_err!(self.tcx.sess, item.span, E0198,
49 "negative implementations are not unsafe");
50 }
1a4d82fc 51
e9174d1e 52 (hir::Unsafety::Normal, hir::Unsafety::Unsafe, _) => {
c34b1796
AL
53 span_err!(self.tcx.sess, item.span, E0199,
54 "implementing the trait `{}` is not unsafe",
62682a34 55 trait_ref);
c34b1796 56 }
1a4d82fc 57
e9174d1e
SL
58 (hir::Unsafety::Unsafe,
59 hir::Unsafety::Normal, hir::ImplPolarity::Positive) => {
c34b1796
AL
60 span_err!(self.tcx.sess, item.span, E0200,
61 "the trait `{}` requires an `unsafe impl` declaration",
62682a34 62 trait_ref);
c34b1796 63 }
85aaf69f 64
e9174d1e
SL
65 (hir::Unsafety::Unsafe,
66 hir::Unsafety::Normal, hir::ImplPolarity::Negative) |
67 (hir::Unsafety::Unsafe,
68 hir::Unsafety::Unsafe, hir::ImplPolarity::Positive) |
69 (hir::Unsafety::Normal, hir::Unsafety::Normal, _) => {
c34b1796 70 /* OK */
1a4d82fc
JJ
71 }
72 }
73 }
c34b1796
AL
74 }
75 }
76}
77
92a42be0 78impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for UnsafetyChecker<'cx, 'tcx> {
e9174d1e 79 fn visit_item(&mut self, item: &'v hir::Item) {
c34b1796 80 match item.node {
e9174d1e
SL
81 hir::ItemDefaultImpl(unsafety, _) => {
82 self.check_unsafety_coherence(item, unsafety, hir::ImplPolarity::Positive);
c34b1796 83 }
e9174d1e 84 hir::ItemImpl(unsafety, polarity, _, _, _, _) => {
c34b1796
AL
85 self.check_unsafety_coherence(item, unsafety, polarity);
86 }
1a4d82fc
JJ
87 _ => { }
88 }
1a4d82fc
JJ
89 }
90}