未验证 提交 c60b051b 编写于 作者: M Manish Goregaokar 提交者: GitHub

Rollup merge of #74357 - nnethercote:symbol-related-improvements, r=oli-obk

Some `Symbol` related improvements

These commits make things nicer and avoid some `Symbol::as_str()` calls.

r? @oli-obk
...@@ -16,9 +16,9 @@ pub fn expand_deriving_copy( ...@@ -16,9 +16,9 @@ pub fn expand_deriving_copy(
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
attributes: Vec::new(), attributes: Vec::new(),
path: path_std!(cx, marker::Copy), path: path_std!(marker::Copy),
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(), generics: Bounds::empty(),
is_unsafe: false, is_unsafe: false,
supports_unions: true, supports_unions: true,
methods: Vec::new(), methods: Vec::new(),
......
...@@ -56,7 +56,7 @@ pub fn expand_deriving_clone( ...@@ -56,7 +56,7 @@ pub fn expand_deriving_clone(
} }
} }
ItemKind::Union(..) => { ItemKind::Union(..) => {
bounds = vec![Literal(path_std!(cx, marker::Copy))]; bounds = vec![Literal(path_std!(marker::Copy))];
is_shallow = true; is_shallow = true;
substructure = combine_substructure(Box::new(|c, s, sub| { substructure = combine_substructure(Box::new(|c, s, sub| {
cs_clone_shallow("Clone", c, s, sub, true) cs_clone_shallow("Clone", c, s, sub, true)
...@@ -78,14 +78,14 @@ pub fn expand_deriving_clone( ...@@ -78,14 +78,14 @@ pub fn expand_deriving_clone(
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
attributes: Vec::new(), attributes: Vec::new(),
path: path_std!(cx, clone::Clone), path: path_std!(clone::Clone),
additional_bounds: bounds, additional_bounds: bounds,
generics: LifetimeBounds::empty(), generics: Bounds::empty(),
is_unsafe: false, is_unsafe: false,
supports_unions: true, supports_unions: true,
methods: vec![MethodDef { methods: vec![MethodDef {
name: sym::clone, name: sym::clone,
generics: LifetimeBounds::empty(), generics: Bounds::empty(),
explicit_self: borrowed_explicit_self(), explicit_self: borrowed_explicit_self(),
args: Vec::new(), args: Vec::new(),
ret_ty: Self_, ret_ty: Self_,
......
...@@ -22,14 +22,14 @@ pub fn expand_deriving_eq( ...@@ -22,14 +22,14 @@ pub fn expand_deriving_eq(
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
attributes: Vec::new(), attributes: Vec::new(),
path: path_std!(cx, cmp::Eq), path: path_std!(cmp::Eq),
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(), generics: Bounds::empty(),
is_unsafe: false, is_unsafe: false,
supports_unions: true, supports_unions: true,
methods: vec![MethodDef { methods: vec![MethodDef {
name: sym::assert_receiver_is_total_eq, name: sym::assert_receiver_is_total_eq,
generics: LifetimeBounds::empty(), generics: Bounds::empty(),
explicit_self: borrowed_explicit_self(), explicit_self: borrowed_explicit_self(),
args: vec![], args: vec![],
ret_ty: nil_ty(), ret_ty: nil_ty(),
...@@ -43,13 +43,7 @@ pub fn expand_deriving_eq( ...@@ -43,13 +43,7 @@ pub fn expand_deriving_eq(
associated_types: Vec::new(), associated_types: Vec::new(),
}; };
super::inject_impl_of_structural_trait( super::inject_impl_of_structural_trait(cx, span, item, path_std!(marker::StructuralEq), push);
cx,
span,
item,
path_std!(cx, marker::StructuralEq),
push,
);
trait_def.expand_ext(cx, mitem, item, push, true) trait_def.expand_ext(cx, mitem, item, push, true)
} }
......
...@@ -20,17 +20,17 @@ pub fn expand_deriving_ord( ...@@ -20,17 +20,17 @@ pub fn expand_deriving_ord(
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
attributes: Vec::new(), attributes: Vec::new(),
path: path_std!(cx, cmp::Ord), path: path_std!(cmp::Ord),
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(), generics: Bounds::empty(),
is_unsafe: false, is_unsafe: false,
supports_unions: false, supports_unions: false,
methods: vec![MethodDef { methods: vec![MethodDef {
name: sym::cmp, name: sym::cmp,
generics: LifetimeBounds::empty(), generics: Bounds::empty(),
explicit_self: borrowed_explicit_self(), explicit_self: borrowed_explicit_self(),
args: vec![(borrowed_self(), "other")], args: vec![(borrowed_self(), sym::other)],
ret_ty: Literal(path_std!(cx, cmp::Ordering)), ret_ty: Literal(path_std!(cmp::Ordering)),
attributes: attrs, attributes: attrs,
is_unsafe: false, is_unsafe: false,
unify_fieldless_variants: true, unify_fieldless_variants: true,
......
...@@ -69,9 +69,9 @@ fn cs_ne(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> ...@@ -69,9 +69,9 @@ fn cs_ne(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr>
let attrs = vec![cx.attribute(inline)]; let attrs = vec![cx.attribute(inline)];
MethodDef { MethodDef {
name: $name, name: $name,
generics: LifetimeBounds::empty(), generics: Bounds::empty(),
explicit_self: borrowed_explicit_self(), explicit_self: borrowed_explicit_self(),
args: vec![(borrowed_self(), "other")], args: vec![(borrowed_self(), sym::other)],
ret_ty: Literal(path_local!(bool)), ret_ty: Literal(path_local!(bool)),
attributes: attrs, attributes: attrs,
is_unsafe: false, is_unsafe: false,
...@@ -85,7 +85,7 @@ fn cs_ne(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> ...@@ -85,7 +85,7 @@ fn cs_ne(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr>
cx, cx,
span, span,
item, item,
path_std!(cx, marker::StructuralPartialEq), path_std!(marker::StructuralPartialEq),
push, push,
); );
...@@ -100,9 +100,9 @@ fn cs_ne(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> ...@@ -100,9 +100,9 @@ fn cs_ne(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr>
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
attributes: Vec::new(), attributes: Vec::new(),
path: path_std!(cx, cmp::PartialEq), path: path_std!(cmp::PartialEq),
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(), generics: Bounds::empty(),
is_unsafe: false, is_unsafe: false,
supports_unions: false, supports_unions: false,
methods, methods,
......
...@@ -23,9 +23,9 @@ pub fn expand_deriving_partial_ord( ...@@ -23,9 +23,9 @@ pub fn expand_deriving_partial_ord(
let attrs = vec![cx.attribute(inline)]; let attrs = vec![cx.attribute(inline)];
MethodDef { MethodDef {
name: $name, name: $name,
generics: LifetimeBounds::empty(), generics: Bounds::empty(),
explicit_self: borrowed_explicit_self(), explicit_self: borrowed_explicit_self(),
args: vec![(borrowed_self(), "other")], args: vec![(borrowed_self(), sym::other)],
ret_ty: Literal(path_local!(bool)), ret_ty: Literal(path_local!(bool)),
attributes: attrs, attributes: attrs,
is_unsafe: false, is_unsafe: false,
...@@ -37,9 +37,9 @@ pub fn expand_deriving_partial_ord( ...@@ -37,9 +37,9 @@ pub fn expand_deriving_partial_ord(
}}; }};
} }
let ordering_ty = Literal(path_std!(cx, cmp::Ordering)); let ordering_ty = Literal(path_std!(cmp::Ordering));
let ret_ty = Literal(Path::new_( let ret_ty = Literal(Path::new_(
pathvec_std!(cx, option::Option), pathvec_std!(option::Option),
None, None,
vec![Box::new(ordering_ty)], vec![Box::new(ordering_ty)],
PathKind::Std, PathKind::Std,
...@@ -50,9 +50,9 @@ pub fn expand_deriving_partial_ord( ...@@ -50,9 +50,9 @@ pub fn expand_deriving_partial_ord(
let partial_cmp_def = MethodDef { let partial_cmp_def = MethodDef {
name: sym::partial_cmp, name: sym::partial_cmp,
generics: LifetimeBounds::empty(), generics: Bounds::empty(),
explicit_self: borrowed_explicit_self(), explicit_self: borrowed_explicit_self(),
args: vec![(borrowed_self(), "other")], args: vec![(borrowed_self(), sym::other)],
ret_ty, ret_ty,
attributes: attrs, attributes: attrs,
is_unsafe: false, is_unsafe: false,
...@@ -80,9 +80,9 @@ pub fn expand_deriving_partial_ord( ...@@ -80,9 +80,9 @@ pub fn expand_deriving_partial_ord(
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
attributes: vec![], attributes: vec![],
path: path_std!(cx, cmp::PartialOrd), path: path_std!(cmp::PartialOrd),
additional_bounds: vec![], additional_bounds: vec![],
generics: LifetimeBounds::empty(), generics: Bounds::empty(),
is_unsafe: false, is_unsafe: false,
supports_unions: false, supports_unions: false,
methods, methods,
......
...@@ -18,22 +18,22 @@ pub fn expand_deriving_debug( ...@@ -18,22 +18,22 @@ pub fn expand_deriving_debug(
) { ) {
// &mut ::std::fmt::Formatter // &mut ::std::fmt::Formatter
let fmtr = let fmtr =
Ptr(Box::new(Literal(path_std!(cx, fmt::Formatter))), Borrowed(None, ast::Mutability::Mut)); Ptr(Box::new(Literal(path_std!(fmt::Formatter))), Borrowed(None, ast::Mutability::Mut));
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
attributes: Vec::new(), attributes: Vec::new(),
path: path_std!(cx, fmt::Debug), path: path_std!(fmt::Debug),
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(), generics: Bounds::empty(),
is_unsafe: false, is_unsafe: false,
supports_unions: false, supports_unions: false,
methods: vec![MethodDef { methods: vec![MethodDef {
name: sym::fmt, name: sym::fmt,
generics: LifetimeBounds::empty(), generics: Bounds::empty(),
explicit_self: borrowed_explicit_self(), explicit_self: borrowed_explicit_self(),
args: vec![(fmtr, "f")], args: vec![(fmtr, sym::f)],
ret_ty: Literal(path_std!(cx, fmt::Result)), ret_ty: Literal(path_std!(fmt::Result)),
attributes: Vec::new(), attributes: Vec::new(),
is_unsafe: false, is_unsafe: false,
unify_fieldless_variants: false, unify_fieldless_variants: false,
...@@ -62,7 +62,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> ...@@ -62,7 +62,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
// We want to make sure we have the ctxt set so that we can use unstable methods // We want to make sure we have the ctxt set so that we can use unstable methods
let span = cx.with_def_site_ctxt(span); let span = cx.with_def_site_ctxt(span);
let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked)); let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
let builder = cx.ident_of("debug_trait_builder", span); let builder = Ident::new(sym::debug_trait_builder, span);
let builder_expr = cx.expr_ident(span, builder); let builder_expr = cx.expr_ident(span, builder);
let fmt = substr.nonself_args[0].clone(); let fmt = substr.nonself_args[0].clone();
...@@ -71,7 +71,8 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> ...@@ -71,7 +71,8 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
match vdata { match vdata {
ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => { ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => {
// tuple struct/"normal" variant // tuple struct/"normal" variant
let expr = cx.expr_method_call(span, fmt, cx.ident_of("debug_tuple", span), vec![name]); let expr =
cx.expr_method_call(span, fmt, Ident::new(sym::debug_tuple, span), vec![name]);
stmts.push(cx.stmt_let(span, true, builder, expr)); stmts.push(cx.stmt_let(span, true, builder, expr));
for field in fields { for field in fields {
...@@ -94,7 +95,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> ...@@ -94,7 +95,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
ast::VariantData::Struct(..) => { ast::VariantData::Struct(..) => {
// normal struct/struct variant // normal struct/struct variant
let expr = let expr =
cx.expr_method_call(span, fmt, cx.ident_of("debug_struct", span), vec![name]); cx.expr_method_call(span, fmt, Ident::new(sym::debug_struct, span), vec![name]);
stmts.push(cx.stmt_let(DUMMY_SP, true, builder, expr)); stmts.push(cx.stmt_let(DUMMY_SP, true, builder, expr));
for field in fields { for field in fields {
...@@ -117,7 +118,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> ...@@ -117,7 +118,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
} }
} }
let expr = cx.expr_method_call(span, builder_expr, cx.ident_of("finish", span), vec![]); let expr = cx.expr_method_call(span, builder_expr, Ident::new(sym::finish, span), vec![]);
stmts.push(cx.stmt_expr(expr)); stmts.push(cx.stmt_expr(expr));
let block = cx.block(span, stmts); let block = cx.block(span, stmts);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
use rustc_ast::ast::{Expr, MetaItem, Mutability}; use rustc_ast::ast::{Expr, MetaItem, Mutability};
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span; use rustc_span::Span;
pub fn expand_deriving_rustc_decodable( pub fn expand_deriving_rustc_decodable(
...@@ -18,38 +18,37 @@ pub fn expand_deriving_rustc_decodable( ...@@ -18,38 +18,37 @@ pub fn expand_deriving_rustc_decodable(
item: &Annotatable, item: &Annotatable,
push: &mut dyn FnMut(Annotatable), push: &mut dyn FnMut(Annotatable),
) { ) {
let krate = "rustc_serialize"; let krate = sym::rustc_serialize;
let typaram = "__D"; let typaram = sym::__D;
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
attributes: Vec::new(), attributes: Vec::new(),
path: Path::new_(vec![krate, "Decodable"], None, vec![], PathKind::Global), path: Path::new_(vec![krate, sym::Decodable], None, vec![], PathKind::Global),
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(), generics: Bounds::empty(),
is_unsafe: false, is_unsafe: false,
supports_unions: false, supports_unions: false,
methods: vec![MethodDef { methods: vec![MethodDef {
name: sym::decode, name: sym::decode,
generics: LifetimeBounds { generics: Bounds {
lifetimes: Vec::new(),
bounds: vec![( bounds: vec![(
typaram, typaram,
vec![Path::new_(vec![krate, "Decoder"], None, vec![], PathKind::Global)], vec![Path::new_(vec![krate, sym::Decoder], None, vec![], PathKind::Global)],
)], )],
}, },
explicit_self: None, explicit_self: None,
args: vec![( args: vec![(
Ptr(Box::new(Literal(Path::new_local(typaram))), Borrowed(None, Mutability::Mut)), Ptr(Box::new(Literal(Path::new_local(typaram))), Borrowed(None, Mutability::Mut)),
"d", sym::d,
)], )],
ret_ty: Literal(Path::new_( ret_ty: Literal(Path::new_(
pathvec_std!(cx, result::Result), pathvec_std!(result::Result),
None, None,
vec![ vec![
Box::new(Self_), Box::new(Self_),
Box::new(Literal(Path::new_( Box::new(Literal(Path::new_(
vec![typaram, "Error"], vec![typaram, sym::Error],
None, None,
vec![], vec![],
PathKind::Local, PathKind::Local,
...@@ -74,17 +73,17 @@ fn decodable_substructure( ...@@ -74,17 +73,17 @@ fn decodable_substructure(
cx: &mut ExtCtxt<'_>, cx: &mut ExtCtxt<'_>,
trait_span: Span, trait_span: Span,
substr: &Substructure<'_>, substr: &Substructure<'_>,
krate: &str, krate: Symbol,
) -> P<Expr> { ) -> P<Expr> {
let decoder = substr.nonself_args[0].clone(); let decoder = substr.nonself_args[0].clone();
let recurse = vec![ let recurse = vec![
cx.ident_of(krate, trait_span), Ident::new(krate, trait_span),
cx.ident_of("Decodable", trait_span), Ident::new(sym::Decodable, trait_span),
cx.ident_of("decode", trait_span), Ident::new(sym::decode, trait_span),
]; ];
let exprdecode = cx.expr_path(cx.path_global(trait_span, recurse)); let exprdecode = cx.expr_path(cx.path_global(trait_span, recurse));
// throw an underscore in front to suppress unused variable warnings // throw an underscore in front to suppress unused variable warnings
let blkarg = cx.ident_of("_d", trait_span); let blkarg = Ident::new(sym::_d, trait_span);
let blkdecoder = cx.expr_ident(trait_span, blkarg); let blkdecoder = cx.expr_ident(trait_span, blkarg);
match *substr.fields { match *substr.fields {
...@@ -93,7 +92,7 @@ fn decodable_substructure( ...@@ -93,7 +92,7 @@ fn decodable_substructure(
Unnamed(ref fields, _) => fields.len(), Unnamed(ref fields, _) => fields.len(),
Named(ref fields) => fields.len(), Named(ref fields) => fields.len(),
}; };
let read_struct_field = cx.ident_of("read_struct_field", trait_span); let read_struct_field = Ident::new(sym::read_struct_field, trait_span);
let path = cx.path_ident(trait_span, substr.type_ident); let path = cx.path_ident(trait_span, substr.type_ident);
let result = let result =
...@@ -116,7 +115,7 @@ fn decodable_substructure( ...@@ -116,7 +115,7 @@ fn decodable_substructure(
cx.expr_method_call( cx.expr_method_call(
trait_span, trait_span,
decoder, decoder,
cx.ident_of("read_struct", trait_span), Ident::new(sym::read_struct, trait_span),
vec![ vec![
cx.expr_str(trait_span, substr.type_ident.name), cx.expr_str(trait_span, substr.type_ident.name),
cx.expr_usize(trait_span, nfields), cx.expr_usize(trait_span, nfields),
...@@ -125,11 +124,11 @@ fn decodable_substructure( ...@@ -125,11 +124,11 @@ fn decodable_substructure(
) )
} }
StaticEnum(_, ref fields) => { StaticEnum(_, ref fields) => {
let variant = cx.ident_of("i", trait_span); let variant = Ident::new(sym::i, trait_span);
let mut arms = Vec::with_capacity(fields.len() + 1); let mut arms = Vec::with_capacity(fields.len() + 1);
let mut variants = Vec::with_capacity(fields.len()); let mut variants = Vec::with_capacity(fields.len());
let rvariant_arg = cx.ident_of("read_enum_variant_arg", trait_span); let rvariant_arg = Ident::new(sym::read_enum_variant_arg, trait_span);
for (i, &(ident, v_span, ref parts)) in fields.iter().enumerate() { for (i, &(ident, v_span, ref parts)) in fields.iter().enumerate() {
variants.push(cx.expr_str(v_span, ident.name)); variants.push(cx.expr_str(v_span, ident.name));
...@@ -164,13 +163,13 @@ fn decodable_substructure( ...@@ -164,13 +163,13 @@ fn decodable_substructure(
let result = cx.expr_method_call( let result = cx.expr_method_call(
trait_span, trait_span,
blkdecoder, blkdecoder,
cx.ident_of("read_enum_variant", trait_span), Ident::new(sym::read_enum_variant, trait_span),
vec![variant_vec, lambda], vec![variant_vec, lambda],
); );
cx.expr_method_call( cx.expr_method_call(
trait_span, trait_span,
decoder, decoder,
cx.ident_of("read_enum", trait_span), Ident::new(sym::read_enum, trait_span),
vec![ vec![
cx.expr_str(trait_span, substr.type_ident.name), cx.expr_str(trait_span, substr.type_ident.name),
cx.lambda1(trait_span, result, blkarg), cx.lambda1(trait_span, result, blkarg),
......
use crate::deriving::generic::ty::*; use crate::deriving::generic::ty::*;
use crate::deriving::generic::*; use crate::deriving::generic::*;
use crate::deriving::path_std;
use rustc_ast::ast::{Expr, MetaItem}; use rustc_ast::ast::{Expr, MetaItem};
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
...@@ -21,14 +20,14 @@ pub fn expand_deriving_default( ...@@ -21,14 +20,14 @@ pub fn expand_deriving_default(
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
attributes: Vec::new(), attributes: Vec::new(),
path: path_std!(cx, default::Default), path: Path::new(vec![kw::Default, sym::Default]),
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(), generics: Bounds::empty(),
is_unsafe: false, is_unsafe: false,
supports_unions: false, supports_unions: false,
methods: vec![MethodDef { methods: vec![MethodDef {
name: kw::Default, name: kw::Default,
generics: LifetimeBounds::empty(), generics: Bounds::empty(),
explicit_self: None, explicit_self: None,
args: Vec::new(), args: Vec::new(),
ret_ty: Self_, ret_ty: Self_,
......
...@@ -92,7 +92,7 @@ ...@@ -92,7 +92,7 @@
use rustc_ast::ast::{Expr, ExprKind, MetaItem, Mutability}; use rustc_ast::ast::{Expr, ExprKind, MetaItem, Mutability};
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span; use rustc_span::Span;
pub fn expand_deriving_rustc_encodable( pub fn expand_deriving_rustc_encodable(
...@@ -102,38 +102,42 @@ pub fn expand_deriving_rustc_encodable( ...@@ -102,38 +102,42 @@ pub fn expand_deriving_rustc_encodable(
item: &Annotatable, item: &Annotatable,
push: &mut dyn FnMut(Annotatable), push: &mut dyn FnMut(Annotatable),
) { ) {
let krate = "rustc_serialize"; let krate = sym::rustc_serialize;
let typaram = "__S"; let typaram = sym::__S;
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
attributes: Vec::new(), attributes: Vec::new(),
path: Path::new_(vec![krate, "Encodable"], None, vec![], PathKind::Global), path: Path::new_(vec![krate, sym::Encodable], None, vec![], PathKind::Global),
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(), generics: Bounds::empty(),
is_unsafe: false, is_unsafe: false,
supports_unions: false, supports_unions: false,
methods: vec![MethodDef { methods: vec![MethodDef {
name: sym::encode, name: sym::encode,
generics: LifetimeBounds { generics: Bounds {
lifetimes: Vec::new(),
bounds: vec![( bounds: vec![(
typaram, typaram,
vec![Path::new_(vec![krate, "Encoder"], None, vec![], PathKind::Global)], vec![Path::new_(vec![krate, sym::Encoder], None, vec![], PathKind::Global)],
)], )],
}, },
explicit_self: borrowed_explicit_self(), explicit_self: borrowed_explicit_self(),
args: vec![( args: vec![(
Ptr(Box::new(Literal(Path::new_local(typaram))), Borrowed(None, Mutability::Mut)), Ptr(Box::new(Literal(Path::new_local(typaram))), Borrowed(None, Mutability::Mut)),
"s", // FIXME: we could use `sym::s` here, but making `s` a static
// symbol changes the symbol index ordering in a way that makes
// ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs
// fail. The linting code should be fixed so that its output
// does not depend on the symbol index ordering.
Symbol::intern("s"),
)], )],
ret_ty: Literal(Path::new_( ret_ty: Literal(Path::new_(
pathvec_std!(cx, result::Result), pathvec_std!(result::Result),
None, None,
vec![ vec![
Box::new(Tuple(Vec::new())), Box::new(Tuple(Vec::new())),
Box::new(Literal(Path::new_( Box::new(Literal(Path::new_(
vec![typaram, "Error"], vec![typaram, sym::Error],
None, None,
vec![], vec![],
PathKind::Local, PathKind::Local,
...@@ -158,24 +162,24 @@ fn encodable_substructure( ...@@ -158,24 +162,24 @@ fn encodable_substructure(
cx: &mut ExtCtxt<'_>, cx: &mut ExtCtxt<'_>,
trait_span: Span, trait_span: Span,
substr: &Substructure<'_>, substr: &Substructure<'_>,
krate: &'static str, krate: Symbol,
) -> P<Expr> { ) -> P<Expr> {
let encoder = substr.nonself_args[0].clone(); let encoder = substr.nonself_args[0].clone();
// throw an underscore in front to suppress unused variable warnings // throw an underscore in front to suppress unused variable warnings
let blkarg = cx.ident_of("_e", trait_span); let blkarg = Ident::new(sym::_e, trait_span);
let blkencoder = cx.expr_ident(trait_span, blkarg); let blkencoder = cx.expr_ident(trait_span, blkarg);
let fn_path = cx.expr_path(cx.path_global( let fn_path = cx.expr_path(cx.path_global(
trait_span, trait_span,
vec![ vec![
cx.ident_of(krate, trait_span), Ident::new(krate, trait_span),
cx.ident_of("Encodable", trait_span), Ident::new(sym::Encodable, trait_span),
cx.ident_of("encode", trait_span), Ident::new(sym::encode, trait_span),
], ],
)); ));
match *substr.fields { match *substr.fields {
Struct(_, ref fields) => { Struct(_, ref fields) => {
let emit_struct_field = cx.ident_of("emit_struct_field", trait_span); let emit_struct_field = Ident::new(sym::emit_struct_field, trait_span);
let mut stmts = Vec::new(); let mut stmts = Vec::new();
for (i, &FieldInfo { name, ref self_, span, .. }) in fields.iter().enumerate() { for (i, &FieldInfo { name, ref self_, span, .. }) in fields.iter().enumerate() {
let name = match name { let name = match name {
...@@ -215,7 +219,7 @@ fn encodable_substructure( ...@@ -215,7 +219,7 @@ fn encodable_substructure(
cx.expr_method_call( cx.expr_method_call(
trait_span, trait_span,
encoder, encoder,
cx.ident_of("emit_struct", trait_span), Ident::new(sym::emit_struct, trait_span),
vec![ vec![
cx.expr_str(trait_span, substr.type_ident.name), cx.expr_str(trait_span, substr.type_ident.name),
cx.expr_usize(trait_span, fields.len()), cx.expr_usize(trait_span, fields.len()),
...@@ -231,7 +235,7 @@ fn encodable_substructure( ...@@ -231,7 +235,7 @@ fn encodable_substructure(
// actually exist. // actually exist.
let me = cx.stmt_let(trait_span, false, blkarg, encoder); let me = cx.stmt_let(trait_span, false, blkarg, encoder);
let encoder = cx.expr_ident(trait_span, blkarg); let encoder = cx.expr_ident(trait_span, blkarg);
let emit_variant_arg = cx.ident_of("emit_enum_variant_arg", trait_span); let emit_variant_arg = Ident::new(sym::emit_enum_variant_arg, trait_span);
let mut stmts = Vec::new(); let mut stmts = Vec::new();
if !fields.is_empty() { if !fields.is_empty() {
let last = fields.len() - 1; let last = fields.len() - 1;
...@@ -264,7 +268,7 @@ fn encodable_substructure( ...@@ -264,7 +268,7 @@ fn encodable_substructure(
let call = cx.expr_method_call( let call = cx.expr_method_call(
trait_span, trait_span,
blkencoder, blkencoder,
cx.ident_of("emit_enum_variant", trait_span), Ident::new(sym::emit_enum_variant, trait_span),
vec![ vec![
name, name,
cx.expr_usize(trait_span, idx), cx.expr_usize(trait_span, idx),
...@@ -276,7 +280,7 @@ fn encodable_substructure( ...@@ -276,7 +280,7 @@ fn encodable_substructure(
let ret = cx.expr_method_call( let ret = cx.expr_method_call(
trait_span, trait_span,
encoder, encoder,
cx.ident_of("emit_enum", trait_span), Ident::new(sym::emit_enum, trait_span),
vec![cx.expr_str(trait_span, substr.type_ident.name), blk], vec![cx.expr_str(trait_span, substr.type_ident.name), blk],
); );
cx.expr_block(cx.block(trait_span, vec![me, cx.stmt_expr(ret)])) cx.expr_block(cx.block(trait_span, vec![me, cx.stmt_expr(ret)]))
......
...@@ -191,7 +191,7 @@ ...@@ -191,7 +191,7 @@
use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span; use rustc_span::Span;
use ty::{LifetimeBounds, Path, Ptr, PtrTy, Self_, Ty}; use ty::{Bounds, Path, Ptr, PtrTy, Self_, Ty};
use crate::deriving; use crate::deriving;
...@@ -204,14 +204,14 @@ pub struct TraitDef<'a> { ...@@ -204,14 +204,14 @@ pub struct TraitDef<'a> {
pub attributes: Vec<ast::Attribute>, pub attributes: Vec<ast::Attribute>,
/// Path of the trait, including any type parameters /// Path of the trait, including any type parameters
pub path: Path<'a>, pub path: Path,
/// Additional bounds required of any type parameters of the type, /// Additional bounds required of any type parameters of the type,
/// other than the current trait /// other than the current trait
pub additional_bounds: Vec<Ty<'a>>, pub additional_bounds: Vec<Ty>,
/// Any extra lifetimes and/or bounds, e.g., `D: serialize::Decoder` /// Any extra lifetimes and/or bounds, e.g., `D: serialize::Decoder`
pub generics: LifetimeBounds<'a>, pub generics: Bounds,
/// Is it an `unsafe` trait? /// Is it an `unsafe` trait?
pub is_unsafe: bool, pub is_unsafe: bool,
...@@ -221,14 +221,14 @@ pub struct TraitDef<'a> { ...@@ -221,14 +221,14 @@ pub struct TraitDef<'a> {
pub methods: Vec<MethodDef<'a>>, pub methods: Vec<MethodDef<'a>>,
pub associated_types: Vec<(Ident, Ty<'a>)>, pub associated_types: Vec<(Ident, Ty)>,
} }
pub struct MethodDef<'a> { pub struct MethodDef<'a> {
/// name of the method /// name of the method
pub name: Symbol, pub name: Symbol,
/// List of generics, e.g., `R: rand::Rng` /// List of generics, e.g., `R: rand::Rng`
pub generics: LifetimeBounds<'a>, pub generics: Bounds,
/// Whether there is a self argument (outer Option) i.e., whether /// Whether there is a self argument (outer Option) i.e., whether
/// this is a static function, and whether it is a pointer (inner /// this is a static function, and whether it is a pointer (inner
...@@ -236,10 +236,10 @@ pub struct MethodDef<'a> { ...@@ -236,10 +236,10 @@ pub struct MethodDef<'a> {
pub explicit_self: Option<Option<PtrTy>>, pub explicit_self: Option<Option<PtrTy>>,
/// Arguments other than the self argument /// Arguments other than the self argument
pub args: Vec<(Ty<'a>, &'a str)>, pub args: Vec<(Ty, Symbol)>,
/// Returns type /// Returns type
pub ret_ty: Ty<'a>, pub ret_ty: Ty,
pub attributes: Vec<ast::Attribute>, pub attributes: Vec<ast::Attribute>,
...@@ -865,7 +865,7 @@ fn split_self_nonself_args( ...@@ -865,7 +865,7 @@ fn split_self_nonself_args(
for (ty, name) in self.args.iter() { for (ty, name) in self.args.iter() {
let ast_ty = ty.to_ty(cx, trait_.span, type_ident, generics); let ast_ty = ty.to_ty(cx, trait_.span, type_ident, generics);
let ident = cx.ident_of(name, trait_.span); let ident = Ident::new(*name, trait_.span);
arg_tys.push((ident, ast_ty)); arg_tys.push((ident, ast_ty));
let arg_expr = cx.expr_ident(trait_.span, ident); let arg_expr = cx.expr_ident(trait_.span, ident);
...@@ -1170,8 +1170,10 @@ fn build_enum_match_tuple<'b>( ...@@ -1170,8 +1170,10 @@ fn build_enum_match_tuple<'b>(
) )
.collect::<Vec<String>>(); .collect::<Vec<String>>();
let self_arg_idents = let self_arg_idents = self_arg_names
self_arg_names.iter().map(|name| cx.ident_of(name, sp)).collect::<Vec<Ident>>(); .iter()
.map(|name| Ident::from_str_and_span(name, sp))
.collect::<Vec<Ident>>();
// The `vi_idents` will be bound, solely in the catch-all, to // The `vi_idents` will be bound, solely in the catch-all, to
// a series of let statements mapping each self_arg to an int // a series of let statements mapping each self_arg to an int
...@@ -1180,7 +1182,7 @@ fn build_enum_match_tuple<'b>( ...@@ -1180,7 +1182,7 @@ fn build_enum_match_tuple<'b>(
.iter() .iter()
.map(|name| { .map(|name| {
let vi_suffix = format!("{}_vi", &name[..]); let vi_suffix = format!("{}_vi", &name[..]);
cx.ident_of(&vi_suffix[..], trait_.span) Ident::from_str_and_span(&vi_suffix, trait_.span)
}) })
.collect::<Vec<Ident>>(); .collect::<Vec<Ident>>();
...@@ -1568,7 +1570,7 @@ fn create_struct_pattern( ...@@ -1568,7 +1570,7 @@ fn create_struct_pattern(
let mut ident_exprs = Vec::new(); let mut ident_exprs = Vec::new();
for (i, struct_field) in struct_def.fields().iter().enumerate() { for (i, struct_field) in struct_def.fields().iter().enumerate() {
let sp = struct_field.span.with_ctxt(self.span.ctxt()); let sp = struct_field.span.with_ctxt(self.span.ctxt());
let ident = cx.ident_of(&format!("{}_{}", prefix, i), self.span); let ident = Ident::from_str_and_span(&format!("{}_{}", prefix, i), self.span);
paths.push(ident.with_span_pos(sp)); paths.push(ident.with_span_pos(sp));
let val = cx.expr_path(cx.path_ident(sp, ident)); let val = cx.expr_path(cx.path_ident(sp, ident));
let val = if use_temporaries { val } else { cx.expr_deref(sp, val) }; let val = if use_temporaries { val } else { cx.expr_deref(sp, val) };
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
use rustc_expand::base::ExtCtxt; use rustc_expand::base::ExtCtxt;
use rustc_span::source_map::{respan, DUMMY_SP}; use rustc_span::source_map::{respan, DUMMY_SP};
use rustc_span::symbol::{kw, Ident}; use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_span::Span; use rustc_span::Span;
/// The types of pointers /// The types of pointers
...@@ -24,10 +24,10 @@ pub enum PtrTy { ...@@ -24,10 +24,10 @@ pub enum PtrTy {
/// A path, e.g., `::std::option::Option::<i32>` (global). Has support /// A path, e.g., `::std::option::Option::<i32>` (global). Has support
/// for type parameters and a lifetime. /// for type parameters and a lifetime.
#[derive(Clone)] #[derive(Clone)]
pub struct Path<'a> { pub struct Path {
path: Vec<&'a str>, path: Vec<Symbol>,
lifetime: Option<Ident>, lifetime: Option<Ident>,
params: Vec<Box<Ty<'a>>>, params: Vec<Box<Ty>>,
kind: PathKind, kind: PathKind,
} }
...@@ -38,19 +38,19 @@ pub enum PathKind { ...@@ -38,19 +38,19 @@ pub enum PathKind {
Std, Std,
} }
impl<'a> Path<'a> { impl Path {
pub fn new(path: Vec<&str>) -> Path<'_> { pub fn new(path: Vec<Symbol>) -> Path {
Path::new_(path, None, Vec::new(), PathKind::Std) Path::new_(path, None, Vec::new(), PathKind::Std)
} }
pub fn new_local(path: &str) -> Path<'_> { pub fn new_local(path: Symbol) -> Path {
Path::new_(vec![path], None, Vec::new(), PathKind::Local) Path::new_(vec![path], None, Vec::new(), PathKind::Local)
} }
pub fn new_<'r>( pub fn new_(
path: Vec<&'r str>, path: Vec<Symbol>,
lifetime: Option<Ident>, lifetime: Option<Ident>,
params: Vec<Box<Ty<'r>>>, params: Vec<Box<Ty>>,
kind: PathKind, kind: PathKind,
) -> Path<'r> { ) -> Path {
Path { path, lifetime, params, kind } Path { path, lifetime, params, kind }
} }
...@@ -70,7 +70,7 @@ pub fn to_path( ...@@ -70,7 +70,7 @@ pub fn to_path(
self_ty: Ident, self_ty: Ident,
self_generics: &Generics, self_generics: &Generics,
) -> ast::Path { ) -> ast::Path {
let mut idents = self.path.iter().map(|s| cx.ident_of(*s, span)).collect(); let mut idents = self.path.iter().map(|s| Ident::new(*s, span)).collect();
let lt = mk_lifetimes(cx, span, &self.lifetime); let lt = mk_lifetimes(cx, span, &self.lifetime);
let tys: Vec<P<ast::Ty>> = let tys: Vec<P<ast::Ty>> =
self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect(); self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();
...@@ -94,21 +94,21 @@ pub fn to_path( ...@@ -94,21 +94,21 @@ pub fn to_path(
/// A type. Supports pointers, Self, and literals. /// A type. Supports pointers, Self, and literals.
#[derive(Clone)] #[derive(Clone)]
pub enum Ty<'a> { pub enum Ty {
Self_, Self_,
/// &/Box/ Ty /// &/Box/ Ty
Ptr(Box<Ty<'a>>, PtrTy), Ptr(Box<Ty>, PtrTy),
/// `mod::mod::Type<[lifetime], [Params...]>`, including a plain type /// `mod::mod::Type<[lifetime], [Params...]>`, including a plain type
/// parameter, and things like `i32` /// parameter, and things like `i32`
Literal(Path<'a>), Literal(Path),
/// includes unit /// includes unit
Tuple(Vec<Ty<'a>>), Tuple(Vec<Ty>),
} }
pub fn borrowed_ptrty() -> PtrTy { pub fn borrowed_ptrty() -> PtrTy {
Borrowed(None, ast::Mutability::Not) Borrowed(None, ast::Mutability::Not)
} }
pub fn borrowed(ty: Box<Ty<'_>>) -> Ty<'_> { pub fn borrowed(ty: Box<Ty>) -> Ty {
Ptr(ty, borrowed_ptrty()) Ptr(ty, borrowed_ptrty())
} }
...@@ -116,11 +116,11 @@ pub fn borrowed_explicit_self() -> Option<Option<PtrTy>> { ...@@ -116,11 +116,11 @@ pub fn borrowed_explicit_self() -> Option<Option<PtrTy>> {
Some(Some(borrowed_ptrty())) Some(Some(borrowed_ptrty()))
} }
pub fn borrowed_self<'r>() -> Ty<'r> { pub fn borrowed_self() -> Ty {
borrowed(Box::new(Self_)) borrowed(Box::new(Self_))
} }
pub fn nil_ty<'r>() -> Ty<'r> { pub fn nil_ty() -> Ty {
Tuple(Vec::new()) Tuple(Vec::new())
} }
...@@ -132,7 +132,7 @@ fn mk_lifetimes(cx: &ExtCtxt<'_>, span: Span, lt: &Option<Ident>) -> Vec<ast::Li ...@@ -132,7 +132,7 @@ fn mk_lifetimes(cx: &ExtCtxt<'_>, span: Span, lt: &Option<Ident>) -> Vec<ast::Li
mk_lifetime(cx, span, lt).into_iter().collect() mk_lifetime(cx, span, lt).into_iter().collect()
} }
impl<'a> Ty<'a> { impl Ty {
pub fn to_ty( pub fn to_ty(
&self, &self,
cx: &ExtCtxt<'_>, cx: &ExtCtxt<'_>,
...@@ -199,9 +199,9 @@ pub fn to_path( ...@@ -199,9 +199,9 @@ pub fn to_path(
fn mk_ty_param( fn mk_ty_param(
cx: &ExtCtxt<'_>, cx: &ExtCtxt<'_>,
span: Span, span: Span,
name: &str, name: Symbol,
attrs: &[ast::Attribute], attrs: &[ast::Attribute],
bounds: &[Path<'_>], bounds: &[Path],
self_ident: Ident, self_ident: Ident,
self_generics: &Generics, self_generics: &Generics,
) -> ast::GenericParam { ) -> ast::GenericParam {
...@@ -212,7 +212,7 @@ fn mk_ty_param( ...@@ -212,7 +212,7 @@ fn mk_ty_param(
cx.trait_bound(path) cx.trait_bound(path)
}) })
.collect(); .collect();
cx.typaram(span, cx.ident_of(name, span), attrs.to_owned(), bounds, None) cx.typaram(span, Ident::new(name, span), attrs.to_owned(), bounds, None)
} }
fn mk_generics(params: Vec<ast::GenericParam>, span: Span) -> Generics { fn mk_generics(params: Vec<ast::GenericParam>, span: Span) -> Generics {
...@@ -223,16 +223,15 @@ fn mk_generics(params: Vec<ast::GenericParam>, span: Span) -> Generics { ...@@ -223,16 +223,15 @@ fn mk_generics(params: Vec<ast::GenericParam>, span: Span) -> Generics {
} }
} }
/// Lifetimes and bounds on type parameters /// Bounds on type parameters.
#[derive(Clone)] #[derive(Clone)]
pub struct LifetimeBounds<'a> { pub struct Bounds {
pub lifetimes: Vec<(&'a str, Vec<&'a str>)>, pub bounds: Vec<(Symbol, Vec<Path>)>,
pub bounds: Vec<(&'a str, Vec<Path<'a>>)>,
} }
impl<'a> LifetimeBounds<'a> { impl Bounds {
pub fn empty() -> LifetimeBounds<'a> { pub fn empty() -> Bounds {
LifetimeBounds { lifetimes: Vec::new(), bounds: Vec::new() } Bounds { bounds: Vec::new() }
} }
pub fn to_generics( pub fn to_generics(
&self, &self,
...@@ -242,18 +241,12 @@ pub fn to_generics( ...@@ -242,18 +241,12 @@ pub fn to_generics(
self_generics: &Generics, self_generics: &Generics,
) -> Generics { ) -> Generics {
let generic_params = self let generic_params = self
.lifetimes .bounds
.iter() .iter()
.map(|&(lt, ref bounds)| { .map(|t| {
let bounds = bounds
.iter()
.map(|b| ast::GenericBound::Outlives(cx.lifetime(span, Ident::from_str(b))));
cx.lifetime_def(span, Ident::from_str(lt), vec![], bounds.collect())
})
.chain(self.bounds.iter().map(|t| {
let (name, ref bounds) = *t; let (name, ref bounds) = *t;
mk_ty_param(cx, span, name, &[], &bounds, self_ty, self_generics) mk_ty_param(cx, span, name, &[], &bounds, self_ty, self_generics)
})) })
.collect(); .collect();
mk_generics(generic_params, span) mk_generics(generic_params, span)
......
...@@ -15,9 +15,9 @@ pub fn expand_deriving_hash( ...@@ -15,9 +15,9 @@ pub fn expand_deriving_hash(
item: &Annotatable, item: &Annotatable,
push: &mut dyn FnMut(Annotatable), push: &mut dyn FnMut(Annotatable),
) { ) {
let path = Path::new_(pathvec_std!(cx, hash::Hash), None, vec![], PathKind::Std); let path = Path::new_(pathvec_std!(hash::Hash), None, vec![], PathKind::Std);
let typaram = "__H"; let typaram = sym::__H;
let arg = Path::new_local(typaram); let arg = Path::new_local(typaram);
let hash_trait_def = TraitDef { let hash_trait_def = TraitDef {
...@@ -25,17 +25,14 @@ pub fn expand_deriving_hash( ...@@ -25,17 +25,14 @@ pub fn expand_deriving_hash(
attributes: Vec::new(), attributes: Vec::new(),
path, path,
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(), generics: Bounds::empty(),
is_unsafe: false, is_unsafe: false,
supports_unions: false, supports_unions: false,
methods: vec![MethodDef { methods: vec![MethodDef {
name: sym::hash, name: sym::hash,
generics: LifetimeBounds { generics: Bounds { bounds: vec![(typaram, vec![path_std!(hash::Hasher)])] },
lifetimes: Vec::new(),
bounds: vec![(typaram, vec![path_std!(cx, hash::Hasher)])],
},
explicit_self: borrowed_explicit_self(), explicit_self: borrowed_explicit_self(),
args: vec![(Ptr(Box::new(Literal(arg)), Borrowed(None, Mutability::Mut)), "state")], args: vec![(Ptr(Box::new(Literal(arg)), Borrowed(None, Mutability::Mut)), sym::state)],
ret_ty: nil_ty(), ret_ty: nil_ty(),
attributes: vec![], attributes: vec![],
is_unsafe: false, is_unsafe: false,
......
...@@ -7,11 +7,11 @@ ...@@ -7,11 +7,11 @@
use rustc_span::Span; use rustc_span::Span;
macro path_local($x:ident) { macro path_local($x:ident) {
generic::ty::Path::new_local(stringify!($x)) generic::ty::Path::new_local(sym::$x)
} }
macro pathvec_std($cx:expr, $($rest:ident)::+) {{ macro pathvec_std($($rest:ident)::+) {{
vec![ $( stringify!($rest) ),+ ] vec![ $( sym::$rest ),+ ]
}} }}
macro path_std($($x:tt)*) { macro path_std($($x:tt)*) {
...@@ -84,7 +84,7 @@ fn inject_impl_of_structural_trait( ...@@ -84,7 +84,7 @@ fn inject_impl_of_structural_trait(
cx: &mut ExtCtxt<'_>, cx: &mut ExtCtxt<'_>,
span: Span, span: Span,
item: &Annotatable, item: &Annotatable,
structural_path: generic::ty::Path<'_>, structural_path: generic::ty::Path,
push: &mut dyn FnMut(Annotatable), push: &mut dyn FnMut(Annotatable),
) { ) {
let item = match *item { let item = match *item {
......
...@@ -578,31 +578,31 @@ fn build_index_map(&mut self) { ...@@ -578,31 +578,31 @@ fn build_index_map(&mut self) {
self.count_args_index_offset = sofar; self.count_args_index_offset = sofar;
} }
fn rtpath(ecx: &ExtCtxt<'_>, s: &str) -> Vec<Ident> { fn rtpath(ecx: &ExtCtxt<'_>, s: Symbol) -> Vec<Ident> {
ecx.std_path(&[sym::fmt, sym::rt, sym::v1, Symbol::intern(s)]) ecx.std_path(&[sym::fmt, sym::rt, sym::v1, s])
} }
fn build_count(&self, c: parse::Count) -> P<ast::Expr> { fn build_count(&self, c: parse::Count) -> P<ast::Expr> {
let sp = self.macsp; let sp = self.macsp;
let count = |c, arg| { let count = |c, arg| {
let mut path = Context::rtpath(self.ecx, "Count"); let mut path = Context::rtpath(self.ecx, sym::Count);
path.push(self.ecx.ident_of(c, sp)); path.push(Ident::new(c, sp));
match arg { match arg {
Some(arg) => self.ecx.expr_call_global(sp, path, vec![arg]), Some(arg) => self.ecx.expr_call_global(sp, path, vec![arg]),
None => self.ecx.expr_path(self.ecx.path_global(sp, path)), None => self.ecx.expr_path(self.ecx.path_global(sp, path)),
} }
}; };
match c { match c {
parse::CountIs(i) => count("Is", Some(self.ecx.expr_usize(sp, i))), parse::CountIs(i) => count(sym::Is, Some(self.ecx.expr_usize(sp, i))),
parse::CountIsParam(i) => { parse::CountIsParam(i) => {
// This needs mapping too, as `i` is referring to a macro // This needs mapping too, as `i` is referring to a macro
// argument. If `i` is not found in `count_positions` then // argument. If `i` is not found in `count_positions` then
// the error had already been emitted elsewhere. // the error had already been emitted elsewhere.
let i = self.count_positions.get(&i).cloned().unwrap_or(0) let i = self.count_positions.get(&i).cloned().unwrap_or(0)
+ self.count_args_index_offset; + self.count_args_index_offset;
count("Param", Some(self.ecx.expr_usize(sp, i))) count(sym::Param, Some(self.ecx.expr_usize(sp, i)))
} }
parse::CountImplied => count("Implied", None), parse::CountImplied => count(sym::Implied, None),
// should never be the case, names are already resolved // should never be the case, names are already resolved
parse::CountIsName(_) => panic!("should never happen"), parse::CountIsName(_) => panic!("should never happen"),
} }
...@@ -690,40 +690,40 @@ fn build_piece( ...@@ -690,40 +690,40 @@ fn build_piece(
// Build the format // Build the format
let fill = self.ecx.expr_lit(sp, ast::LitKind::Char(fill)); let fill = self.ecx.expr_lit(sp, ast::LitKind::Char(fill));
let align = |name| { let align = |name| {
let mut p = Context::rtpath(self.ecx, "Alignment"); let mut p = Context::rtpath(self.ecx, sym::Alignment);
p.push(self.ecx.ident_of(name, sp)); p.push(Ident::new(name, sp));
self.ecx.path_global(sp, p) self.ecx.path_global(sp, p)
}; };
let align = match arg.format.align { let align = match arg.format.align {
parse::AlignLeft => align("Left"), parse::AlignLeft => align(sym::Left),
parse::AlignRight => align("Right"), parse::AlignRight => align(sym::Right),
parse::AlignCenter => align("Center"), parse::AlignCenter => align(sym::Center),
parse::AlignUnknown => align("Unknown"), parse::AlignUnknown => align(sym::Unknown),
}; };
let align = self.ecx.expr_path(align); let align = self.ecx.expr_path(align);
let flags = self.ecx.expr_u32(sp, arg.format.flags); let flags = self.ecx.expr_u32(sp, arg.format.flags);
let prec = self.build_count(arg.format.precision); let prec = self.build_count(arg.format.precision);
let width = self.build_count(arg.format.width); let width = self.build_count(arg.format.width);
let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, "FormatSpec")); let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, sym::FormatSpec));
let fmt = self.ecx.expr_struct( let fmt = self.ecx.expr_struct(
sp, sp,
path, path,
vec![ vec![
self.ecx.field_imm(sp, self.ecx.ident_of("fill", sp), fill), self.ecx.field_imm(sp, Ident::new(sym::fill, sp), fill),
self.ecx.field_imm(sp, self.ecx.ident_of("align", sp), align), self.ecx.field_imm(sp, Ident::new(sym::align, sp), align),
self.ecx.field_imm(sp, self.ecx.ident_of("flags", sp), flags), self.ecx.field_imm(sp, Ident::new(sym::flags, sp), flags),
self.ecx.field_imm(sp, self.ecx.ident_of("precision", sp), prec), self.ecx.field_imm(sp, Ident::new(sym::precision, sp), prec),
self.ecx.field_imm(sp, self.ecx.ident_of("width", sp), width), self.ecx.field_imm(sp, Ident::new(sym::width, sp), width),
], ],
); );
let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, "Argument")); let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, sym::Argument));
Some(self.ecx.expr_struct( Some(self.ecx.expr_struct(
sp, sp,
path, path,
vec![ vec![
self.ecx.field_imm(sp, self.ecx.ident_of("position", sp), pos), self.ecx.field_imm(sp, Ident::new(sym::position, sp), pos),
self.ecx.field_imm(sp, self.ecx.ident_of("format", sp), fmt), self.ecx.field_imm(sp, Ident::new(sym::format, sp), fmt),
], ],
)) ))
} }
...@@ -740,7 +740,7 @@ fn into_expr(self) -> P<ast::Expr> { ...@@ -740,7 +740,7 @@ fn into_expr(self) -> P<ast::Expr> {
let mut heads = Vec::with_capacity(self.args.len()); let mut heads = Vec::with_capacity(self.args.len());
let names_pos: Vec<_> = (0..self.args.len()) let names_pos: Vec<_> = (0..self.args.len())
.map(|i| self.ecx.ident_of(&format!("arg{}", i), self.macsp)) .map(|i| Ident::from_str_and_span(&format!("arg{}", i), self.macsp))
.collect(); .collect();
// First, build up the static array which will become our precompiled // First, build up the static array which will become our precompiled
......
...@@ -58,7 +58,7 @@ fn allocator_fn(&self, method: &AllocatorMethod) -> Stmt { ...@@ -58,7 +58,7 @@ fn allocator_fn(&self, method: &AllocatorMethod) -> Stmt {
let mut abi_args = Vec::new(); let mut abi_args = Vec::new();
let mut i = 0; let mut i = 0;
let mut mk = || { let mut mk = || {
let name = self.cx.ident_of(&format!("arg{}", i), self.span); let name = Ident::from_str_and_span(&format!("arg{}", i), self.span);
i += 1; i += 1;
name name
}; };
...@@ -72,7 +72,7 @@ fn allocator_fn(&self, method: &AllocatorMethod) -> Stmt { ...@@ -72,7 +72,7 @@ fn allocator_fn(&self, method: &AllocatorMethod) -> Stmt {
let kind = ItemKind::Fn(ast::Defaultness::Final, sig, Generics::default(), block); let kind = ItemKind::Fn(ast::Defaultness::Final, sig, Generics::default(), block);
let item = self.cx.item( let item = self.cx.item(
self.span, self.span,
self.cx.ident_of(&self.kind.fn_name(method.name), self.span), Ident::from_str_and_span(&self.kind.fn_name(method.name), self.span),
self.attrs(), self.attrs(),
kind, kind,
); );
......
...@@ -384,12 +384,12 @@ fn mk_decls( ...@@ -384,12 +384,12 @@ fn mk_decls(
let proc_macro = Ident::new(sym::proc_macro, span); let proc_macro = Ident::new(sym::proc_macro, span);
let krate = cx.item(span, proc_macro, Vec::new(), ast::ItemKind::ExternCrate(None)); let krate = cx.item(span, proc_macro, Vec::new(), ast::ItemKind::ExternCrate(None));
let bridge = cx.ident_of("bridge", span); let bridge = Ident::new(sym::bridge, span);
let client = cx.ident_of("client", span); let client = Ident::new(sym::client, span);
let proc_macro_ty = cx.ident_of("ProcMacro", span); let proc_macro_ty = Ident::new(sym::ProcMacro, span);
let custom_derive = cx.ident_of("custom_derive", span); let custom_derive = Ident::new(sym::custom_derive, span);
let attr = cx.ident_of("attr", span); let attr = Ident::new(sym::attr, span);
let bang = cx.ident_of("bang", span); let bang = Ident::new(sym::bang, span);
let krate_ref = RefCell::new(ast_krate); let krate_ref = RefCell::new(ast_krate);
...@@ -447,7 +447,7 @@ fn mk_decls( ...@@ -447,7 +447,7 @@ fn mk_decls(
let decls_static = cx let decls_static = cx
.item_static( .item_static(
span, span,
cx.ident_of("_DECLS", span), Ident::new(sym::_DECLS, span),
cx.ty_rptr( cx.ty_rptr(
span, span,
cx.ty( cx.ty(
......
...@@ -108,22 +108,38 @@ pub fn expand_test_or_bench( ...@@ -108,22 +108,38 @@ pub fn expand_test_or_bench(
let test_id = Ident::new(sym::test, attr_sp); let test_id = Ident::new(sym::test, attr_sp);
// creates test::$name // creates test::$name
let test_path = |name| cx.path(sp, vec![test_id, cx.ident_of(name, sp)]); let test_path = |name| cx.path(sp, vec![test_id, Ident::from_str_and_span(name, sp)]);
// creates test::ShouldPanic::$name // creates test::ShouldPanic::$name
let should_panic_path = let should_panic_path = |name| {
|name| cx.path(sp, vec![test_id, cx.ident_of("ShouldPanic", sp), cx.ident_of(name, sp)]); cx.path(
sp,
vec![
test_id,
Ident::from_str_and_span("ShouldPanic", sp),
Ident::from_str_and_span(name, sp),
],
)
};
// creates test::TestType::$name // creates test::TestType::$name
let test_type_path = let test_type_path = |name| {
|name| cx.path(sp, vec![test_id, cx.ident_of("TestType", sp), cx.ident_of(name, sp)]); cx.path(
sp,
vec![
test_id,
Ident::from_str_and_span("TestType", sp),
Ident::from_str_and_span(name, sp),
],
)
};
// creates $name: $expr // creates $name: $expr
let field = |name, expr| cx.field_imm(sp, cx.ident_of(name, sp), expr); let field = |name, expr| cx.field_imm(sp, Ident::from_str_and_span(name, sp), expr);
let test_fn = if is_bench { let test_fn = if is_bench {
// A simple ident for a lambda // A simple ident for a lambda
let b = cx.ident_of("b", attr_sp); let b = Ident::from_str_and_span("b", attr_sp);
cx.expr_call( cx.expr_call(
sp, sp,
......
...@@ -270,7 +270,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> { ...@@ -270,7 +270,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
let mut test_runner = cx let mut test_runner = cx
.test_runner .test_runner
.clone() .clone()
.unwrap_or(ecx.path(sp, vec![test_id, ecx.ident_of(runner_name, sp)])); .unwrap_or(ecx.path(sp, vec![test_id, Ident::from_str_and_span(runner_name, sp)]));
test_runner.span = sp; test_runner.span = sp;
......
...@@ -1061,9 +1061,6 @@ pub fn trace_macros(&self) -> bool { ...@@ -1061,9 +1061,6 @@ pub fn trace_macros(&self) -> bool {
pub fn set_trace_macros(&mut self, x: bool) { pub fn set_trace_macros(&mut self, x: bool) {
self.ecfg.trace_mac = x self.ecfg.trace_mac = x
} }
pub fn ident_of(&self, st: &str, sp: Span) -> Ident {
Ident::from_str_and_span(st, sp)
}
pub fn std_path(&self, components: &[Symbol]) -> Vec<Ident> { pub fn std_path(&self, components: &[Symbol]) -> Vec<Ident> {
let def_site = self.with_def_site_ctxt(DUMMY_SP); let def_site = self.with_def_site_ctxt(DUMMY_SP);
iter::once(Ident::new(kw::DollarCrate, def_site)) iter::once(Ident::new(kw::DollarCrate, def_site))
......
...@@ -368,7 +368,7 @@ pub fn expr_try(&self, sp: Span, head: P<ast::Expr>) -> P<ast::Expr> { ...@@ -368,7 +368,7 @@ pub fn expr_try(&self, sp: Span, head: P<ast::Expr>) -> P<ast::Expr> {
let err = self.std_path(&[sym::result, sym::Result, sym::Err]); let err = self.std_path(&[sym::result, sym::Result, sym::Err]);
let err_path = self.path_global(sp, err); let err_path = self.path_global(sp, err);
let binding_variable = self.ident_of("__try_var", sp); let binding_variable = Ident::new(sym::__try_var, sp);
let binding_pat = self.pat_ident(sp, binding_variable); let binding_pat = self.pat_ident(sp, binding_variable);
let binding_expr = self.expr_ident(sp, binding_variable); let binding_expr = self.expr_ident(sp, binding_variable);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_index::bit_set::BitMatrix; use rustc_index::bit_set::BitMatrix;
use rustc_index::vec::IndexVec; use rustc_index::vec::IndexVec;
use rustc_span::{Span, Symbol}; use rustc_span::Span;
use rustc_target::abi::VariantIdx; use rustc_target::abi::VariantIdx;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::cell::Cell; use std::cell::Cell;
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)] #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
pub enum UnsafetyViolationKind { pub enum UnsafetyViolationKind {
/// Only permitted in regular `fn`s, prohibitted in `const fn`s. /// Only permitted in regular `fn`s, prohibited in `const fn`s.
General, General,
/// Permitted both in `const fn`s and regular `fn`s. /// Permitted both in `const fn`s and regular `fn`s.
GeneralAndConstFn, GeneralAndConstFn,
...@@ -35,13 +35,97 @@ pub enum UnsafetyViolationKind { ...@@ -35,13 +35,97 @@ pub enum UnsafetyViolationKind {
UnsafeFnBorrowPacked, UnsafeFnBorrowPacked,
} }
#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
pub enum UnsafetyViolationDetails {
CallToUnsafeFunction,
UseOfInlineAssembly,
InitializingTypeWith,
CastOfPointerToInt,
BorrowOfPackedField,
UseOfMutableStatic,
UseOfExternStatic,
DerefOfRawPointer,
AssignToNonCopyUnionField,
AccessToUnionField,
MutationOfLayoutConstrainedField,
BorrowOfLayoutConstrainedField,
CallToFunctionWith,
}
impl UnsafetyViolationDetails {
pub fn description_and_note(&self) -> (&'static str, &'static str) {
use UnsafetyViolationDetails::*;
match self {
CallToUnsafeFunction => (
"call to unsafe function",
"consult the function's documentation for information on how to avoid undefined \
behavior",
),
UseOfInlineAssembly => (
"use of inline assembly",
"inline assembly is entirely unchecked and can cause undefined behavior",
),
InitializingTypeWith => (
"initializing type with `rustc_layout_scalar_valid_range` attr",
"initializing a layout restricted type's field with a value outside the valid \
range is undefined behavior",
),
CastOfPointerToInt => {
("cast of pointer to int", "casting pointers to integers in constants")
}
BorrowOfPackedField => (
"borrow of packed field",
"fields of packed structs might be misaligned: dereferencing a misaligned pointer \
or even just creating a misaligned reference is undefined behavior",
),
UseOfMutableStatic => (
"use of mutable static",
"mutable statics can be mutated by multiple threads: aliasing violations or data \
races will cause undefined behavior",
),
UseOfExternStatic => (
"use of extern static",
"extern statics are not controlled by the Rust type system: invalid data, \
aliasing violations or data races will cause undefined behavior",
),
DerefOfRawPointer => (
"dereference of raw pointer",
"raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules \
and cause data races: all of these are undefined behavior",
),
AssignToNonCopyUnionField => (
"assignment to non-`Copy` union field",
"the previous content of the field will be dropped, which causes undefined \
behavior if the field was not properly initialized",
),
AccessToUnionField => (
"access to union field",
"the field may not be properly initialized: using uninitialized data will cause \
undefined behavior",
),
MutationOfLayoutConstrainedField => (
"mutation of layout constrained field",
"mutating layout constrained fields cannot statically be checked for valid values",
),
BorrowOfLayoutConstrainedField => (
"borrow of layout constrained field with interior mutability",
"references to fields of layout constrained fields lose the constraints. Coupled \
with interior mutability, the field can be changed to invalid values",
),
CallToFunctionWith => (
"call to function with `#[target_feature]`",
"can only be called if the required target features are available",
),
}
}
}
#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)] #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
pub struct UnsafetyViolation { pub struct UnsafetyViolation {
pub source_info: SourceInfo, pub source_info: SourceInfo,
pub lint_root: hir::HirId, pub lint_root: hir::HirId,
pub description: Symbol,
pub details: Symbol,
pub kind: UnsafetyViolationKind, pub kind: UnsafetyViolationKind,
pub details: UnsafetyViolationDetails,
} }
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
......
...@@ -1440,12 +1440,12 @@ fn path_append( ...@@ -1440,12 +1440,12 @@ fn path_append(
// FIXME(eddyb) `name` should never be empty, but it // FIXME(eddyb) `name` should never be empty, but it
// currently is for `extern { ... }` "foreign modules". // currently is for `extern { ... }` "foreign modules".
let name = disambiguated_data.data.as_symbol().as_str(); let name = disambiguated_data.data.as_symbol();
if !name.is_empty() { if name != kw::Invalid {
if !self.empty_path { if !self.empty_path {
write!(self, "::")?; write!(self, "::")?;
} }
if Ident::from_str(&name).is_raw_guess() { if Ident::with_dummy_span(name).is_raw_guess() {
write!(self, "r#")?; write!(self, "r#")?;
} }
write!(self, "{}", name)?; write!(self, "{}", name)?;
......
...@@ -60,12 +60,12 @@ fn def_id_to_string_id(&mut self, def_id: DefId) -> StringId { ...@@ -60,12 +60,12 @@ fn def_id_to_string_id(&mut self, def_id: DefId) -> StringId {
match def_key.disambiguated_data.data { match def_key.disambiguated_data.data {
DefPathData::CrateRoot => { DefPathData::CrateRoot => {
name = self.tcx.original_crate_name(def_id.krate).as_str(); name = self.tcx.original_crate_name(def_id.krate);
dis = ""; dis = "";
end_index = 3; end_index = 3;
} }
other => { other => {
name = other.as_symbol().as_str(); name = other.as_symbol();
if def_key.disambiguated_data.disambiguator == 0 { if def_key.disambiguated_data.disambiguator == 0 {
dis = ""; dis = "";
end_index = 3; end_index = 3;
...@@ -79,10 +79,11 @@ fn def_id_to_string_id(&mut self, def_id: DefId) -> StringId { ...@@ -79,10 +79,11 @@ fn def_id_to_string_id(&mut self, def_id: DefId) -> StringId {
} }
} }
let name = &*name.as_str();
let components = [ let components = [
StringComponent::Ref(parent_string_id), StringComponent::Ref(parent_string_id),
StringComponent::Value("::"), StringComponent::Value("::"),
StringComponent::Value(&name[..]), StringComponent::Value(name),
StringComponent::Value(dis), StringComponent::Value(dis),
]; ];
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint::builtin::{SAFE_PACKED_BORROWS, UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE}; use rustc_session::lint::builtin::{SAFE_PACKED_BORROWS, UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE};
use rustc_session::lint::Level; use rustc_session::lint::Level;
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::sym;
use std::ops::Bound; use std::ops::Bound;
...@@ -86,10 +86,8 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location ...@@ -86,10 +86,8 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
let sig = func_ty.fn_sig(self.tcx); let sig = func_ty.fn_sig(self.tcx);
if let hir::Unsafety::Unsafe = sig.unsafety() { if let hir::Unsafety::Unsafe = sig.unsafety() {
self.require_unsafe( self.require_unsafe(
"call to unsafe function",
"consult the function's documentation for information on how to avoid \
undefined behavior",
UnsafetyViolationKind::GeneralAndConstFn, UnsafetyViolationKind::GeneralAndConstFn,
UnsafetyViolationDetails::CallToUnsafeFunction,
) )
} }
...@@ -99,9 +97,8 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location ...@@ -99,9 +97,8 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
} }
TerminatorKind::InlineAsm { .. } => self.require_unsafe( TerminatorKind::InlineAsm { .. } => self.require_unsafe(
"use of inline assembly",
"inline assembly is entirely unchecked and can cause undefined behavior",
UnsafetyViolationKind::General, UnsafetyViolationKind::General,
UnsafetyViolationDetails::UseOfInlineAssembly,
), ),
} }
self.super_terminator(terminator, location); self.super_terminator(terminator, location);
...@@ -122,9 +119,8 @@ fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { ...@@ -122,9 +119,8 @@ fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
} }
StatementKind::LlvmInlineAsm { .. } => self.require_unsafe( StatementKind::LlvmInlineAsm { .. } => self.require_unsafe(
"use of inline assembly",
"inline assembly is entirely unchecked and can cause undefined behavior",
UnsafetyViolationKind::General, UnsafetyViolationKind::General,
UnsafetyViolationDetails::UseOfInlineAssembly,
), ),
} }
self.super_statement(statement, location); self.super_statement(statement, location);
...@@ -138,10 +134,8 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { ...@@ -138,10 +134,8 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
match self.tcx.layout_scalar_valid_range(def.did) { match self.tcx.layout_scalar_valid_range(def.did) {
(Bound::Unbounded, Bound::Unbounded) => {} (Bound::Unbounded, Bound::Unbounded) => {}
_ => self.require_unsafe( _ => self.require_unsafe(
"initializing type with `rustc_layout_scalar_valid_range` attr",
"initializing a layout restricted type's field with a value \
outside the valid range is undefined behavior",
UnsafetyViolationKind::GeneralAndConstFn, UnsafetyViolationKind::GeneralAndConstFn,
UnsafetyViolationDetails::InitializingTypeWith,
), ),
} }
} }
...@@ -163,9 +157,8 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { ...@@ -163,9 +157,8 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
match (cast_in, cast_out) { match (cast_in, cast_out) {
(CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) => { (CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) => {
self.require_unsafe( self.require_unsafe(
"cast of pointer to int",
"casting pointers to integers in constants",
UnsafetyViolationKind::General, UnsafetyViolationKind::General,
UnsafetyViolationDetails::CastOfPointerToInt,
); );
} }
_ => {} _ => {}
...@@ -190,11 +183,8 @@ fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: ...@@ -190,11 +183,8 @@ fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location:
if context.is_borrow() { if context.is_borrow() {
if util::is_disaligned(self.tcx, self.body, self.param_env, *place) { if util::is_disaligned(self.tcx, self.body, self.param_env, *place) {
self.require_unsafe( self.require_unsafe(
"borrow of packed field",
"fields of packed structs might be misaligned: dereferencing a \
misaligned pointer or even just creating a misaligned reference \
is undefined behavior",
UnsafetyViolationKind::BorrowPacked, UnsafetyViolationKind::BorrowPacked,
UnsafetyViolationDetails::BorrowOfPackedField,
); );
} }
} }
...@@ -204,11 +194,8 @@ fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: ...@@ -204,11 +194,8 @@ fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location:
if context.is_borrow() { if context.is_borrow() {
if util::is_disaligned(self.tcx, self.body, self.param_env, *place) { if util::is_disaligned(self.tcx, self.body, self.param_env, *place) {
self.require_unsafe( self.require_unsafe(
"borrow of packed field",
"fields of packed structs might be misaligned: dereferencing a \
misaligned pointer or even just creating a misaligned reference \
is undefined behavior",
UnsafetyViolationKind::BorrowPacked, UnsafetyViolationKind::BorrowPacked,
UnsafetyViolationDetails::BorrowOfPackedField,
); );
} }
} }
...@@ -219,19 +206,14 @@ fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: ...@@ -219,19 +206,14 @@ fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location:
if let Some(box LocalInfo::StaticRef { def_id, .. }) = decl.local_info { if let Some(box LocalInfo::StaticRef { def_id, .. }) = decl.local_info {
if self.tcx.is_mutable_static(def_id) { if self.tcx.is_mutable_static(def_id) {
self.require_unsafe( self.require_unsafe(
"use of mutable static",
"mutable statics can be mutated by multiple threads: aliasing \
violations or data races will cause undefined behavior",
UnsafetyViolationKind::General, UnsafetyViolationKind::General,
UnsafetyViolationDetails::UseOfMutableStatic,
); );
return; return;
} else if self.tcx.is_foreign_item(def_id) { } else if self.tcx.is_foreign_item(def_id) {
self.require_unsafe( self.require_unsafe(
"use of extern static",
"extern statics are not controlled by the Rust type system: \
invalid data, aliasing violations or data races will cause \
undefined behavior",
UnsafetyViolationKind::General, UnsafetyViolationKind::General,
UnsafetyViolationDetails::UseOfExternStatic,
); );
return; return;
} }
...@@ -246,11 +228,8 @@ fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: ...@@ -246,11 +228,8 @@ fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location:
let base_ty = Place::ty_from(place.local, proj_base, self.body, self.tcx).ty; let base_ty = Place::ty_from(place.local, proj_base, self.body, self.tcx).ty;
match base_ty.kind { match base_ty.kind {
ty::RawPtr(..) => self.require_unsafe( ty::RawPtr(..) => self.require_unsafe(
"dereference of raw pointer",
"raw pointers may be NULL, dangling or unaligned; they can violate \
aliasing rules and cause data races: all of these are undefined \
behavior",
UnsafetyViolationKind::General, UnsafetyViolationKind::General,
UnsafetyViolationDetails::DerefOfRawPointer,
), ),
ty::Adt(adt, _) => { ty::Adt(adt, _) => {
if adt.is_union() { if adt.is_union() {
...@@ -271,21 +250,16 @@ fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: ...@@ -271,21 +250,16 @@ fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location:
self.param_env, self.param_env,
) { ) {
self.require_unsafe( self.require_unsafe(
"assignment to non-`Copy` union field",
"the previous content of the field will be dropped, which \
causes undefined behavior if the field was not properly \
initialized",
UnsafetyViolationKind::GeneralAndConstFn, UnsafetyViolationKind::GeneralAndConstFn,
UnsafetyViolationDetails::AssignToNonCopyUnionField,
) )
} else { } else {
// write to non-move union, safe // write to non-move union, safe
} }
} else { } else {
self.require_unsafe( self.require_unsafe(
"access to union field",
"the field may not be properly initialized: using \
uninitialized data will cause undefined behavior",
UnsafetyViolationKind::GeneralAndConstFn, UnsafetyViolationKind::GeneralAndConstFn,
UnsafetyViolationDetails::AccessToUnionField,
) )
} }
} }
...@@ -298,12 +272,7 @@ fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: ...@@ -298,12 +272,7 @@ fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location:
} }
impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
fn require_unsafe( fn require_unsafe(&mut self, kind: UnsafetyViolationKind, details: UnsafetyViolationDetails) {
&mut self,
description: &'static str,
details: &'static str,
kind: UnsafetyViolationKind,
) {
let source_info = self.source_info; let source_info = self.source_info;
let lint_root = self.body.source_scopes[self.source_info.scope] let lint_root = self.body.source_scopes[self.source_info.scope]
.local_data .local_data
...@@ -311,13 +280,7 @@ fn require_unsafe( ...@@ -311,13 +280,7 @@ fn require_unsafe(
.assert_crate_local() .assert_crate_local()
.lint_root; .lint_root;
self.register_violations( self.register_violations(
&[UnsafetyViolation { &[UnsafetyViolation { source_info, lint_root, kind, details }],
source_info,
lint_root,
description: Symbol::intern(description),
details: Symbol::intern(details),
kind,
}],
&[], &[],
); );
} }
...@@ -434,12 +397,8 @@ fn check_mut_borrowing_layout_constrained_field( ...@@ -434,12 +397,8 @@ fn check_mut_borrowing_layout_constrained_field(
if self.tcx.layout_scalar_valid_range(def.did) if self.tcx.layout_scalar_valid_range(def.did)
!= (Bound::Unbounded, Bound::Unbounded) != (Bound::Unbounded, Bound::Unbounded)
{ {
let (description, details) = if is_mut_use { let details = if is_mut_use {
( UnsafetyViolationDetails::MutationOfLayoutConstrainedField
"mutation of layout constrained field",
"mutating layout constrained fields cannot statically be \
checked for valid values",
)
// Check `is_freeze` as late as possible to avoid cycle errors // Check `is_freeze` as late as possible to avoid cycle errors
// with opaque types. // with opaque types.
...@@ -448,21 +407,11 @@ fn check_mut_borrowing_layout_constrained_field( ...@@ -448,21 +407,11 @@ fn check_mut_borrowing_layout_constrained_field(
.ty .ty
.is_freeze(self.tcx.at(self.source_info.span), self.param_env) .is_freeze(self.tcx.at(self.source_info.span), self.param_env)
{ {
( UnsafetyViolationDetails::BorrowOfLayoutConstrainedField
"borrow of layout constrained field with interior \
mutability",
"references to fields of layout constrained fields \
lose the constraints. Coupled with interior mutability, \
the field can be changed to invalid values",
)
} else { } else {
continue; continue;
}; };
self.require_unsafe( self.require_unsafe(UnsafetyViolationKind::GeneralAndConstFn, details);
description,
details,
UnsafetyViolationKind::GeneralAndConstFn,
);
} }
} }
} }
...@@ -480,9 +429,8 @@ fn check_target_features(&mut self, func_did: DefId) { ...@@ -480,9 +429,8 @@ fn check_target_features(&mut self, func_did: DefId) {
// Is `callee_features` a subset of `calling_features`? // Is `callee_features` a subset of `calling_features`?
if !callee_features.iter().all(|feature| self_features.contains(feature)) { if !callee_features.iter().all(|feature| self_features.contains(feature)) {
self.require_unsafe( self.require_unsafe(
"call to function with `#[target_feature]`",
"can only be called if the required target features are available",
UnsafetyViolationKind::GeneralAndConstFn, UnsafetyViolationKind::GeneralAndConstFn,
UnsafetyViolationDetails::CallToFunctionWith,
) )
} }
} }
...@@ -675,9 +623,9 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { ...@@ -675,9 +623,9 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) {
let UnsafetyCheckResult { violations, unsafe_blocks } = tcx.unsafety_check_result(def_id); let UnsafetyCheckResult { violations, unsafe_blocks } = tcx.unsafety_check_result(def_id);
for &UnsafetyViolation { source_info, lint_root, description, details, kind } in for &UnsafetyViolation { source_info, lint_root, kind, details } in violations.iter() {
violations.iter() let (description, note) = details.description_and_note();
{
// Report an error. // Report an error.
let unsafe_fn_msg = let unsafe_fn_msg =
if unsafe_op_in_unsafe_fn_allowed(tcx, lint_root) { " function or" } else { "" }; if unsafe_op_in_unsafe_fn_allowed(tcx, lint_root) { " function or" } else { "" };
...@@ -693,8 +641,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { ...@@ -693,8 +641,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) {
description, description,
unsafe_fn_msg, unsafe_fn_msg,
) )
.span_label(source_info.span, &*description.as_str()) .span_label(source_info.span, description)
.note(&details.as_str()) .note(note)
.emit(); .emit();
} }
UnsafetyViolationKind::BorrowPacked => { UnsafetyViolationKind::BorrowPacked => {
...@@ -712,7 +660,7 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { ...@@ -712,7 +660,7 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) {
"{} is unsafe and requires unsafe{} block (error E0133)", "{} is unsafe and requires unsafe{} block (error E0133)",
description, unsafe_fn_msg, description, unsafe_fn_msg,
)) ))
.note(&details.as_str()) .note(note)
.emit() .emit()
}, },
) )
...@@ -727,8 +675,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { ...@@ -727,8 +675,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) {
"{} is unsafe and requires unsafe block (error E0133)", "{} is unsafe and requires unsafe block (error E0133)",
description, description,
)) ))
.span_label(source_info.span, &*description.as_str()) .span_label(source_info.span, description)
.note(&details.as_str()) .note(note)
.emit(); .emit();
}, },
), ),
...@@ -756,8 +704,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { ...@@ -756,8 +704,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) {
"{} is unsafe and requires unsafe block (error E0133)", "{} is unsafe and requires unsafe block (error E0133)",
description, description,
)) ))
.span_label(source_info.span, &*description.as_str()) .span_label(source_info.span, description)
.note(&details.as_str()) .note(note)
.emit(); .emit();
}) })
} }
......
...@@ -122,19 +122,28 @@ ...@@ -122,19 +122,28 @@
// There is currently no checking that all symbols are used; that would be // There is currently no checking that all symbols are used; that would be
// nice to have. // nice to have.
Symbols { Symbols {
Alignment,
Arc, Arc,
Argument,
ArgumentV1, ArgumentV1,
Arguments, Arguments,
C, C,
Center,
Clone, Clone,
Copy, Copy,
Count,
Debug, Debug,
Decodable, Decodable,
Decoder,
Default, Default,
Encodable, Encodable,
Encoder,
Eq, Eq,
Equal, Equal,
Err, Err,
Error,
FormatSpec,
Formatter,
From, From,
Future, Future,
FxHashMap, FxHashMap,
...@@ -143,11 +152,15 @@ ...@@ -143,11 +152,15 @@
Hash, Hash,
HashMap, HashMap,
HashSet, HashSet,
Hasher,
Implied,
Input, Input,
IntoIterator, IntoIterator,
Is,
ItemContext, ItemContext,
Iterator, Iterator,
Layout, Layout,
Left,
LintPass, LintPass,
None, None,
Ok, Ok,
...@@ -155,11 +168,13 @@ ...@@ -155,11 +168,13 @@
Ord, Ord,
Ordering, Ordering,
Output, Output,
Param,
PartialEq, PartialEq,
PartialOrd, PartialOrd,
Pending, Pending,
Pin, Pin,
Poll, Poll,
ProcMacro,
ProcMacroHack, ProcMacroHack,
ProceduralMasqueradeDummyType, ProceduralMasqueradeDummyType,
Range, Range,
...@@ -172,20 +187,31 @@ ...@@ -172,20 +187,31 @@
Ready, Ready,
Result, Result,
Return, Return,
Right,
RustcDecodable, RustcDecodable,
RustcEncodable, RustcEncodable,
Send, Send,
Some, Some,
StructuralEq,
StructuralPartialEq,
Sync, Sync,
Target, Target,
Try, Try,
Ty, Ty,
TyCtxt, TyCtxt,
TyKind, TyKind,
Unknown,
Vec, Vec,
Yield, Yield,
_DECLS,
_Self, _Self,
__D,
__H,
__S,
__next, __next,
__try_var,
_d,
_e,
_task_context, _task_context,
aarch64_target_feature, aarch64_target_feature,
abi, abi,
...@@ -226,6 +252,7 @@ ...@@ -226,6 +252,7 @@
allowed, allowed,
always, always,
and, and,
and_then,
any, any,
arbitrary_enum_discriminant, arbitrary_enum_discriminant,
arbitrary_self_types, arbitrary_self_types,
...@@ -256,6 +283,7 @@ ...@@ -256,6 +283,7 @@
automatically_derived, automatically_derived,
avx512_target_feature, avx512_target_feature,
await_macro, await_macro,
bang,
begin_panic, begin_panic,
bench, bench,
bin, bin,
...@@ -278,6 +306,7 @@ ...@@ -278,6 +306,7 @@
box_syntax, box_syntax,
braced_empty_structs, braced_empty_structs,
breakpoint, breakpoint,
bridge,
bswap, bswap,
c_variadic, c_variadic,
call, call,
...@@ -299,6 +328,7 @@ ...@@ -299,6 +328,7 @@
cfg_target_vendor, cfg_target_vendor,
cfg_version, cfg_version,
char, char,
client,
clippy, clippy,
clone, clone,
clone_closures, clone_closures,
...@@ -370,11 +400,15 @@ ...@@ -370,11 +400,15 @@
custom_derive, custom_derive,
custom_inner_attributes, custom_inner_attributes,
custom_test_frameworks, custom_test_frameworks,
d,
dead_code, dead_code,
dealloc, dealloc,
debug, debug,
debug_assertions, debug_assertions,
debug_struct,
debug_trait, debug_trait,
debug_trait_builder,
debug_tuple,
decl_macro, decl_macro,
declare_lint_pass, declare_lint_pass,
decode, decode,
...@@ -421,6 +455,11 @@ ...@@ -421,6 +455,11 @@
dyn_trait, dyn_trait,
eh_catch_typeinfo, eh_catch_typeinfo,
eh_personality, eh_personality,
emit_enum,
emit_enum_variant,
emit_enum_variant_arg,
emit_struct,
emit_struct_field,
enable, enable,
enclosing_scope, enclosing_scope,
encode, encode,
...@@ -448,6 +487,7 @@ ...@@ -448,6 +487,7 @@
extern_prelude, extern_prelude,
extern_types, extern_types,
external_doc, external_doc,
f,
f16c_target_feature, f16c_target_feature,
f32, f32,
f32_runtime, f32_runtime,
...@@ -464,6 +504,9 @@ ...@@ -464,6 +504,9 @@
field, field,
field_init_shorthand, field_init_shorthand,
file, file,
fill,
finish,
flags,
float_to_int_unchecked, float_to_int_unchecked,
floorf32, floorf32,
floorf64, floorf64,
...@@ -478,6 +521,7 @@ ...@@ -478,6 +521,7 @@
fn_once_output, fn_once_output,
forbid, forbid,
forget, forget,
format,
format_args, format_args,
format_args_capture, format_args_capture,
format_args_nl, format_args_nl,
...@@ -519,6 +563,7 @@ ...@@ -519,6 +563,7 @@
html_no_source, html_no_source,
html_playground_url, html_playground_url,
html_root_url, html_root_url,
i,
i128, i128,
i128_type, i128_type,
i16, i16,
...@@ -606,6 +651,7 @@ ...@@ -606,6 +651,7 @@
main, main,
managed_boxes, managed_boxes,
manually_drop, manually_drop,
map,
marker, marker,
marker_trait_attr, marker_trait_attr,
masked, masked,
...@@ -708,6 +754,7 @@ ...@@ -708,6 +754,7 @@
options, options,
or, or,
or_patterns, or_patterns,
other,
out, out,
overlapping_marker_traits, overlapping_marker_traits,
owned_box, owned_box,
...@@ -739,6 +786,7 @@ ...@@ -739,6 +786,7 @@
plugins, plugins,
pointer, pointer,
poll, poll,
position,
post_dash_lto: "post-lto", post_dash_lto: "post-lto",
powerpc_target_feature, powerpc_target_feature,
powf32, powf32,
...@@ -747,6 +795,7 @@ ...@@ -747,6 +795,7 @@
powif64, powif64,
pre_dash_lto: "pre-lto", pre_dash_lto: "pre-lto",
precise_pointer_size_matching, precise_pointer_size_matching,
precision,
pref_align_of, pref_align_of,
prefetch_read_data, prefetch_read_data,
prefetch_read_instruction, prefetch_read_instruction,
...@@ -783,6 +832,11 @@ ...@@ -783,6 +832,11 @@
raw_identifiers, raw_identifiers,
raw_ref_op, raw_ref_op,
re_rebalance_coherence, re_rebalance_coherence,
read_enum,
read_enum_variant,
read_enum_variant_arg,
read_struct,
read_struct_field,
readonly, readonly,
realloc, realloc,
reason, reason,
...@@ -872,6 +926,7 @@ ...@@ -872,6 +926,7 @@
rustc_promotable, rustc_promotable,
rustc_regions, rustc_regions,
rustc_reservation_impl, rustc_reservation_impl,
rustc_serialize,
rustc_specialization_trait, rustc_specialization_trait,
rustc_stable, rustc_stable,
rustc_std_internal_symbol, rustc_std_internal_symbol,
...@@ -976,6 +1031,7 @@ ...@@ -976,6 +1031,7 @@
stable, stable,
staged_api, staged_api,
start, start,
state,
static_in_const, static_in_const,
static_nobundle, static_nobundle,
static_recursion, static_recursion,
...@@ -1123,6 +1179,7 @@ ...@@ -1123,6 +1179,7 @@
wasm_import_module, wasm_import_module,
wasm_target_feature, wasm_target_feature,
while_let, while_let,
width,
windows, windows,
windows_subsystem, windows_subsystem,
wrapping_add, wrapping_add,
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
TypeFoldable, WithConstness, TypeFoldable, WithConstness,
}; };
use rustc_session::DiagnosticMessageId; use rustc_session::DiagnosticMessageId;
use rustc_span::symbol::sym; use rustc_span::symbol::{kw, sym};
use rustc_span::{ExpnKind, MultiSpan, Span, DUMMY_SP}; use rustc_span::{ExpnKind, MultiSpan, Span, DUMMY_SP};
use std::fmt; use std::fmt;
...@@ -1524,7 +1524,7 @@ fn maybe_report_ambiguity( ...@@ -1524,7 +1524,7 @@ fn maybe_report_ambiguity(
(self.tcx.sess.source_map().span_to_snippet(span), &obligation.cause.code) (self.tcx.sess.source_map().span_to_snippet(span), &obligation.cause.code)
{ {
let generics = self.tcx.generics_of(*def_id); let generics = self.tcx.generics_of(*def_id);
if generics.params.iter().any(|p| p.name.as_str() != "Self") if generics.params.iter().any(|p| p.name != kw::SelfUpper)
&& !snippet.ends_with('>') && !snippet.ends_with('>')
{ {
// FIXME: To avoid spurious suggestions in functions where type arguments // FIXME: To avoid spurious suggestions in functions where type arguments
......
...@@ -322,12 +322,12 @@ fn can_use_as_ref(&self, expr: &hir::Expr<'_>) -> Option<(Span, &'static str, St ...@@ -322,12 +322,12 @@ fn can_use_as_ref(&self, expr: &hir::Expr<'_>) -> Option<(Span, &'static str, St
let self_ty = self.tables.borrow().node_type(method_expr[0].hir_id); let self_ty = self.tables.borrow().node_type(method_expr[0].hir_id);
let self_ty = format!("{:?}", self_ty); let self_ty = format!("{:?}", self_ty);
let name = method_path.ident.as_str(); let name = method_path.ident.name;
let is_as_ref_able = (self_ty.starts_with("&std::option::Option") let is_as_ref_able = (self_ty.starts_with("&std::option::Option")
|| self_ty.starts_with("&std::result::Result") || self_ty.starts_with("&std::result::Result")
|| self_ty.starts_with("std::option::Option") || self_ty.starts_with("std::option::Option")
|| self_ty.starts_with("std::result::Result")) || self_ty.starts_with("std::result::Result"))
&& (name == "map" || name == "and_then"); && (name == sym::map || name == sym::and_then);
match (is_as_ref_able, self.sess().source_map().span_to_snippet(*method_span)) { match (is_as_ref_able, self.sess().source_map().span_to_snippet(*method_span)) {
(true, Ok(src)) => { (true, Ok(src)) => {
let suggestion = format!("as_ref().{}", src); let suggestion = format!("as_ref().{}", src);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
use rustc_span::symbol::{Ident, SymbolStr}; use rustc_span::symbol::{Ident, Symbol};
use std::cmp::Ordering; use std::cmp::Ordering;
declare_clippy_lint! { declare_clippy_lint! {
...@@ -75,7 +75,7 @@ pub struct NonExpressiveNames { ...@@ -75,7 +75,7 @@ pub struct NonExpressiveNames {
impl_lint_pass!(NonExpressiveNames => [SIMILAR_NAMES, MANY_SINGLE_CHAR_NAMES, JUST_UNDERSCORES_AND_DIGITS]); impl_lint_pass!(NonExpressiveNames => [SIMILAR_NAMES, MANY_SINGLE_CHAR_NAMES, JUST_UNDERSCORES_AND_DIGITS]);
struct ExistingName { struct ExistingName {
interned: SymbolStr, interned: Symbol,
span: Span, span: Span,
len: usize, len: usize,
exemptions: &'static [&'static str], exemptions: &'static [&'static str],
...@@ -218,18 +218,19 @@ fn check_ident(&mut self, ident: Ident) { ...@@ -218,18 +218,19 @@ fn check_ident(&mut self, ident: Ident) {
let mut split_at = None; let mut split_at = None;
match existing_name.len.cmp(&count) { match existing_name.len.cmp(&count) {
Ordering::Greater => { Ordering::Greater => {
if existing_name.len - count != 1 || levenstein_not_1(&interned_name, &existing_name.interned) { if existing_name.len - count != 1 || levenstein_not_1(&interned_name, &existing_name.interned.as_str()) {
continue; continue;
} }
}, },
Ordering::Less => { Ordering::Less => {
if count - existing_name.len != 1 || levenstein_not_1(&existing_name.interned, &interned_name) { if count - existing_name.len != 1 || levenstein_not_1(&existing_name.interned.as_str(), &interned_name) {
continue; continue;
} }
}, },
Ordering::Equal => { Ordering::Equal => {
let mut interned_chars = interned_name.chars(); let mut interned_chars = interned_name.chars();
let mut existing_chars = existing_name.interned.chars(); let interned_str = existing_name.interned.as_str();
let mut existing_chars = interned_str.chars();
let first_i = interned_chars.next().expect("we know we have at least one char"); let first_i = interned_chars.next().expect("we know we have at least one char");
let first_e = existing_chars.next().expect("we know we have at least one char"); let first_e = existing_chars.next().expect("we know we have at least one char");
let eq_or_numeric = |(a, b): (char, char)| a == b || a.is_numeric() && b.is_numeric(); let eq_or_numeric = |(a, b): (char, char)| a == b || a.is_numeric() && b.is_numeric();
...@@ -302,7 +303,7 @@ fn check_ident(&mut self, ident: Ident) { ...@@ -302,7 +303,7 @@ fn check_ident(&mut self, ident: Ident) {
} }
self.0.names.push(ExistingName { self.0.names.push(ExistingName {
exemptions: get_exemptions(&interned_name).unwrap_or(&[]), exemptions: get_exemptions(&interned_name).unwrap_or(&[]),
interned: interned_name, interned: ident.name,
span: ident.span, span: ident.span,
len: count, len: count,
}); });
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
use rustc_span::symbol::{Ident, SymbolStr}; use rustc_span::symbol::Ident;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for imports that remove "unsafe" from an item's /// **What it does:** Checks for imports that remove "unsafe" from an item's
...@@ -73,6 +73,6 @@ fn unsafe_to_safe_check(old_name: Ident, new_name: Ident, cx: &EarlyContext<'_>, ...@@ -73,6 +73,6 @@ fn unsafe_to_safe_check(old_name: Ident, new_name: Ident, cx: &EarlyContext<'_>,
} }
#[must_use] #[must_use]
fn contains_unsafe(name: &SymbolStr) -> bool { fn contains_unsafe(name: &str) -> bool {
name.contains("Unsafe") || name.contains("unsafe") name.contains("Unsafe") || name.contains("unsafe")
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册