]>
git.proxmox.com Git - rustc.git/blob - src/librustc_typeck/coherence/unsafety.rs
1 //! Unsafety checker: every impl either implements a trait defined in this
2 //! crate or pertains to a type defined in this crate.
5 use rustc
::hir
::itemlikevisit
::ItemLikeVisitor
;
6 use rustc
::hir
::{self, Unsafety}
;
8 use rustc_error_codes
::*;
10 pub fn check(tcx
: TyCtxt
<'_
>) {
11 let mut unsafety
= UnsafetyChecker { tcx }
;
12 tcx
.hir().krate().visit_all_item_likes(&mut unsafety
);
15 struct UnsafetyChecker
<'tcx
> {
19 impl UnsafetyChecker
<'tcx
> {
20 fn check_unsafety_coherence(&mut self,
22 impl_generics
: Option
<&hir
::Generics
>,
23 unsafety
: hir
::Unsafety
,
24 polarity
: hir
::ImplPolarity
)
26 let local_did
= self.tcx
.hir().local_def_id(item
.hir_id
);
27 if let Some(trait_ref
) = self.tcx
.impl_trait_ref(local_did
) {
28 let trait_def
= self.tcx
.trait_def(trait_ref
.def_id
);
29 let unsafe_attr
= impl_generics
.and_then(|generics
| {
30 generics
.params
.iter().find(|p
| p
.pure_wrt_drop
).map(|_
| "may_dangle")
32 match (trait_def
.unsafety
, unsafe_attr
, unsafety
, polarity
) {
33 (Unsafety
::Normal
, None
, Unsafety
::Unsafe
, hir
::ImplPolarity
::Positive
) => {
34 span_err
!(self.tcx
.sess
,
37 "implementing the trait `{}` is not unsafe",
38 trait_ref
.print_only_trait_path());
41 (Unsafety
::Unsafe
, _
, Unsafety
::Normal
, hir
::ImplPolarity
::Positive
) => {
42 span_err
!(self.tcx
.sess
,
45 "the trait `{}` requires an `unsafe impl` declaration",
46 trait_ref
.print_only_trait_path());
49 (Unsafety
::Normal
, Some(attr_name
), Unsafety
::Normal
,
50 hir
::ImplPolarity
::Positive
) =>
52 span_err
!(self.tcx
.sess
,
55 "requires an `unsafe impl` declaration due to `#[{}]` attribute",
59 (_
, _
, Unsafety
::Unsafe
, hir
::ImplPolarity
::Negative
) => {
60 // Reported in AST validation
61 self.tcx
.sess
.delay_span_bug(item
.span
, "unsafe negative impl");
63 (_
, _
, Unsafety
::Normal
, hir
::ImplPolarity
::Negative
) |
64 (Unsafety
::Unsafe
, _
, Unsafety
::Unsafe
, hir
::ImplPolarity
::Positive
) |
65 (Unsafety
::Normal
, Some(_
), Unsafety
::Unsafe
, hir
::ImplPolarity
::Positive
) |
66 (Unsafety
::Normal
, None
, Unsafety
::Normal
, _
) => {
74 impl ItemLikeVisitor
<'v
> for UnsafetyChecker
<'tcx
> {
75 fn visit_item(&mut self, item
: &'v hir
::Item
) {
76 if let hir
::ItemKind
::Impl(unsafety
, polarity
, _
, ref generics
, ..) = item
.kind
{
77 self.check_unsafety_coherence(item
, Some(generics
), unsafety
, polarity
);
81 fn visit_trait_item(&mut self, _trait_item
: &hir
::TraitItem
) {
84 fn visit_impl_item(&mut self, _impl_item
: &hir
::ImplItem
) {