1 // Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution.
4 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7 // option. This file may not be copied, modified, or distributed
8 // except according to those terms.
10 use crate::rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
11 use crate::rustc::{declare_tool_lint, lint_array};
12 use crate::syntax::ast::*;
13 use crate::syntax::source_map::Span;
14 use crate::syntax::symbol::LocalInternedString;
15 use crate::utils::span_lint;
17 /// **What it does:** Checks for imports that remove "unsafe" from an item's
20 /// **Why is this bad?** Renaming makes it less clear which traits and
21 /// structures are unsafe.
23 /// **Known problems:** None.
27 /// use std::cell::{UnsafeCell as TotallySafeCell};
29 /// extern crate crossbeam;
30 /// use crossbeam::{spawn_unsafe as spawn};
32 declare_clippy_lint! {
33 pub UNSAFE_REMOVED_FROM_NAME,
35 "`unsafe` removed from API names on import"
38 pub struct UnsafeNameRemoval;
40 impl LintPass for UnsafeNameRemoval {
41 fn get_lints(&self) -> LintArray {
42 lint_array!(UNSAFE_REMOVED_FROM_NAME)
46 impl EarlyLintPass for UnsafeNameRemoval {
47 fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
48 if let ItemKind::Use(ref use_tree) = item.node {
49 check_use_tree(use_tree, cx, item.span);
54 fn check_use_tree(use_tree: &UseTree, cx: &EarlyContext<'_>, span: Span) {
56 UseTreeKind::Simple(Some(new_name), ..) => {
57 let old_name = use_tree
61 .expect("use paths cannot be empty")
63 unsafe_to_safe_check(old_name, new_name, cx, span);
65 UseTreeKind::Simple(None, ..) | UseTreeKind::Glob => {},
66 UseTreeKind::Nested(ref nested_use_tree) => {
67 for &(ref use_tree, _) in nested_use_tree {
68 check_use_tree(use_tree, cx, span);
74 fn unsafe_to_safe_check(old_name: Ident, new_name: Ident, cx: &EarlyContext<'_>, span: Span) {
75 let old_str = old_name.name.as_str();
76 let new_str = new_name.name.as_str();
77 if contains_unsafe(&old_str) && !contains_unsafe(&new_str) {
80 UNSAFE_REMOVED_FROM_NAME,
83 "removed \"unsafe\" from the name of `{}` in use as `{}`",
90 fn contains_unsafe(name: &LocalInternedString) -> bool {
91 name.contains("Unsafe") || name.contains("unsafe")