1
Fork 0

Add and use more static symbols.

Note that the output of `unpretty-debug.stdout` has changed. In that
test the hash values are normalized from a symbol numbers to small
numbers like "0#0" and "0#1". The increase in the number of static
symbols must have caused the original numbers to contain more digits,
resulting in different pretty-printing prior to normalization.
This commit is contained in:
Nicholas Nethercote 2020-07-08 11:04:10 +10:00
parent e284f5d050
commit f04e866e57
44 changed files with 785 additions and 570 deletions

View file

@ -9,7 +9,7 @@ pub enum AllocatorKind {
} }
impl AllocatorKind { impl AllocatorKind {
pub fn fn_name(&self, base: &str) -> String { pub fn fn_name(&self, base: Symbol) -> String {
match *self { match *self {
AllocatorKind::Global => format!("__rg_{}", base), AllocatorKind::Global => format!("__rg_{}", base),
AllocatorKind::Default => format!("__rdl_{}", base), AllocatorKind::Default => format!("__rdl_{}", base),
@ -26,29 +26,29 @@ pub enum AllocatorTy {
} }
pub struct AllocatorMethod { pub struct AllocatorMethod {
pub name: &'static str, pub name: Symbol,
pub inputs: &'static [AllocatorTy], pub inputs: &'static [AllocatorTy],
pub output: AllocatorTy, pub output: AllocatorTy,
} }
pub static ALLOCATOR_METHODS: &[AllocatorMethod] = &[ pub static ALLOCATOR_METHODS: &[AllocatorMethod] = &[
AllocatorMethod { AllocatorMethod {
name: "alloc", name: sym::alloc,
inputs: &[AllocatorTy::Layout], inputs: &[AllocatorTy::Layout],
output: AllocatorTy::ResultPtr, output: AllocatorTy::ResultPtr,
}, },
AllocatorMethod { AllocatorMethod {
name: "dealloc", name: sym::dealloc,
inputs: &[AllocatorTy::Ptr, AllocatorTy::Layout], inputs: &[AllocatorTy::Ptr, AllocatorTy::Layout],
output: AllocatorTy::Unit, output: AllocatorTy::Unit,
}, },
AllocatorMethod { AllocatorMethod {
name: "realloc", name: sym::realloc,
inputs: &[AllocatorTy::Ptr, AllocatorTy::Layout, AllocatorTy::Usize], inputs: &[AllocatorTy::Ptr, AllocatorTy::Layout, AllocatorTy::Usize],
output: AllocatorTy::ResultPtr, output: AllocatorTy::ResultPtr,
}, },
AllocatorMethod { AllocatorMethod {
name: "alloc_zeroed", name: sym::alloc_zeroed,
inputs: &[AllocatorTy::Layout], inputs: &[AllocatorTy::Layout],
output: AllocatorTy::ResultPtr, output: AllocatorTy::ResultPtr,
}, },
@ -70,7 +70,7 @@ pub fn global_allocator_spans(krate: &ast::Crate) -> Vec<Span> {
} }
} }
let name = Symbol::intern(&AllocatorKind::Global.fn_name("alloc")); let name = Symbol::intern(&AllocatorKind::Global.fn_name(sym::alloc));
let mut f = Finder { name, spans: Vec::new() }; let mut f = Finder { name, spans: Vec::new() };
visit::walk_crate(&mut f, krate); visit::walk_crate(&mut f, krate);
f.spans f.spans

View file

@ -1041,10 +1041,10 @@ pub fn find_transparency(
break; break;
} else if let Some(value) = attr.value_str() { } else if let Some(value) = attr.value_str() {
transparency = Some(( transparency = Some((
match &*value.as_str() { match value {
"transparent" => Transparency::Transparent, sym::transparent => Transparency::Transparent,
"semitransparent" => Transparency::SemiTransparent, sym::semitransparent => Transparency::SemiTransparent,
"opaque" => Transparency::Opaque, sym::opaque => Transparency::Opaque,
_ => { _ => {
error = Some(TransparencyError::UnknownTransparency(value, attr.span)); error = Some(TransparencyError::UnknownTransparency(value, attr.span));
continue; continue;

View file

@ -84,7 +84,7 @@ pub fn expand_deriving_clone(
is_unsafe: false, is_unsafe: false,
supports_unions: true, supports_unions: true,
methods: vec![MethodDef { methods: vec![MethodDef {
name: "clone", name: sym::clone,
generics: LifetimeBounds::empty(), generics: LifetimeBounds::empty(),
explicit_self: borrowed_explicit_self(), explicit_self: borrowed_explicit_self(),
args: Vec::new(), args: Vec::new(),

View file

@ -28,7 +28,7 @@ pub fn expand_deriving_eq(
is_unsafe: false, is_unsafe: false,
supports_unions: true, supports_unions: true,
methods: vec![MethodDef { methods: vec![MethodDef {
name: "assert_receiver_is_total_eq", name: sym::assert_receiver_is_total_eq,
generics: LifetimeBounds::empty(), generics: LifetimeBounds::empty(),
explicit_self: borrowed_explicit_self(), explicit_self: borrowed_explicit_self(),
args: vec![], args: vec![],

View file

@ -26,7 +26,7 @@ pub fn expand_deriving_ord(
is_unsafe: false, is_unsafe: false,
supports_unions: false, supports_unions: false,
methods: vec![MethodDef { methods: vec![MethodDef {
name: "cmp", name: sym::cmp,
generics: LifetimeBounds::empty(), generics: LifetimeBounds::empty(),
explicit_self: borrowed_explicit_self(), explicit_self: borrowed_explicit_self(),
args: vec![(borrowed_self(), "other")], args: vec![(borrowed_self(), "other")],

View file

@ -92,9 +92,9 @@ pub fn expand_deriving_partial_eq(
// avoid defining `ne` if we can // avoid defining `ne` if we can
// c-like enums, enums without any fields and structs without fields // c-like enums, enums without any fields and structs without fields
// can safely define only `eq`. // can safely define only `eq`.
let mut methods = vec![md!("eq", cs_eq)]; let mut methods = vec![md!(sym::eq, cs_eq)];
if !is_type_without_fields(item) { if !is_type_without_fields(item) {
methods.push(md!("ne", cs_ne)); methods.push(md!(sym::ne, cs_ne));
} }
let trait_def = TraitDef { let trait_def = TraitDef {

View file

@ -49,7 +49,7 @@ pub fn expand_deriving_partial_ord(
let attrs = vec![cx.attribute(inline)]; let attrs = vec![cx.attribute(inline)];
let partial_cmp_def = MethodDef { let partial_cmp_def = MethodDef {
name: "partial_cmp", name: sym::partial_cmp,
generics: LifetimeBounds::empty(), generics: LifetimeBounds::empty(),
explicit_self: borrowed_explicit_self(), explicit_self: borrowed_explicit_self(),
args: vec![(borrowed_self(), "other")], args: vec![(borrowed_self(), "other")],
@ -70,10 +70,10 @@ pub fn expand_deriving_partial_ord(
} else { } else {
vec![ vec![
partial_cmp_def, partial_cmp_def,
md!("lt", true, false), md!(sym::lt, true, false),
md!("le", true, true), md!(sym::le, true, true),
md!("gt", false, false), md!(sym::gt, false, false),
md!("ge", false, true), md!(sym::ge, false, true),
] ]
}; };
@ -108,14 +108,14 @@ pub fn some_ordering_collapsed(
) -> P<ast::Expr> { ) -> P<ast::Expr> {
let lft = cx.expr_ident(span, self_arg_tags[0]); let lft = cx.expr_ident(span, self_arg_tags[0]);
let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1])); let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
let op_str = match op { let op_sym = match op {
PartialCmpOp => "partial_cmp", PartialCmpOp => sym::partial_cmp,
LtOp => "lt", LtOp => sym::lt,
LeOp => "le", LeOp => sym::le,
GtOp => "gt", GtOp => sym::gt,
GeOp => "ge", GeOp => sym::ge,
}; };
cx.expr_method_call(span, lft, cx.ident_of(op_str, span), vec![rgt]) cx.expr_method_call(span, lft, Ident::new(op_sym, span), vec![rgt])
} }
pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> { pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> {

View file

@ -29,7 +29,7 @@ pub fn expand_deriving_debug(
is_unsafe: false, is_unsafe: false,
supports_unions: false, supports_unions: false,
methods: vec![MethodDef { methods: vec![MethodDef {
name: "fmt", name: sym::fmt,
generics: LifetimeBounds::empty(), generics: LifetimeBounds::empty(),
explicit_self: borrowed_explicit_self(), explicit_self: borrowed_explicit_self(),
args: vec![(fmtr, "f")], args: vec![(fmtr, "f")],

View file

@ -8,7 +8,7 @@ use rustc_ast::ast;
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::Symbol; use rustc_span::symbol::{sym, Symbol};
use rustc_span::Span; use rustc_span::Span;
pub fn expand_deriving_rustc_decodable( pub fn expand_deriving_rustc_decodable(
@ -30,7 +30,7 @@ pub fn expand_deriving_rustc_decodable(
is_unsafe: false, is_unsafe: false,
supports_unions: false, supports_unions: false,
methods: vec![MethodDef { methods: vec![MethodDef {
name: "decode", name: sym::decode,
generics: LifetimeBounds { generics: LifetimeBounds {
lifetimes: Vec::new(), lifetimes: Vec::new(),
bounds: vec![( bounds: vec![(

View file

@ -27,7 +27,7 @@ pub fn expand_deriving_default(
is_unsafe: false, is_unsafe: false,
supports_unions: false, supports_unions: false,
methods: vec![MethodDef { methods: vec![MethodDef {
name: "default", name: kw::Default,
generics: LifetimeBounds::empty(), generics: LifetimeBounds::empty(),
explicit_self: None, explicit_self: None,
args: Vec::new(), args: Vec::new(),

View file

@ -92,7 +92,7 @@ use crate::deriving::pathvec_std;
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::Symbol; use rustc_span::symbol::{sym, Symbol};
use rustc_span::Span; use rustc_span::Span;
pub fn expand_deriving_rustc_encodable( pub fn expand_deriving_rustc_encodable(
@ -114,7 +114,7 @@ pub fn expand_deriving_rustc_encodable(
is_unsafe: false, is_unsafe: false,
supports_unions: false, supports_unions: false,
methods: vec![MethodDef { methods: vec![MethodDef {
name: "encode", name: sym::encode,
generics: LifetimeBounds { generics: LifetimeBounds {
lifetimes: Vec::new(), lifetimes: Vec::new(),
bounds: vec![( bounds: vec![(

View file

@ -226,7 +226,7 @@ pub struct TraitDef<'a> {
pub struct MethodDef<'a> { pub struct MethodDef<'a> {
/// name of the method /// name of the method
pub name: &'a str, 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: LifetimeBounds<'a>,
@ -681,7 +681,7 @@ impl<'a> TraitDef<'a> {
let opt_trait_ref = Some(trait_ref); let opt_trait_ref = Some(trait_ref);
let unused_qual = { let unused_qual = {
let word = rustc_ast::attr::mk_nested_word_item(Ident::new( let word = rustc_ast::attr::mk_nested_word_item(Ident::new(
Symbol::intern("unused_qualifications"), sym::unused_qualifications,
self.span, self.span,
)); ));
let list = rustc_ast::attr::mk_list_item(Ident::new(sym::allow, self.span), vec![word]); let list = rustc_ast::attr::mk_list_item(Ident::new(sym::allow, self.span), vec![word]);
@ -818,7 +818,7 @@ impl<'a> MethodDef<'a> {
) -> P<Expr> { ) -> P<Expr> {
let substructure = Substructure { let substructure = Substructure {
type_ident, type_ident,
method_ident: cx.ident_of(self.name, trait_.span), method_ident: Ident::new(self.name, trait_.span),
self_args, self_args,
nonself_args, nonself_args,
fields, fields,
@ -913,7 +913,7 @@ impl<'a> MethodDef<'a> {
let ret_type = self.get_ret_ty(cx, trait_, generics, type_ident); let ret_type = self.get_ret_ty(cx, trait_, generics, type_ident);
let method_ident = cx.ident_of(self.name, trait_.span); let method_ident = Ident::new(self.name, trait_.span);
let fn_decl = cx.fn_decl(args, ast::FnRetTy::Ty(ret_type)); let fn_decl = cx.fn_decl(args, ast::FnRetTy::Ty(ret_type));
let body_block = cx.block_expr(body); let body_block = cx.block_expr(body);
@ -1315,7 +1315,7 @@ impl<'a> MethodDef<'a> {
// Since we know that all the arguments will match if we reach // Since we know that all the arguments will match if we reach
// the match expression we add the unreachable intrinsics as the // the match expression we add the unreachable intrinsics as the
// result of the catch all which should help llvm in optimizing it // result of the catch all which should help llvm in optimizing it
Some(deriving::call_intrinsic(cx, sp, "unreachable", vec![])) Some(deriving::call_intrinsic(cx, sp, sym::unreachable, vec![]))
} }
_ => None, _ => None,
}; };
@ -1363,7 +1363,7 @@ impl<'a> MethodDef<'a> {
for (&ident, self_arg) in vi_idents.iter().zip(&self_args) { for (&ident, self_arg) in vi_idents.iter().zip(&self_args) {
let self_addr = cx.expr_addr_of(sp, self_arg.clone()); let self_addr = cx.expr_addr_of(sp, self_arg.clone());
let variant_value = let variant_value =
deriving::call_intrinsic(cx, sp, "discriminant_value", vec![self_addr]); deriving::call_intrinsic(cx, sp, sym::discriminant_value, vec![self_addr]);
let let_stmt = cx.stmt_let(sp, false, ident, variant_value); let let_stmt = cx.stmt_let(sp, false, ident, variant_value);
index_let_stmts.push(let_stmt); index_let_stmts.push(let_stmt);
@ -1464,7 +1464,7 @@ impl<'a> MethodDef<'a> {
// derive Debug on such a type could here generate code // derive Debug on such a type could here generate code
// that needs the feature gate enabled.) // that needs the feature gate enabled.)
deriving::call_intrinsic(cx, sp, "unreachable", vec![]) deriving::call_intrinsic(cx, sp, sym::unreachable, vec![])
} else { } else {
// Final wrinkle: the self_args are expressions that deref // Final wrinkle: the self_args are expressions that deref
// down to desired places, but we cannot actually deref // down to desired places, but we cannot actually deref

View file

@ -29,7 +29,7 @@ pub fn expand_deriving_hash(
is_unsafe: false, is_unsafe: false,
supports_unions: false, supports_unions: false,
methods: vec![MethodDef { methods: vec![MethodDef {
name: "hash", name: sym::hash,
generics: LifetimeBounds { generics: LifetimeBounds {
lifetimes: Vec::new(), lifetimes: Vec::new(),
bounds: vec![(typaram, vec![path_std!(cx, hash::Hasher)])], bounds: vec![(typaram, vec![path_std!(cx, hash::Hasher)])],
@ -73,7 +73,7 @@ fn hash_substructure(cx: &mut ExtCtxt<'_>, trait_span: Span, substr: &Substructu
let variant_value = deriving::call_intrinsic( let variant_value = deriving::call_intrinsic(
cx, cx,
trait_span, trait_span,
"discriminant_value", sym::discriminant_value,
vec![cx.expr_self(trait_span)], vec![cx.expr_self(trait_span)],
); );

View file

@ -62,11 +62,11 @@ impl MultiItemModifier for BuiltinDerive {
fn call_intrinsic( fn call_intrinsic(
cx: &ExtCtxt<'_>, cx: &ExtCtxt<'_>,
span: Span, span: Span,
intrinsic: &str, intrinsic: Symbol,
args: Vec<P<ast::Expr>>, args: Vec<P<ast::Expr>>,
) -> P<ast::Expr> { ) -> P<ast::Expr> {
let span = cx.with_def_site_ctxt(span); let span = cx.with_def_site_ctxt(span);
let path = cx.std_path(&[sym::intrinsics, Symbol::intern(intrinsic)]); let path = cx.std_path(&[sym::intrinsics, intrinsic]);
let call = cx.expr_call_global(span, path, args); let call = cx.expr_call_global(span, path, args);
cx.expr_block(P(ast::Block { cx.expr_block(P(ast::Block {

View file

@ -79,12 +79,8 @@ impl AllocFnFactory<'_, '_> {
self.cx.stmt_item(self.span, item) self.cx.stmt_item(self.span, item)
} }
fn call_allocator(&self, method: &str, mut args: Vec<P<Expr>>) -> P<Expr> { fn call_allocator(&self, method: Symbol, mut args: Vec<P<Expr>>) -> P<Expr> {
let method = self.cx.std_path(&[ let method = self.cx.std_path(&[sym::alloc, sym::GlobalAlloc, method]);
Symbol::intern("alloc"),
Symbol::intern("GlobalAlloc"),
Symbol::intern(method),
]);
let method = self.cx.expr_path(self.cx.path(self.span, method)); let method = self.cx.expr_path(self.cx.path(self.span, method));
let allocator = self.cx.path_ident(self.span, self.global); let allocator = self.cx.path_ident(self.span, self.global);
let allocator = self.cx.expr_path(allocator); let allocator = self.cx.expr_path(allocator);
@ -115,11 +111,8 @@ impl AllocFnFactory<'_, '_> {
args.push(self.cx.param(self.span, size, ty_usize.clone())); args.push(self.cx.param(self.span, size, ty_usize.clone()));
args.push(self.cx.param(self.span, align, ty_usize)); args.push(self.cx.param(self.span, align, ty_usize));
let layout_new = self.cx.std_path(&[ let layout_new =
Symbol::intern("alloc"), self.cx.std_path(&[sym::alloc, sym::Layout, sym::from_size_align_unchecked]);
Symbol::intern("Layout"),
Symbol::intern("from_size_align_unchecked"),
]);
let layout_new = self.cx.expr_path(self.cx.path(self.span, layout_new)); let layout_new = self.cx.expr_path(self.cx.path(self.span, layout_new));
let size = self.cx.expr_ident(self.span, size); let size = self.cx.expr_ident(self.span, size);
let align = self.cx.expr_ident(self.span, align); let align = self.cx.expr_ident(self.span, align);

View file

@ -164,10 +164,8 @@ impl MutVisitor for EntryPointCleaner {
EntryPointType::MainNamed | EntryPointType::MainAttr | EntryPointType::Start => item EntryPointType::MainNamed | EntryPointType::MainAttr | EntryPointType::Start => item
.map(|ast::Item { id, ident, attrs, kind, vis, span, tokens }| { .map(|ast::Item { id, ident, attrs, kind, vis, span, tokens }| {
let allow_ident = Ident::new(sym::allow, self.def_site); let allow_ident = Ident::new(sym::allow, self.def_site);
let dc_nested = attr::mk_nested_word_item(Ident::from_str_and_span( let dc_nested =
"dead_code", attr::mk_nested_word_item(Ident::new(sym::dead_code, self.def_site));
self.def_site,
));
let allow_dead_code_item = attr::mk_list_item(allow_ident, vec![dc_nested]); let allow_dead_code_item = attr::mk_list_item(allow_ident, vec![dc_nested]);
let allow_dead_code = attr::mk_attr_outer(allow_dead_code_item); let allow_dead_code = attr::mk_attr_outer(allow_dead_code_item);
let attrs = attrs let attrs = attrs

View file

@ -25,59 +25,59 @@ use rustc_middle::mir::Operand;
use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt}; use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt};
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty};
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_span::Span; use rustc_span::{sym, symbol::kw, Span, Symbol};
use rustc_target::abi::{self, HasDataLayout, LayoutOf, Primitive}; use rustc_target::abi::{self, HasDataLayout, LayoutOf, Primitive};
use rustc_target::spec::PanicStrategy; use rustc_target::spec::PanicStrategy;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::iter; use std::iter;
fn get_simple_intrinsic(cx: &CodegenCx<'ll, '_>, name: &str) -> Option<&'ll Value> { fn get_simple_intrinsic(cx: &CodegenCx<'ll, '_>, name: Symbol) -> Option<&'ll Value> {
let llvm_name = match name { let llvm_name = match name {
"sqrtf32" => "llvm.sqrt.f32", sym::sqrtf32 => "llvm.sqrt.f32",
"sqrtf64" => "llvm.sqrt.f64", sym::sqrtf64 => "llvm.sqrt.f64",
"powif32" => "llvm.powi.f32", sym::powif32 => "llvm.powi.f32",
"powif64" => "llvm.powi.f64", sym::powif64 => "llvm.powi.f64",
"sinf32" => "llvm.sin.f32", sym::sinf32 => "llvm.sin.f32",
"sinf64" => "llvm.sin.f64", sym::sinf64 => "llvm.sin.f64",
"cosf32" => "llvm.cos.f32", sym::cosf32 => "llvm.cos.f32",
"cosf64" => "llvm.cos.f64", sym::cosf64 => "llvm.cos.f64",
"powf32" => "llvm.pow.f32", sym::powf32 => "llvm.pow.f32",
"powf64" => "llvm.pow.f64", sym::powf64 => "llvm.pow.f64",
"expf32" => "llvm.exp.f32", sym::expf32 => "llvm.exp.f32",
"expf64" => "llvm.exp.f64", sym::expf64 => "llvm.exp.f64",
"exp2f32" => "llvm.exp2.f32", sym::exp2f32 => "llvm.exp2.f32",
"exp2f64" => "llvm.exp2.f64", sym::exp2f64 => "llvm.exp2.f64",
"logf32" => "llvm.log.f32", sym::logf32 => "llvm.log.f32",
"logf64" => "llvm.log.f64", sym::logf64 => "llvm.log.f64",
"log10f32" => "llvm.log10.f32", sym::log10f32 => "llvm.log10.f32",
"log10f64" => "llvm.log10.f64", sym::log10f64 => "llvm.log10.f64",
"log2f32" => "llvm.log2.f32", sym::log2f32 => "llvm.log2.f32",
"log2f64" => "llvm.log2.f64", sym::log2f64 => "llvm.log2.f64",
"fmaf32" => "llvm.fma.f32", sym::fmaf32 => "llvm.fma.f32",
"fmaf64" => "llvm.fma.f64", sym::fmaf64 => "llvm.fma.f64",
"fabsf32" => "llvm.fabs.f32", sym::fabsf32 => "llvm.fabs.f32",
"fabsf64" => "llvm.fabs.f64", sym::fabsf64 => "llvm.fabs.f64",
"minnumf32" => "llvm.minnum.f32", sym::minnumf32 => "llvm.minnum.f32",
"minnumf64" => "llvm.minnum.f64", sym::minnumf64 => "llvm.minnum.f64",
"maxnumf32" => "llvm.maxnum.f32", sym::maxnumf32 => "llvm.maxnum.f32",
"maxnumf64" => "llvm.maxnum.f64", sym::maxnumf64 => "llvm.maxnum.f64",
"copysignf32" => "llvm.copysign.f32", sym::copysignf32 => "llvm.copysign.f32",
"copysignf64" => "llvm.copysign.f64", sym::copysignf64 => "llvm.copysign.f64",
"floorf32" => "llvm.floor.f32", sym::floorf32 => "llvm.floor.f32",
"floorf64" => "llvm.floor.f64", sym::floorf64 => "llvm.floor.f64",
"ceilf32" => "llvm.ceil.f32", sym::ceilf32 => "llvm.ceil.f32",
"ceilf64" => "llvm.ceil.f64", sym::ceilf64 => "llvm.ceil.f64",
"truncf32" => "llvm.trunc.f32", sym::truncf32 => "llvm.trunc.f32",
"truncf64" => "llvm.trunc.f64", sym::truncf64 => "llvm.trunc.f64",
"rintf32" => "llvm.rint.f32", sym::rintf32 => "llvm.rint.f32",
"rintf64" => "llvm.rint.f64", sym::rintf64 => "llvm.rint.f64",
"nearbyintf32" => "llvm.nearbyint.f32", sym::nearbyintf32 => "llvm.nearbyint.f32",
"nearbyintf64" => "llvm.nearbyint.f64", sym::nearbyintf64 => "llvm.nearbyint.f64",
"roundf32" => "llvm.round.f32", sym::roundf32 => "llvm.round.f32",
"roundf64" => "llvm.round.f64", sym::roundf64 => "llvm.round.f64",
"assume" => "llvm.assume", sym::assume => "llvm.assume",
"abort" => "llvm.trap", sym::abort => "llvm.trap",
_ => return None, _ => return None,
}; };
Some(cx.get_intrinsic(&llvm_name)) Some(cx.get_intrinsic(&llvm_name))
@ -86,12 +86,12 @@ fn get_simple_intrinsic(cx: &CodegenCx<'ll, '_>, name: &str) -> Option<&'ll Valu
impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
fn is_codegen_intrinsic( fn is_codegen_intrinsic(
&mut self, &mut self,
intrinsic: &str, intrinsic: Symbol,
args: &Vec<Operand<'tcx>>, args: &Vec<Operand<'tcx>>,
caller_instance: ty::Instance<'tcx>, caller_instance: ty::Instance<'tcx>,
) -> bool { ) -> bool {
match intrinsic { match intrinsic {
"count_code_region" => { sym::count_code_region => {
use coverage::count_code_region_args::*; use coverage::count_code_region_args::*;
self.add_counter_region( self.add_counter_region(
caller_instance, caller_instance,
@ -101,13 +101,13 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
); );
true // Also inject the counter increment in the backend true // Also inject the counter increment in the backend
} }
"coverage_counter_add" | "coverage_counter_subtract" => { sym::coverage_counter_add | sym::coverage_counter_subtract => {
use coverage::coverage_counter_expression_args::*; use coverage::coverage_counter_expression_args::*;
self.add_counter_expression_region( self.add_counter_expression_region(
caller_instance, caller_instance,
op_to_u32(&args[COUNTER_EXPRESSION_INDEX]), op_to_u32(&args[COUNTER_EXPRESSION_INDEX]),
op_to_u32(&args[LEFT_INDEX]), op_to_u32(&args[LEFT_INDEX]),
if intrinsic == "coverage_counter_add" { if intrinsic == sym::coverage_counter_add {
CounterOp::Add CounterOp::Add
} else { } else {
CounterOp::Subtract CounterOp::Subtract
@ -118,7 +118,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
); );
false // Does not inject backend code false // Does not inject backend code
} }
"coverage_unreachable" => { sym::coverage_unreachable => {
use coverage::coverage_unreachable_args::*; use coverage::coverage_unreachable_args::*;
self.add_unreachable_region( self.add_unreachable_region(
caller_instance, caller_instance,
@ -152,7 +152,8 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
let arg_tys = sig.inputs(); let arg_tys = sig.inputs();
let ret_ty = sig.output(); let ret_ty = sig.output();
let name = &*tcx.item_name(def_id).as_str(); let name = tcx.item_name(def_id);
let name_str = &*name.as_str();
let llret_ty = self.layout_of(ret_ty).llvm_type(self); let llret_ty = self.layout_of(ret_ty).llvm_type(self);
let result = PlaceRef::new_sized(llresult, fn_abi.ret.layout); let result = PlaceRef::new_sized(llresult, fn_abi.ret.layout);
@ -164,18 +165,18 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
&args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
None, None,
), ),
"unreachable" => { sym::unreachable => {
return; return;
} }
"likely" => { sym::likely => {
let expect = self.get_intrinsic(&("llvm.expect.i1")); let expect = self.get_intrinsic(&("llvm.expect.i1"));
self.call(expect, &[args[0].immediate(), self.const_bool(true)], None) self.call(expect, &[args[0].immediate(), self.const_bool(true)], None)
} }
"unlikely" => { sym::unlikely => {
let expect = self.get_intrinsic(&("llvm.expect.i1")); let expect = self.get_intrinsic(&("llvm.expect.i1"));
self.call(expect, &[args[0].immediate(), self.const_bool(false)], None) self.call(expect, &[args[0].immediate(), self.const_bool(false)], None)
} }
"try" => { kw::Try => {
try_intrinsic( try_intrinsic(
self, self,
args[0].immediate(), args[0].immediate(),
@ -185,11 +186,11 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
); );
return; return;
} }
"breakpoint" => { sym::breakpoint => {
let llfn = self.get_intrinsic(&("llvm.debugtrap")); let llfn = self.get_intrinsic(&("llvm.debugtrap"));
self.call(llfn, &[], None) self.call(llfn, &[], None)
} }
"count_code_region" => { sym::count_code_region => {
// FIXME(richkadel): The current implementation assumes the MIR for the given // FIXME(richkadel): The current implementation assumes the MIR for the given
// caller_instance represents a single function. Validate and/or correct if inlining // caller_instance represents a single function. Validate and/or correct if inlining
// and/or monomorphization invalidates these assumptions. // and/or monomorphization invalidates these assumptions.
@ -206,13 +207,13 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
); );
self.instrprof_increment(mangled_fn_name, hash, num_counters, index) self.instrprof_increment(mangled_fn_name, hash, num_counters, index)
} }
"va_start" => self.va_start(args[0].immediate()), sym::va_start => self.va_start(args[0].immediate()),
"va_end" => self.va_end(args[0].immediate()), sym::va_end => self.va_end(args[0].immediate()),
"va_copy" => { sym::va_copy => {
let intrinsic = self.cx().get_intrinsic(&("llvm.va_copy")); let intrinsic = self.cx().get_intrinsic(&("llvm.va_copy"));
self.call(intrinsic, &[args[0].immediate(), args[1].immediate()], None) self.call(intrinsic, &[args[0].immediate(), args[1].immediate()], None)
} }
"va_arg" => { sym::va_arg => {
match fn_abi.ret.layout.abi { match fn_abi.ret.layout.abi {
abi::Abi::Scalar(ref scalar) => { abi::Abi::Scalar(ref scalar) => {
match scalar.value { match scalar.value {
@ -238,7 +239,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
_ => bug!("the va_arg intrinsic does not work with non-scalar types"), _ => bug!("the va_arg intrinsic does not work with non-scalar types"),
} }
} }
"size_of_val" => { sym::size_of_val => {
let tp_ty = substs.type_at(0); let tp_ty = substs.type_at(0);
if let OperandValue::Pair(_, meta) = args[0].val { if let OperandValue::Pair(_, meta) = args[0].val {
let (llsize, _) = glue::size_and_align_of_dst(self, tp_ty, Some(meta)); let (llsize, _) = glue::size_and_align_of_dst(self, tp_ty, Some(meta));
@ -247,7 +248,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
self.const_usize(self.size_of(tp_ty).bytes()) self.const_usize(self.size_of(tp_ty).bytes())
} }
} }
"min_align_of_val" => { sym::min_align_of_val => {
let tp_ty = substs.type_at(0); let tp_ty = substs.type_at(0);
if let OperandValue::Pair(_, meta) = args[0].val { if let OperandValue::Pair(_, meta) = args[0].val {
let (_, llalign) = glue::size_and_align_of_dst(self, tp_ty, Some(meta)); let (_, llalign) = glue::size_and_align_of_dst(self, tp_ty, Some(meta));
@ -256,8 +257,13 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
self.const_usize(self.align_of(tp_ty).bytes()) self.const_usize(self.align_of(tp_ty).bytes())
} }
} }
"size_of" | "pref_align_of" | "min_align_of" | "needs_drop" | "type_id" sym::size_of
| "type_name" | "variant_count" => { | sym::pref_align_of
| sym::min_align_of
| sym::needs_drop
| sym::type_id
| sym::type_name
| sym::variant_count => {
let value = self let value = self
.tcx .tcx
.const_eval_instance(ty::ParamEnv::reveal_all(), instance, None) .const_eval_instance(ty::ParamEnv::reveal_all(), instance, None)
@ -265,21 +271,21 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
OperandRef::from_const(self, value, ret_ty).immediate_or_packed_pair(self) OperandRef::from_const(self, value, ret_ty).immediate_or_packed_pair(self)
} }
// Effectively no-op // Effectively no-op
"forget" => { sym::forget => {
return; return;
} }
"offset" => { sym::offset => {
let ptr = args[0].immediate(); let ptr = args[0].immediate();
let offset = args[1].immediate(); let offset = args[1].immediate();
self.inbounds_gep(ptr, &[offset]) self.inbounds_gep(ptr, &[offset])
} }
"arith_offset" => { sym::arith_offset => {
let ptr = args[0].immediate(); let ptr = args[0].immediate();
let offset = args[1].immediate(); let offset = args[1].immediate();
self.gep(ptr, &[offset]) self.gep(ptr, &[offset])
} }
"copy_nonoverlapping" => { sym::copy_nonoverlapping => {
copy_intrinsic( copy_intrinsic(
self, self,
false, false,
@ -291,7 +297,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
); );
return; return;
} }
"copy" => { sym::copy => {
copy_intrinsic( copy_intrinsic(
self, self,
true, true,
@ -303,7 +309,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
); );
return; return;
} }
"write_bytes" => { sym::write_bytes => {
memset_intrinsic( memset_intrinsic(
self, self,
false, false,
@ -315,7 +321,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
return; return;
} }
"volatile_copy_nonoverlapping_memory" => { sym::volatile_copy_nonoverlapping_memory => {
copy_intrinsic( copy_intrinsic(
self, self,
false, false,
@ -327,7 +333,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
); );
return; return;
} }
"volatile_copy_memory" => { sym::volatile_copy_memory => {
copy_intrinsic( copy_intrinsic(
self, self,
true, true,
@ -339,7 +345,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
); );
return; return;
} }
"volatile_set_memory" => { sym::volatile_set_memory => {
memset_intrinsic( memset_intrinsic(
self, self,
true, true,
@ -350,14 +356,14 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
); );
return; return;
} }
"volatile_load" | "unaligned_volatile_load" => { sym::volatile_load | sym::unaligned_volatile_load => {
let tp_ty = substs.type_at(0); let tp_ty = substs.type_at(0);
let mut ptr = args[0].immediate(); let mut ptr = args[0].immediate();
if let PassMode::Cast(ty) = fn_abi.ret.mode { if let PassMode::Cast(ty) = fn_abi.ret.mode {
ptr = self.pointercast(ptr, self.type_ptr_to(ty.llvm_type(self))); ptr = self.pointercast(ptr, self.type_ptr_to(ty.llvm_type(self)));
} }
let load = self.volatile_load(ptr); let load = self.volatile_load(ptr);
let align = if name == "unaligned_volatile_load" { let align = if name == sym::unaligned_volatile_load {
1 1
} else { } else {
self.align_of(tp_ty).bytes() as u32 self.align_of(tp_ty).bytes() as u32
@ -367,26 +373,26 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
} }
to_immediate(self, load, self.layout_of(tp_ty)) to_immediate(self, load, self.layout_of(tp_ty))
} }
"volatile_store" => { sym::volatile_store => {
let dst = args[0].deref(self.cx()); let dst = args[0].deref(self.cx());
args[1].val.volatile_store(self, dst); args[1].val.volatile_store(self, dst);
return; return;
} }
"unaligned_volatile_store" => { sym::unaligned_volatile_store => {
let dst = args[0].deref(self.cx()); let dst = args[0].deref(self.cx());
args[1].val.unaligned_volatile_store(self, dst); args[1].val.unaligned_volatile_store(self, dst);
return; return;
} }
"prefetch_read_data" sym::prefetch_read_data
| "prefetch_write_data" | sym::prefetch_write_data
| "prefetch_read_instruction" | sym::prefetch_read_instruction
| "prefetch_write_instruction" => { | sym::prefetch_write_instruction => {
let expect = self.get_intrinsic(&("llvm.prefetch")); let expect = self.get_intrinsic(&("llvm.prefetch"));
let (rw, cache_type) = match name { let (rw, cache_type) = match name {
"prefetch_read_data" => (0, 1), sym::prefetch_read_data => (0, 1),
"prefetch_write_data" => (1, 1), sym::prefetch_write_data => (1, 1),
"prefetch_read_instruction" => (0, 0), sym::prefetch_read_instruction => (0, 0),
"prefetch_write_instruction" => (1, 0), sym::prefetch_write_instruction => (1, 0),
_ => bug!(), _ => bug!(),
}; };
self.call( self.call(
@ -400,32 +406,51 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
None, None,
) )
} }
"ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | "ctpop" | "bswap" sym::ctlz
| "bitreverse" | "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" | sym::ctlz_nonzero
| "wrapping_add" | "wrapping_sub" | "wrapping_mul" | "unchecked_div" | sym::cttz
| "unchecked_rem" | "unchecked_shl" | "unchecked_shr" | "unchecked_add" | sym::cttz_nonzero
| "unchecked_sub" | "unchecked_mul" | "exact_div" | "rotate_left" | "rotate_right" | sym::ctpop
| "saturating_add" | "saturating_sub" => { | sym::bswap
| sym::bitreverse
| sym::add_with_overflow
| sym::sub_with_overflow
| sym::mul_with_overflow
| sym::wrapping_add
| sym::wrapping_sub
| sym::wrapping_mul
| sym::unchecked_div
| sym::unchecked_rem
| sym::unchecked_shl
| sym::unchecked_shr
| sym::unchecked_add
| sym::unchecked_sub
| sym::unchecked_mul
| sym::exact_div
| sym::rotate_left
| sym::rotate_right
| sym::saturating_add
| sym::saturating_sub => {
let ty = arg_tys[0]; let ty = arg_tys[0];
match int_type_width_signed(ty, self) { match int_type_width_signed(ty, self) {
Some((width, signed)) => match name { Some((width, signed)) => match name {
"ctlz" | "cttz" => { sym::ctlz | sym::cttz => {
let y = self.const_bool(false); let y = self.const_bool(false);
let llfn = self.get_intrinsic(&format!("llvm.{}.i{}", name, width)); let llfn = self.get_intrinsic(&format!("llvm.{}.i{}", name, width));
self.call(llfn, &[args[0].immediate(), y], None) self.call(llfn, &[args[0].immediate(), y], None)
} }
"ctlz_nonzero" | "cttz_nonzero" => { sym::ctlz_nonzero | sym::cttz_nonzero => {
let y = self.const_bool(true); let y = self.const_bool(true);
let llvm_name = &format!("llvm.{}.i{}", &name[..4], width); let llvm_name = &format!("llvm.{}.i{}", &name_str[..4], width);
let llfn = self.get_intrinsic(llvm_name); let llfn = self.get_intrinsic(llvm_name);
self.call(llfn, &[args[0].immediate(), y], None) self.call(llfn, &[args[0].immediate(), y], None)
} }
"ctpop" => self.call( sym::ctpop => self.call(
self.get_intrinsic(&format!("llvm.ctpop.i{}", width)), self.get_intrinsic(&format!("llvm.ctpop.i{}", width)),
&[args[0].immediate()], &[args[0].immediate()],
None, None,
), ),
"bswap" => { sym::bswap => {
if width == 8 { if width == 8 {
args[0].immediate() // byte swap a u8/i8 is just a no-op args[0].immediate() // byte swap a u8/i8 is just a no-op
} else { } else {
@ -436,16 +461,18 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
) )
} }
} }
"bitreverse" => self.call( sym::bitreverse => self.call(
self.get_intrinsic(&format!("llvm.bitreverse.i{}", width)), self.get_intrinsic(&format!("llvm.bitreverse.i{}", width)),
&[args[0].immediate()], &[args[0].immediate()],
None, None,
), ),
"add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" => { sym::add_with_overflow
| sym::sub_with_overflow
| sym::mul_with_overflow => {
let intrinsic = format!( let intrinsic = format!(
"llvm.{}{}.with.overflow.i{}", "llvm.{}{}.with.overflow.i{}",
if signed { 's' } else { 'u' }, if signed { 's' } else { 'u' },
&name[..3], &name_str[..3],
width width
); );
let llfn = self.get_intrinsic(&intrinsic); let llfn = self.get_intrinsic(&intrinsic);
@ -464,61 +491,61 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
return; return;
} }
"wrapping_add" => self.add(args[0].immediate(), args[1].immediate()), sym::wrapping_add => self.add(args[0].immediate(), args[1].immediate()),
"wrapping_sub" => self.sub(args[0].immediate(), args[1].immediate()), sym::wrapping_sub => self.sub(args[0].immediate(), args[1].immediate()),
"wrapping_mul" => self.mul(args[0].immediate(), args[1].immediate()), sym::wrapping_mul => self.mul(args[0].immediate(), args[1].immediate()),
"exact_div" => { sym::exact_div => {
if signed { if signed {
self.exactsdiv(args[0].immediate(), args[1].immediate()) self.exactsdiv(args[0].immediate(), args[1].immediate())
} else { } else {
self.exactudiv(args[0].immediate(), args[1].immediate()) self.exactudiv(args[0].immediate(), args[1].immediate())
} }
} }
"unchecked_div" => { sym::unchecked_div => {
if signed { if signed {
self.sdiv(args[0].immediate(), args[1].immediate()) self.sdiv(args[0].immediate(), args[1].immediate())
} else { } else {
self.udiv(args[0].immediate(), args[1].immediate()) self.udiv(args[0].immediate(), args[1].immediate())
} }
} }
"unchecked_rem" => { sym::unchecked_rem => {
if signed { if signed {
self.srem(args[0].immediate(), args[1].immediate()) self.srem(args[0].immediate(), args[1].immediate())
} else { } else {
self.urem(args[0].immediate(), args[1].immediate()) self.urem(args[0].immediate(), args[1].immediate())
} }
} }
"unchecked_shl" => self.shl(args[0].immediate(), args[1].immediate()), sym::unchecked_shl => self.shl(args[0].immediate(), args[1].immediate()),
"unchecked_shr" => { sym::unchecked_shr => {
if signed { if signed {
self.ashr(args[0].immediate(), args[1].immediate()) self.ashr(args[0].immediate(), args[1].immediate())
} else { } else {
self.lshr(args[0].immediate(), args[1].immediate()) self.lshr(args[0].immediate(), args[1].immediate())
} }
} }
"unchecked_add" => { sym::unchecked_add => {
if signed { if signed {
self.unchecked_sadd(args[0].immediate(), args[1].immediate()) self.unchecked_sadd(args[0].immediate(), args[1].immediate())
} else { } else {
self.unchecked_uadd(args[0].immediate(), args[1].immediate()) self.unchecked_uadd(args[0].immediate(), args[1].immediate())
} }
} }
"unchecked_sub" => { sym::unchecked_sub => {
if signed { if signed {
self.unchecked_ssub(args[0].immediate(), args[1].immediate()) self.unchecked_ssub(args[0].immediate(), args[1].immediate())
} else { } else {
self.unchecked_usub(args[0].immediate(), args[1].immediate()) self.unchecked_usub(args[0].immediate(), args[1].immediate())
} }
} }
"unchecked_mul" => { sym::unchecked_mul => {
if signed { if signed {
self.unchecked_smul(args[0].immediate(), args[1].immediate()) self.unchecked_smul(args[0].immediate(), args[1].immediate())
} else { } else {
self.unchecked_umul(args[0].immediate(), args[1].immediate()) self.unchecked_umul(args[0].immediate(), args[1].immediate())
} }
} }
"rotate_left" | "rotate_right" => { sym::rotate_left | sym::rotate_right => {
let is_left = name == "rotate_left"; let is_left = name == sym::rotate_left;
let val = args[0].immediate(); let val = args[0].immediate();
let raw_shift = args[1].immediate(); let raw_shift = args[1].immediate();
// rotate = funnel shift with first two args the same // rotate = funnel shift with first two args the same
@ -527,8 +554,8 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
let llfn = self.get_intrinsic(llvm_name); let llfn = self.get_intrinsic(llvm_name);
self.call(llfn, &[val, val, raw_shift], None) self.call(llfn, &[val, val, raw_shift], None)
} }
"saturating_add" | "saturating_sub" => { sym::saturating_add | sym::saturating_sub => {
let is_add = name == "saturating_add"; let is_add = name == sym::saturating_add;
let lhs = args[0].immediate(); let lhs = args[0].immediate();
let rhs = args[1].immediate(); let rhs = args[1].immediate();
let llvm_name = &format!( let llvm_name = &format!(
@ -556,14 +583,14 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
} }
} }
} }
"fadd_fast" | "fsub_fast" | "fmul_fast" | "fdiv_fast" | "frem_fast" => { sym::fadd_fast | sym::fsub_fast | sym::fmul_fast | sym::fdiv_fast | sym::frem_fast => {
match float_type_width(arg_tys[0]) { match float_type_width(arg_tys[0]) {
Some(_width) => match name { Some(_width) => match name {
"fadd_fast" => self.fadd_fast(args[0].immediate(), args[1].immediate()), sym::fadd_fast => self.fadd_fast(args[0].immediate(), args[1].immediate()),
"fsub_fast" => self.fsub_fast(args[0].immediate(), args[1].immediate()), sym::fsub_fast => self.fsub_fast(args[0].immediate(), args[1].immediate()),
"fmul_fast" => self.fmul_fast(args[0].immediate(), args[1].immediate()), sym::fmul_fast => self.fmul_fast(args[0].immediate(), args[1].immediate()),
"fdiv_fast" => self.fdiv_fast(args[0].immediate(), args[1].immediate()), sym::fdiv_fast => self.fdiv_fast(args[0].immediate(), args[1].immediate()),
"frem_fast" => self.frem_fast(args[0].immediate(), args[1].immediate()), sym::frem_fast => self.frem_fast(args[0].immediate(), args[1].immediate()),
_ => bug!(), _ => bug!(),
}, },
None => { None => {
@ -581,7 +608,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
} }
} }
"float_to_int_unchecked" => { sym::float_to_int_unchecked => {
if float_type_width(arg_tys[0]).is_none() { if float_type_width(arg_tys[0]).is_none() {
span_invalid_monomorphization_error( span_invalid_monomorphization_error(
tcx.sess, tcx.sess,
@ -619,7 +646,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
} }
} }
"discriminant_value" => { sym::discriminant_value => {
if ret_ty.is_integral() { if ret_ty.is_integral() {
args[0].deref(self.cx()).codegen_get_discr(self, ret_ty) args[0].deref(self.cx()).codegen_get_discr(self, ret_ty)
} else { } else {
@ -627,7 +654,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
} }
} }
name if name.starts_with("simd_") => { _ if name_str.starts_with("simd_") => {
match generic_simd_intrinsic(self, name, callee_ty, args, ret_ty, llret_ty, span) { match generic_simd_intrinsic(self, name, callee_ty, args, ret_ty, llret_ty, span) {
Ok(llval) => llval, Ok(llval) => llval,
Err(()) => return, Err(()) => return,
@ -635,11 +662,11 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
} }
// This requires that atomic intrinsics follow a specific naming pattern: // This requires that atomic intrinsics follow a specific naming pattern:
// "atomic_<operation>[_<ordering>]", and no ordering means SeqCst // "atomic_<operation>[_<ordering>]", and no ordering means SeqCst
name if name.starts_with("atomic_") => { name if name_str.starts_with("atomic_") => {
use rustc_codegen_ssa::common::AtomicOrdering::*; use rustc_codegen_ssa::common::AtomicOrdering::*;
use rustc_codegen_ssa::common::{AtomicRmwBinOp, SynchronizationScope}; use rustc_codegen_ssa::common::{AtomicRmwBinOp, SynchronizationScope};
let split: Vec<&str> = name.split('_').collect(); let split: Vec<&str> = name_str.split('_').collect();
let is_cxchg = split[1] == "cxchg" || split[1] == "cxchgweak"; let is_cxchg = split[1] == "cxchg" || split[1] == "cxchgweak";
let (order, failorder) = match split.len() { let (order, failorder) = match split.len() {
@ -769,23 +796,23 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
} }
} }
"nontemporal_store" => { sym::nontemporal_store => {
let dst = args[0].deref(self.cx()); let dst = args[0].deref(self.cx());
args[1].val.nontemporal_store(self, dst); args[1].val.nontemporal_store(self, dst);
return; return;
} }
"ptr_guaranteed_eq" | "ptr_guaranteed_ne" => { sym::ptr_guaranteed_eq | sym::ptr_guaranteed_ne => {
let a = args[0].immediate(); let a = args[0].immediate();
let b = args[1].immediate(); let b = args[1].immediate();
if name == "ptr_guaranteed_eq" { if name == sym::ptr_guaranteed_eq {
self.icmp(IntPredicate::IntEQ, a, b) self.icmp(IntPredicate::IntEQ, a, b)
} else { } else {
self.icmp(IntPredicate::IntNE, a, b) self.icmp(IntPredicate::IntNE, a, b)
} }
} }
"ptr_offset_from" => { sym::ptr_offset_from => {
let ty = substs.type_at(0); let ty = substs.type_at(0);
let pointee_size = self.size_of(ty); let pointee_size = self.size_of(ty);
@ -1172,7 +1199,7 @@ fn get_rust_try_fn<'ll, 'tcx>(
fn generic_simd_intrinsic( fn generic_simd_intrinsic(
bx: &mut Builder<'a, 'll, 'tcx>, bx: &mut Builder<'a, 'll, 'tcx>,
name: &str, name: Symbol,
callee_ty: Ty<'tcx>, callee_ty: Ty<'tcx>,
args: &[OperandRef<'tcx, &'ll Value>], args: &[OperandRef<'tcx, &'ll Value>],
ret_ty: Ty<'tcx>, ret_ty: Ty<'tcx>,
@ -1219,8 +1246,9 @@ fn generic_simd_intrinsic(
let sig = tcx let sig = tcx
.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &callee_ty.fn_sig(tcx)); .normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &callee_ty.fn_sig(tcx));
let arg_tys = sig.inputs(); let arg_tys = sig.inputs();
let name_str = &*name.as_str();
if name == "simd_select_bitmask" { if name == sym::simd_select_bitmask {
let in_ty = arg_tys[0]; let in_ty = arg_tys[0];
let m_len = match in_ty.kind { let m_len = match in_ty.kind {
// Note that this `.unwrap()` crashes for isize/usize, that's sort // Note that this `.unwrap()` crashes for isize/usize, that's sort
@ -1250,12 +1278,12 @@ fn generic_simd_intrinsic(
let in_len = arg_tys[0].simd_size(tcx); let in_len = arg_tys[0].simd_size(tcx);
let comparison = match name { let comparison = match name {
"simd_eq" => Some(hir::BinOpKind::Eq), sym::simd_eq => Some(hir::BinOpKind::Eq),
"simd_ne" => Some(hir::BinOpKind::Ne), sym::simd_ne => Some(hir::BinOpKind::Ne),
"simd_lt" => Some(hir::BinOpKind::Lt), sym::simd_lt => Some(hir::BinOpKind::Lt),
"simd_le" => Some(hir::BinOpKind::Le), sym::simd_le => Some(hir::BinOpKind::Le),
"simd_gt" => Some(hir::BinOpKind::Gt), sym::simd_gt => Some(hir::BinOpKind::Gt),
"simd_ge" => Some(hir::BinOpKind::Ge), sym::simd_ge => Some(hir::BinOpKind::Ge),
_ => None, _ => None,
}; };
@ -1289,8 +1317,8 @@ fn generic_simd_intrinsic(
)); ));
} }
if name.starts_with("simd_shuffle") { if name_str.starts_with("simd_shuffle") {
let n: u64 = name["simd_shuffle".len()..].parse().unwrap_or_else(|_| { let n: u64 = name_str["simd_shuffle".len()..].parse().unwrap_or_else(|_| {
span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?") span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?")
}); });
@ -1351,7 +1379,7 @@ fn generic_simd_intrinsic(
)); ));
} }
if name == "simd_insert" { if name == sym::simd_insert {
require!( require!(
in_elem == arg_tys[2], in_elem == arg_tys[2],
"expected inserted type `{}` (element of input `{}`), found `{}`", "expected inserted type `{}` (element of input `{}`), found `{}`",
@ -1365,7 +1393,7 @@ fn generic_simd_intrinsic(
args[1].immediate(), args[1].immediate(),
)); ));
} }
if name == "simd_extract" { if name == sym::simd_extract {
require!( require!(
ret_ty == in_elem, ret_ty == in_elem,
"expected return type `{}` (element of input `{}`), found `{}`", "expected return type `{}` (element of input `{}`), found `{}`",
@ -1376,7 +1404,7 @@ fn generic_simd_intrinsic(
return Ok(bx.extract_element(args[0].immediate(), args[1].immediate())); return Ok(bx.extract_element(args[0].immediate(), args[1].immediate()));
} }
if name == "simd_select" { if name == sym::simd_select {
let m_elem_ty = in_elem; let m_elem_ty = in_elem;
let m_len = in_len; let m_len = in_len;
require_simd!(arg_tys[1], "argument"); require_simd!(arg_tys[1], "argument");
@ -1398,7 +1426,7 @@ fn generic_simd_intrinsic(
return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate())); return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate()));
} }
if name == "simd_bitmask" { if name == sym::simd_bitmask {
// The `fn simd_bitmask(vector) -> unsigned integer` intrinsic takes a // The `fn simd_bitmask(vector) -> unsigned integer` intrinsic takes a
// vector mask and returns an unsigned integer containing the most // vector mask and returns an unsigned integer containing the most
// significant bit (MSB) of each lane. // significant bit (MSB) of each lane.
@ -1513,46 +1541,46 @@ fn generic_simd_intrinsic(
} }
match name { match name {
"simd_fsqrt" => { sym::simd_fsqrt => {
return simd_simple_float_intrinsic("sqrt", in_elem, in_ty, in_len, bx, span, args); return simd_simple_float_intrinsic("sqrt", in_elem, in_ty, in_len, bx, span, args);
} }
"simd_fsin" => { sym::simd_fsin => {
return simd_simple_float_intrinsic("sin", in_elem, in_ty, in_len, bx, span, args); return simd_simple_float_intrinsic("sin", in_elem, in_ty, in_len, bx, span, args);
} }
"simd_fcos" => { sym::simd_fcos => {
return simd_simple_float_intrinsic("cos", in_elem, in_ty, in_len, bx, span, args); return simd_simple_float_intrinsic("cos", in_elem, in_ty, in_len, bx, span, args);
} }
"simd_fabs" => { sym::simd_fabs => {
return simd_simple_float_intrinsic("fabs", in_elem, in_ty, in_len, bx, span, args); return simd_simple_float_intrinsic("fabs", in_elem, in_ty, in_len, bx, span, args);
} }
"simd_floor" => { sym::simd_floor => {
return simd_simple_float_intrinsic("floor", in_elem, in_ty, in_len, bx, span, args); return simd_simple_float_intrinsic("floor", in_elem, in_ty, in_len, bx, span, args);
} }
"simd_ceil" => { sym::simd_ceil => {
return simd_simple_float_intrinsic("ceil", in_elem, in_ty, in_len, bx, span, args); return simd_simple_float_intrinsic("ceil", in_elem, in_ty, in_len, bx, span, args);
} }
"simd_fexp" => { sym::simd_fexp => {
return simd_simple_float_intrinsic("exp", in_elem, in_ty, in_len, bx, span, args); return simd_simple_float_intrinsic("exp", in_elem, in_ty, in_len, bx, span, args);
} }
"simd_fexp2" => { sym::simd_fexp2 => {
return simd_simple_float_intrinsic("exp2", in_elem, in_ty, in_len, bx, span, args); return simd_simple_float_intrinsic("exp2", in_elem, in_ty, in_len, bx, span, args);
} }
"simd_flog10" => { sym::simd_flog10 => {
return simd_simple_float_intrinsic("log10", in_elem, in_ty, in_len, bx, span, args); return simd_simple_float_intrinsic("log10", in_elem, in_ty, in_len, bx, span, args);
} }
"simd_flog2" => { sym::simd_flog2 => {
return simd_simple_float_intrinsic("log2", in_elem, in_ty, in_len, bx, span, args); return simd_simple_float_intrinsic("log2", in_elem, in_ty, in_len, bx, span, args);
} }
"simd_flog" => { sym::simd_flog => {
return simd_simple_float_intrinsic("log", in_elem, in_ty, in_len, bx, span, args); return simd_simple_float_intrinsic("log", in_elem, in_ty, in_len, bx, span, args);
} }
"simd_fpowi" => { sym::simd_fpowi => {
return simd_simple_float_intrinsic("powi", in_elem, in_ty, in_len, bx, span, args); return simd_simple_float_intrinsic("powi", in_elem, in_ty, in_len, bx, span, args);
} }
"simd_fpow" => { sym::simd_fpow => {
return simd_simple_float_intrinsic("pow", in_elem, in_ty, in_len, bx, span, args); return simd_simple_float_intrinsic("pow", in_elem, in_ty, in_len, bx, span, args);
} }
"simd_fma" => { sym::simd_fma => {
return simd_simple_float_intrinsic("fma", in_elem, in_ty, in_len, bx, span, args); return simd_simple_float_intrinsic("fma", in_elem, in_ty, in_len, bx, span, args);
} }
_ => { /* fallthrough */ } _ => { /* fallthrough */ }
@ -1591,7 +1619,7 @@ fn generic_simd_intrinsic(
cx.type_vector(elem_ty, vec_len) cx.type_vector(elem_ty, vec_len)
} }
if name == "simd_gather" { if name == sym::simd_gather {
// simd_gather(values: <N x T>, pointers: <N x *_ T>, // simd_gather(values: <N x T>, pointers: <N x *_ T>,
// mask: <N x i{M}>) -> <N x T> // mask: <N x i{M}>) -> <N x T>
// * N: number of elements in the input vectors // * N: number of elements in the input vectors
@ -1718,7 +1746,7 @@ fn generic_simd_intrinsic(
return Ok(v); return Ok(v);
} }
if name == "simd_scatter" { if name == sym::simd_scatter {
// simd_scatter(values: <N x T>, pointers: <N x *mut T>, // simd_scatter(values: <N x T>, pointers: <N x *mut T>,
// mask: <N x i{M}>) -> () // mask: <N x i{M}>) -> ()
// * N: number of elements in the input vectors // * N: number of elements in the input vectors
@ -1841,8 +1869,9 @@ fn generic_simd_intrinsic(
} }
macro_rules! arith_red { macro_rules! arith_red {
($name:tt : $integer_reduce:ident, $float_reduce:ident, $ordered:expr) => { ($name:ident : $integer_reduce:ident, $float_reduce:ident, $ordered:expr, $op:ident,
if name == $name { $identity:expr) => {
if name == sym::$name {
require!( require!(
ret_ty == in_elem, ret_ty == in_elem,
"expected return type `{}` (element of input `{}`), found `{}`", "expected return type `{}` (element of input `{}`), found `{}`",
@ -1856,11 +1885,7 @@ fn generic_simd_intrinsic(
if $ordered { if $ordered {
// if overflow occurs, the result is the // if overflow occurs, the result is the
// mathematical result modulo 2^n: // mathematical result modulo 2^n:
if name.contains("mul") { Ok(bx.$op(args[1].immediate(), r))
Ok(bx.mul(args[1].immediate(), r))
} else {
Ok(bx.add(args[1].immediate(), r))
}
} else { } else {
Ok(bx.$integer_reduce(args[0].immediate())) Ok(bx.$integer_reduce(args[0].immediate()))
} }
@ -1871,14 +1896,13 @@ fn generic_simd_intrinsic(
args[1].immediate() args[1].immediate()
} else { } else {
// unordered arithmetic reductions use the identity accumulator // unordered arithmetic reductions use the identity accumulator
let identity_acc = if $name.contains("mul") { 1.0 } else { 0.0 };
match f.bit_width() { match f.bit_width() {
32 => bx.const_real(bx.type_f32(), identity_acc), 32 => bx.const_real(bx.type_f32(), $identity),
64 => bx.const_real(bx.type_f64(), identity_acc), 64 => bx.const_real(bx.type_f64(), $identity),
v => return_error!( v => return_error!(
r#" r#"
unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
$name, sym::$name,
in_ty, in_ty,
in_elem, in_elem,
v, v,
@ -1890,7 +1914,7 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
} }
_ => return_error!( _ => return_error!(
"unsupported {} from `{}` with element `{}` to `{}`", "unsupported {} from `{}` with element `{}` to `{}`",
$name, sym::$name,
in_ty, in_ty,
in_elem, in_elem,
ret_ty ret_ty
@ -1900,14 +1924,26 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
}; };
} }
arith_red!("simd_reduce_add_ordered": vector_reduce_add, vector_reduce_fadd, true); arith_red!(simd_reduce_add_ordered: vector_reduce_add, vector_reduce_fadd, true, add, 0.0);
arith_red!("simd_reduce_mul_ordered": vector_reduce_mul, vector_reduce_fmul, true); arith_red!(simd_reduce_mul_ordered: vector_reduce_mul, vector_reduce_fmul, true, mul, 1.0);
arith_red!("simd_reduce_add_unordered": vector_reduce_add, vector_reduce_fadd_fast, false); arith_red!(
arith_red!("simd_reduce_mul_unordered": vector_reduce_mul, vector_reduce_fmul_fast, false); simd_reduce_add_unordered: vector_reduce_add,
vector_reduce_fadd_fast,
false,
add,
0.0
);
arith_red!(
simd_reduce_mul_unordered: vector_reduce_mul,
vector_reduce_fmul_fast,
false,
mul,
1.0
);
macro_rules! minmax_red { macro_rules! minmax_red {
($name:tt: $int_red:ident, $float_red:ident) => { ($name:ident: $int_red:ident, $float_red:ident) => {
if name == $name { if name == sym::$name {
require!( require!(
ret_ty == in_elem, ret_ty == in_elem,
"expected return type `{}` (element of input `{}`), found `{}`", "expected return type `{}` (element of input `{}`), found `{}`",
@ -1921,7 +1957,7 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
ty::Float(_f) => Ok(bx.$float_red(args[0].immediate())), ty::Float(_f) => Ok(bx.$float_red(args[0].immediate())),
_ => return_error!( _ => return_error!(
"unsupported {} from `{}` with element `{}` to `{}`", "unsupported {} from `{}` with element `{}` to `{}`",
$name, sym::$name,
in_ty, in_ty,
in_elem, in_elem,
ret_ty ret_ty
@ -1931,15 +1967,15 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
}; };
} }
minmax_red!("simd_reduce_min": vector_reduce_min, vector_reduce_fmin); minmax_red!(simd_reduce_min: vector_reduce_min, vector_reduce_fmin);
minmax_red!("simd_reduce_max": vector_reduce_max, vector_reduce_fmax); minmax_red!(simd_reduce_max: vector_reduce_max, vector_reduce_fmax);
minmax_red!("simd_reduce_min_nanless": vector_reduce_min, vector_reduce_fmin_fast); minmax_red!(simd_reduce_min_nanless: vector_reduce_min, vector_reduce_fmin_fast);
minmax_red!("simd_reduce_max_nanless": vector_reduce_max, vector_reduce_fmax_fast); minmax_red!(simd_reduce_max_nanless: vector_reduce_max, vector_reduce_fmax_fast);
macro_rules! bitwise_red { macro_rules! bitwise_red {
($name:tt : $red:ident, $boolean:expr) => { ($name:ident : $red:ident, $boolean:expr) => {
if name == $name { if name == sym::$name {
let input = if !$boolean { let input = if !$boolean {
require!( require!(
ret_ty == in_elem, ret_ty == in_elem,
@ -1954,7 +1990,7 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
ty::Int(_) | ty::Uint(_) => {} ty::Int(_) | ty::Uint(_) => {}
_ => return_error!( _ => return_error!(
"unsupported {} from `{}` with element `{}` to `{}`", "unsupported {} from `{}` with element `{}` to `{}`",
$name, sym::$name,
in_ty, in_ty,
in_elem, in_elem,
ret_ty ret_ty
@ -1973,7 +2009,7 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
} }
_ => return_error!( _ => return_error!(
"unsupported {} from `{}` with element `{}` to `{}`", "unsupported {} from `{}` with element `{}` to `{}`",
$name, sym::$name,
in_ty, in_ty,
in_elem, in_elem,
ret_ty ret_ty
@ -1983,13 +2019,13 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
}; };
} }
bitwise_red!("simd_reduce_and": vector_reduce_and, false); bitwise_red!(simd_reduce_and: vector_reduce_and, false);
bitwise_red!("simd_reduce_or": vector_reduce_or, false); bitwise_red!(simd_reduce_or: vector_reduce_or, false);
bitwise_red!("simd_reduce_xor": vector_reduce_xor, false); bitwise_red!(simd_reduce_xor: vector_reduce_xor, false);
bitwise_red!("simd_reduce_all": vector_reduce_and, true); bitwise_red!(simd_reduce_all: vector_reduce_and, true);
bitwise_red!("simd_reduce_any": vector_reduce_or, true); bitwise_red!(simd_reduce_any: vector_reduce_or, true);
if name == "simd_cast" { if name == sym::simd_cast {
require_simd!(ret_ty, "return"); require_simd!(ret_ty, "return");
let out_len = ret_ty.simd_size(tcx); let out_len = ret_ty.simd_size(tcx);
require!( require!(
@ -2077,7 +2113,7 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
} }
macro_rules! arith { macro_rules! arith {
($($name: ident: $($($p: ident),* => $call: ident),*;)*) => { ($($name: ident: $($($p: ident),* => $call: ident),*;)*) => {
$(if name == stringify!($name) { $(if name == sym::$name {
match in_elem.kind { match in_elem.kind {
$($(ty::$p(_))|* => { $($(ty::$p(_))|* => {
return Ok(bx.$call(args[0].immediate(), args[1].immediate())) return Ok(bx.$call(args[0].immediate(), args[1].immediate()))
@ -2107,10 +2143,10 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
} }
if name == "simd_saturating_add" || name == "simd_saturating_sub" { if name == sym::simd_saturating_add || name == sym::simd_saturating_sub {
let lhs = args[0].immediate(); let lhs = args[0].immediate();
let rhs = args[1].immediate(); let rhs = args[1].immediate();
let is_add = name == "simd_saturating_add"; let is_add = name == sym::simd_saturating_add;
let ptr_bits = bx.tcx().data_layout.pointer_size.bits() as _; let ptr_bits = bx.tcx().data_layout.pointer_size.bits() as _;
let (signed, elem_width, elem_ty) = match in_elem.kind { let (signed, elem_width, elem_ty) = match in_elem.kind {
ty::Int(i) => (true, i.bit_width().unwrap_or(ptr_bits), bx.cx.type_int_from_ty(i)), ty::Int(i) => (true, i.bit_width().unwrap_or(ptr_bits), bx.cx.type_int_from_ty(i)),

View file

@ -16,6 +16,7 @@ use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
use rustc_middle::ty::Instance; use rustc_middle::ty::Instance;
use rustc_middle::ty::{SymbolName, TyCtxt}; use rustc_middle::ty::{SymbolName, TyCtxt};
use rustc_session::config::{CrateType, SanitizerSet}; use rustc_session::config::{CrateType, SanitizerSet};
use rustc_span::symbol::sym;
pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel { pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel {
crates_export_threshold(&tcx.sess.crate_types()) crates_export_threshold(&tcx.sess.crate_types())
@ -107,7 +108,7 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
}) })
.map(|def_id| { .map(|def_id| {
let export_level = if special_runtime_crate { let export_level = if special_runtime_crate {
let name = tcx.symbol_name(Instance::mono(tcx, def_id.to_def_id())).name.as_str(); let name = tcx.symbol_name(Instance::mono(tcx, def_id.to_def_id())).name;
// We can probably do better here by just ensuring that // We can probably do better here by just ensuring that
// it has hidden visibility rather than public // it has hidden visibility rather than public
// visibility, as this is primarily here to ensure it's // visibility, as this is primarily here to ensure it's
@ -115,13 +116,12 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
// //
// In general though we won't link right if these // In general though we won't link right if these
// symbols are stripped, and LTO currently strips them. // symbols are stripped, and LTO currently strips them.
if name == "rust_eh_personality" match name {
|| name == "rust_eh_register_frames" sym::rust_eh_personality
|| name == "rust_eh_unregister_frames" | sym::rust_eh_register_frames
{ | sym::rust_eh_unregister_frames =>
SymbolExportLevel::C SymbolExportLevel::C,
} else { _ => SymbolExportLevel::Rust,
SymbolExportLevel::Rust
} }
} else { } else {
symbol_export_level(tcx, def_id.to_def_id()) symbol_export_level(tcx, def_id.to_def_id())

View file

@ -17,7 +17,8 @@ use rustc_middle::mir::interpret::{AllocId, ConstValue, Pointer, Scalar};
use rustc_middle::mir::AssertKind; use rustc_middle::mir::AssertKind;
use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt}; use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt};
use rustc_middle::ty::{self, Instance, Ty, TypeFoldable}; use rustc_middle::ty::{self, Instance, Ty, TypeFoldable};
use rustc_span::{source_map::Span, symbol::Symbol}; use rustc_span::source_map::Span;
use rustc_span::{sym, Symbol};
use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode}; use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode};
use rustc_target::abi::{self, LayoutOf}; use rustc_target::abi::{self, LayoutOf};
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
@ -445,7 +446,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
&mut self, &mut self,
helper: &TerminatorCodegenHelper<'tcx>, helper: &TerminatorCodegenHelper<'tcx>,
bx: &mut Bx, bx: &mut Bx,
intrinsic: Option<&str>, intrinsic: Option<Symbol>,
instance: Option<Instance<'tcx>>, instance: Option<Instance<'tcx>>,
span: Span, span: Span,
destination: &Option<(mir::Place<'tcx>, mir::BasicBlock)>, destination: &Option<(mir::Place<'tcx>, mir::BasicBlock)>,
@ -461,10 +462,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
UninitValid, UninitValid,
}; };
let panic_intrinsic = intrinsic.and_then(|i| match i { let panic_intrinsic = intrinsic.and_then(|i| match i {
// FIXME: Move to symbols instead of strings. sym::assert_inhabited => Some(AssertIntrinsic::Inhabited),
"assert_inhabited" => Some(AssertIntrinsic::Inhabited), sym::assert_zero_valid => Some(AssertIntrinsic::ZeroValid),
"assert_zero_valid" => Some(AssertIntrinsic::ZeroValid), sym::assert_uninit_valid => Some(AssertIntrinsic::UninitValid),
"assert_uninit_valid" => Some(AssertIntrinsic::UninitValid),
_ => None, _ => None,
}); });
if let Some(intrinsic) = panic_intrinsic { if let Some(intrinsic) = panic_intrinsic {
@ -568,10 +568,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// Handle intrinsics old codegen wants Expr's for, ourselves. // Handle intrinsics old codegen wants Expr's for, ourselves.
let intrinsic = match def { let intrinsic = match def {
Some(ty::InstanceDef::Intrinsic(def_id)) => Some(bx.tcx().item_name(def_id).as_str()), Some(ty::InstanceDef::Intrinsic(def_id)) => Some(bx.tcx().item_name(def_id)),
_ => None, _ => None,
}; };
let intrinsic = intrinsic.as_ref().map(|s| &s[..]);
let extra_args = &args[sig.inputs().skip_binder().len()..]; let extra_args = &args[sig.inputs().skip_binder().len()..];
let extra_args = extra_args let extra_args = extra_args
@ -587,7 +586,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
None => FnAbi::of_fn_ptr(&bx, sig, &extra_args), None => FnAbi::of_fn_ptr(&bx, sig, &extra_args),
}; };
if intrinsic == Some("transmute") { if intrinsic == Some(sym::transmute) {
if let Some(destination_ref) = destination.as_ref() { if let Some(destination_ref) = destination.as_ref() {
let &(dest, target) = destination_ref; let &(dest, target) = destination_ref;
self.codegen_transmute(&mut bx, &args[0], dest); self.codegen_transmute(&mut bx, &args[0], dest);
@ -607,7 +606,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
} }
// For normal codegen, this Miri-specific intrinsic should never occur. // For normal codegen, this Miri-specific intrinsic should never occur.
if intrinsic == Some("miri_start_panic") { if intrinsic == Some(sym::miri_start_panic) {
bug!("`miri_start_panic` should never end up in compiled code"); bug!("`miri_start_panic` should never end up in compiled code");
} }
@ -635,7 +634,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
ReturnDest::Nothing ReturnDest::Nothing
}; };
if intrinsic == Some("caller_location") { if intrinsic == Some(sym::caller_location) {
if let Some((_, target)) = destination.as_ref() { if let Some((_, target)) = destination.as_ref() {
let location = self.get_caller_location(&mut bx, fn_span); let location = self.get_caller_location(&mut bx, fn_span);
@ -650,7 +649,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
return; return;
} }
if intrinsic.is_some() && intrinsic != Some("drop_in_place") { if intrinsic.is_some() && intrinsic != Some(sym::drop_in_place) {
let intrinsic = intrinsic.unwrap(); let intrinsic = intrinsic.unwrap();
// `is_codegen_intrinsic()` allows the backend implementation to perform compile-time // `is_codegen_intrinsic()` allows the backend implementation to perform compile-time
@ -682,7 +681,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// third argument must be constant. This is // third argument must be constant. This is
// checked by const-qualification, which also // checked by const-qualification, which also
// promotes any complex rvalues to constants. // promotes any complex rvalues to constants.
if i == 2 && intrinsic.starts_with("simd_shuffle") { if i == 2 && intrinsic.as_str().starts_with("simd_shuffle") {
if let mir::Operand::Constant(constant) = arg { if let mir::Operand::Constant(constant) = arg {
let c = self.eval_mir_constant(constant); let c = self.eval_mir_constant(constant);
let (llval, ty) = self.simd_shuffle_indices( let (llval, ty) = self.simd_shuffle_indices(

View file

@ -2,7 +2,7 @@ use super::BackendTypes;
use crate::mir::operand::OperandRef; use crate::mir::operand::OperandRef;
use rustc_middle::mir::Operand; use rustc_middle::mir::Operand;
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty};
use rustc_span::Span; use rustc_span::{Span, Symbol};
use rustc_target::abi::call::FnAbi; use rustc_target::abi::call::FnAbi;
pub trait IntrinsicCallMethods<'tcx>: BackendTypes { pub trait IntrinsicCallMethods<'tcx>: BackendTypes {
@ -24,7 +24,7 @@ pub trait IntrinsicCallMethods<'tcx>: BackendTypes {
/// the intrinsic does not need code generation. /// the intrinsic does not need code generation.
fn is_codegen_intrinsic( fn is_codegen_intrinsic(
&mut self, &mut self,
intrinsic: &str, intrinsic: Symbol,
args: &Vec<Operand<'tcx>>, args: &Vec<Operand<'tcx>>,
caller_instance: ty::Instance<'tcx>, caller_instance: ty::Instance<'tcx>,
) -> bool; ) -> bool;

View file

@ -698,7 +698,7 @@ impl RustcDefaultCalls {
.parse_sess .parse_sess
.config .config
.iter() .iter()
.filter_map(|&(name, ref value)| { .filter_map(|&(name, value)| {
// Note that crt-static is a specially recognized cfg // Note that crt-static is a specially recognized cfg
// directive that's printed out here as part of // directive that's printed out here as part of
// rust-lang/rust#37406, but in general the // rust-lang/rust#37406, but in general the
@ -707,9 +707,7 @@ impl RustcDefaultCalls {
// specifically allowing the crt-static cfg and that's // specifically allowing the crt-static cfg and that's
// it, this is intended to get into Cargo and then go // it, this is intended to get into Cargo and then go
// through to build scripts. // through to build scripts.
let value = value.as_ref().map(|s| s.as_str()); if (name != sym::target_feature || value != Some(sym::crt_dash_static))
let value = value.as_ref().map(|s| s.as_ref());
if (name != sym::target_feature || value != Some("crt-static"))
&& !allow_unstable_cfg && !allow_unstable_cfg
&& find_gated_cfg(|cfg_sym| cfg_sym == name).is_some() && find_gated_cfg(|cfg_sym| cfg_sym == name).is_some()
{ {

View file

@ -16,7 +16,7 @@ use rustc_ast::ast;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_macros::HashStable_Generic; use rustc_macros::HashStable_Generic;
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::Span; use rustc_span::Span;
use lazy_static::lazy_static; use lazy_static::lazy_static;
@ -52,10 +52,10 @@ macro_rules! language_item_table {
} }
impl LangItem { impl LangItem {
/// Returns the `name` in `#[lang = "$name"]`. /// Returns the `name` symbol in `#[lang = "$name"]`.
/// For example, `LangItem::EqTraitLangItem`, /// For example, `LangItem::EqTraitLangItem`,
/// that is `#[lang = "eq"]` would result in `"eq"`. /// that is `#[lang = "eq"]` would result in `sym::eq`.
pub fn name(self) -> &'static str { pub fn name(self) -> Symbol {
match self { match self {
$( $variant => $name, )* $( $variant => $name, )*
} }
@ -110,9 +110,8 @@ macro_rules! language_item_table {
} }
$( $(
/// Returns the corresponding `DefId` for the lang item /// Returns the corresponding `DefId` for the lang item if it
#[doc = $name] /// exists.
/// if it exists.
#[allow(dead_code)] #[allow(dead_code)]
pub fn $method(&self) -> Option<DefId> { pub fn $method(&self) -> Option<DefId> {
self.items[$variant as usize] self.items[$variant as usize]
@ -122,7 +121,7 @@ macro_rules! language_item_table {
lazy_static! { lazy_static! {
/// A mapping from the name of the lang item to its order and the form it must be of. /// A mapping from the name of the lang item to its order and the form it must be of.
pub static ref ITEM_REFS: FxHashMap<&'static str, (usize, Target)> = { pub static ref ITEM_REFS: FxHashMap<Symbol, (usize, Target)> = {
let mut item_refs = FxHashMap::default(); let mut item_refs = FxHashMap::default();
$( item_refs.insert($name, ($variant as usize, $target)); )* $( item_refs.insert($name, ($variant as usize, $target)); )*
item_refs item_refs
@ -154,100 +153,100 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
} }
language_item_table! { language_item_table! {
// Variant name, Name, Method name, Target; // Variant name, Name, Method name, Target;
BoolImplItem, "bool", bool_impl, Target::Impl; BoolImplItem, sym::bool, bool_impl, Target::Impl;
CharImplItem, "char", char_impl, Target::Impl; CharImplItem, sym::char, char_impl, Target::Impl;
StrImplItem, "str", str_impl, Target::Impl; StrImplItem, sym::str, str_impl, Target::Impl;
SliceImplItem, "slice", slice_impl, Target::Impl; SliceImplItem, sym::slice, slice_impl, Target::Impl;
SliceU8ImplItem, "slice_u8", slice_u8_impl, Target::Impl; SliceU8ImplItem, sym::slice_u8, slice_u8_impl, Target::Impl;
StrAllocImplItem, "str_alloc", str_alloc_impl, Target::Impl; StrAllocImplItem, sym::str_alloc, str_alloc_impl, Target::Impl;
SliceAllocImplItem, "slice_alloc", slice_alloc_impl, Target::Impl; SliceAllocImplItem, sym::slice_alloc, slice_alloc_impl, Target::Impl;
SliceU8AllocImplItem, "slice_u8_alloc", slice_u8_alloc_impl, Target::Impl; SliceU8AllocImplItem, sym::slice_u8_alloc, slice_u8_alloc_impl, Target::Impl;
ConstPtrImplItem, "const_ptr", const_ptr_impl, Target::Impl; ConstPtrImplItem, sym::const_ptr, const_ptr_impl, Target::Impl;
MutPtrImplItem, "mut_ptr", mut_ptr_impl, Target::Impl; MutPtrImplItem, sym::mut_ptr, mut_ptr_impl, Target::Impl;
ConstSlicePtrImplItem, "const_slice_ptr", const_slice_ptr_impl, Target::Impl; ConstSlicePtrImplItem, sym::const_slice_ptr, const_slice_ptr_impl, Target::Impl;
MutSlicePtrImplItem, "mut_slice_ptr", mut_slice_ptr_impl, Target::Impl; MutSlicePtrImplItem, sym::mut_slice_ptr, mut_slice_ptr_impl, Target::Impl;
I8ImplItem, "i8", i8_impl, Target::Impl; I8ImplItem, sym::i8, i8_impl, Target::Impl;
I16ImplItem, "i16", i16_impl, Target::Impl; I16ImplItem, sym::i16, i16_impl, Target::Impl;
I32ImplItem, "i32", i32_impl, Target::Impl; I32ImplItem, sym::i32, i32_impl, Target::Impl;
I64ImplItem, "i64", i64_impl, Target::Impl; I64ImplItem, sym::i64, i64_impl, Target::Impl;
I128ImplItem, "i128", i128_impl, Target::Impl; I128ImplItem, sym::i128, i128_impl, Target::Impl;
IsizeImplItem, "isize", isize_impl, Target::Impl; IsizeImplItem, sym::isize, isize_impl, Target::Impl;
U8ImplItem, "u8", u8_impl, Target::Impl; U8ImplItem, sym::u8, u8_impl, Target::Impl;
U16ImplItem, "u16", u16_impl, Target::Impl; U16ImplItem, sym::u16, u16_impl, Target::Impl;
U32ImplItem, "u32", u32_impl, Target::Impl; U32ImplItem, sym::u32, u32_impl, Target::Impl;
U64ImplItem, "u64", u64_impl, Target::Impl; U64ImplItem, sym::u64, u64_impl, Target::Impl;
U128ImplItem, "u128", u128_impl, Target::Impl; U128ImplItem, sym::u128, u128_impl, Target::Impl;
UsizeImplItem, "usize", usize_impl, Target::Impl; UsizeImplItem, sym::usize, usize_impl, Target::Impl;
F32ImplItem, "f32", f32_impl, Target::Impl; F32ImplItem, sym::f32, f32_impl, Target::Impl;
F64ImplItem, "f64", f64_impl, Target::Impl; F64ImplItem, sym::f64, f64_impl, Target::Impl;
F32RuntimeImplItem, "f32_runtime", f32_runtime_impl, Target::Impl; F32RuntimeImplItem, sym::f32_runtime, f32_runtime_impl, Target::Impl;
F64RuntimeImplItem, "f64_runtime", f64_runtime_impl, Target::Impl; F64RuntimeImplItem, sym::f64_runtime, f64_runtime_impl, Target::Impl;
SizedTraitLangItem, "sized", sized_trait, Target::Trait; SizedTraitLangItem, sym::sized, sized_trait, Target::Trait;
UnsizeTraitLangItem, "unsize", unsize_trait, Target::Trait; UnsizeTraitLangItem, sym::unsize, unsize_trait, Target::Trait;
// trait injected by #[derive(PartialEq)], (i.e. "Partial EQ"). // trait injected by #[derive(PartialEq)], (i.e. "Partial EQ").
StructuralPeqTraitLangItem, "structural_peq", structural_peq_trait, Target::Trait; StructuralPeqTraitLangItem, sym::structural_peq, structural_peq_trait, Target::Trait;
// trait injected by #[derive(Eq)], (i.e. "Total EQ"; no, I will not apologize). // trait injected by #[derive(Eq)], (i.e. "Total EQ"; no, I will not apologize).
StructuralTeqTraitLangItem, "structural_teq", structural_teq_trait, Target::Trait; StructuralTeqTraitLangItem, sym::structural_teq, structural_teq_trait, Target::Trait;
CopyTraitLangItem, "copy", copy_trait, Target::Trait; CopyTraitLangItem, sym::copy, copy_trait, Target::Trait;
CloneTraitLangItem, "clone", clone_trait, Target::Trait; CloneTraitLangItem, sym::clone, clone_trait, Target::Trait;
SyncTraitLangItem, "sync", sync_trait, Target::Trait; SyncTraitLangItem, sym::sync, sync_trait, Target::Trait;
DiscriminantKindTraitLangItem,"discriminant_kind", discriminant_kind_trait, Target::Trait; DiscriminantKindTraitLangItem, sym::discriminant_kind, discriminant_kind_trait, Target::Trait;
FreezeTraitLangItem, "freeze", freeze_trait, Target::Trait; FreezeTraitLangItem, sym::freeze, freeze_trait, Target::Trait;
DropTraitLangItem, "drop", drop_trait, Target::Trait; DropTraitLangItem, sym::drop, drop_trait, Target::Trait;
CoerceUnsizedTraitLangItem, "coerce_unsized", coerce_unsized_trait, Target::Trait; CoerceUnsizedTraitLangItem, sym::coerce_unsized, coerce_unsized_trait, Target::Trait;
DispatchFromDynTraitLangItem,"dispatch_from_dyn", dispatch_from_dyn_trait, Target::Trait; DispatchFromDynTraitLangItem, sym::dispatch_from_dyn, dispatch_from_dyn_trait, Target::Trait;
AddTraitLangItem(Op), "add", add_trait, Target::Trait; AddTraitLangItem(Op), sym::add, add_trait, Target::Trait;
SubTraitLangItem(Op), "sub", sub_trait, Target::Trait; SubTraitLangItem(Op), sym::sub, sub_trait, Target::Trait;
MulTraitLangItem(Op), "mul", mul_trait, Target::Trait; MulTraitLangItem(Op), sym::mul, mul_trait, Target::Trait;
DivTraitLangItem(Op), "div", div_trait, Target::Trait; DivTraitLangItem(Op), sym::div, div_trait, Target::Trait;
RemTraitLangItem(Op), "rem", rem_trait, Target::Trait; RemTraitLangItem(Op), sym::rem, rem_trait, Target::Trait;
NegTraitLangItem(Op), "neg", neg_trait, Target::Trait; NegTraitLangItem(Op), sym::neg, neg_trait, Target::Trait;
NotTraitLangItem(Op), "not", not_trait, Target::Trait; NotTraitLangItem(Op), sym::not, not_trait, Target::Trait;
BitXorTraitLangItem(Op), "bitxor", bitxor_trait, Target::Trait; BitXorTraitLangItem(Op), sym::bitxor, bitxor_trait, Target::Trait;
BitAndTraitLangItem(Op), "bitand", bitand_trait, Target::Trait; BitAndTraitLangItem(Op), sym::bitand, bitand_trait, Target::Trait;
BitOrTraitLangItem(Op), "bitor", bitor_trait, Target::Trait; BitOrTraitLangItem(Op), sym::bitor, bitor_trait, Target::Trait;
ShlTraitLangItem(Op), "shl", shl_trait, Target::Trait; ShlTraitLangItem(Op), sym::shl, shl_trait, Target::Trait;
ShrTraitLangItem(Op), "shr", shr_trait, Target::Trait; ShrTraitLangItem(Op), sym::shr, shr_trait, Target::Trait;
AddAssignTraitLangItem(Op), "add_assign", add_assign_trait, Target::Trait; AddAssignTraitLangItem(Op), sym::add_assign, add_assign_trait, Target::Trait;
SubAssignTraitLangItem(Op), "sub_assign", sub_assign_trait, Target::Trait; SubAssignTraitLangItem(Op), sym::sub_assign, sub_assign_trait, Target::Trait;
MulAssignTraitLangItem(Op), "mul_assign", mul_assign_trait, Target::Trait; MulAssignTraitLangItem(Op), sym::mul_assign, mul_assign_trait, Target::Trait;
DivAssignTraitLangItem(Op), "div_assign", div_assign_trait, Target::Trait; DivAssignTraitLangItem(Op), sym::div_assign, div_assign_trait, Target::Trait;
RemAssignTraitLangItem(Op), "rem_assign", rem_assign_trait, Target::Trait; RemAssignTraitLangItem(Op), sym::rem_assign, rem_assign_trait, Target::Trait;
BitXorAssignTraitLangItem(Op),"bitxor_assign", bitxor_assign_trait, Target::Trait; BitXorAssignTraitLangItem(Op), sym::bitxor_assign, bitxor_assign_trait, Target::Trait;
BitAndAssignTraitLangItem(Op),"bitand_assign", bitand_assign_trait, Target::Trait; BitAndAssignTraitLangItem(Op), sym::bitand_assign, bitand_assign_trait, Target::Trait;
BitOrAssignTraitLangItem(Op),"bitor_assign", bitor_assign_trait, Target::Trait; BitOrAssignTraitLangItem(Op), sym::bitor_assign, bitor_assign_trait, Target::Trait;
ShlAssignTraitLangItem(Op), "shl_assign", shl_assign_trait, Target::Trait; ShlAssignTraitLangItem(Op), sym::shl_assign, shl_assign_trait, Target::Trait;
ShrAssignTraitLangItem(Op), "shr_assign", shr_assign_trait, Target::Trait; ShrAssignTraitLangItem(Op), sym::shr_assign, shr_assign_trait, Target::Trait;
IndexTraitLangItem(Op), "index", index_trait, Target::Trait; IndexTraitLangItem(Op), sym::index, index_trait, Target::Trait;
IndexMutTraitLangItem(Op), "index_mut", index_mut_trait, Target::Trait; IndexMutTraitLangItem(Op), sym::index_mut, index_mut_trait, Target::Trait;
UnsafeCellTypeLangItem, "unsafe_cell", unsafe_cell_type, Target::Struct; UnsafeCellTypeLangItem, sym::unsafe_cell, unsafe_cell_type, Target::Struct;
VaListTypeLangItem, "va_list", va_list, Target::Struct; VaListTypeLangItem, sym::va_list, va_list, Target::Struct;
DerefTraitLangItem, "deref", deref_trait, Target::Trait; DerefTraitLangItem, sym::deref, deref_trait, Target::Trait;
DerefMutTraitLangItem, "deref_mut", deref_mut_trait, Target::Trait; DerefMutTraitLangItem, sym::deref_mut, deref_mut_trait, Target::Trait;
ReceiverTraitLangItem, "receiver", receiver_trait, Target::Trait; ReceiverTraitLangItem, sym::receiver, receiver_trait, Target::Trait;
FnTraitLangItem, "fn", fn_trait, Target::Trait; FnTraitLangItem, kw::Fn, fn_trait, Target::Trait;
FnMutTraitLangItem, "fn_mut", fn_mut_trait, Target::Trait; FnMutTraitLangItem, sym::fn_mut, fn_mut_trait, Target::Trait;
FnOnceTraitLangItem, "fn_once", fn_once_trait, Target::Trait; FnOnceTraitLangItem, sym::fn_once, fn_once_trait, Target::Trait;
FnOnceOutputLangItem, "fn_once_output", fn_once_output, Target::AssocTy; FnOnceOutputLangItem, sym::fn_once_output, fn_once_output, Target::AssocTy;
FutureTraitLangItem, "future_trait", future_trait, Target::Trait; FutureTraitLangItem, sym::future_trait, future_trait, Target::Trait;
GeneratorStateLangItem, "generator_state", gen_state, Target::Enum; GeneratorStateLangItem, sym::generator_state, gen_state, Target::Enum;
GeneratorTraitLangItem, "generator", gen_trait, Target::Trait; GeneratorTraitLangItem, sym::generator, gen_trait, Target::Trait;
UnpinTraitLangItem, "unpin", unpin_trait, Target::Trait; UnpinTraitLangItem, sym::unpin, unpin_trait, Target::Trait;
PinTypeLangItem, "pin", pin_type, Target::Struct; PinTypeLangItem, sym::pin, pin_type, Target::Struct;
// Don't be fooled by the naming here: this lang item denotes `PartialEq`, not `Eq`. // Don't be fooled by the naming here: this lang item denotes `PartialEq`, not `Eq`.
EqTraitLangItem, "eq", eq_trait, Target::Trait; EqTraitLangItem, sym::eq, eq_trait, Target::Trait;
PartialOrdTraitLangItem, "partial_ord", partial_ord_trait, Target::Trait; PartialOrdTraitLangItem, sym::partial_ord, partial_ord_trait, Target::Trait;
// A number of panic-related lang items. The `panic` item corresponds to // A number of panic-related lang items. The `panic` item corresponds to
// divide-by-zero and various panic cases with `match`. The // divide-by-zero and various panic cases with `match`. The
@ -258,39 +257,39 @@ language_item_table! {
// defined to use it, but a final product is required to define it // defined to use it, but a final product is required to define it
// somewhere. Additionally, there are restrictions on crates that use a weak // somewhere. Additionally, there are restrictions on crates that use a weak
// lang item, but do not have it defined. // lang item, but do not have it defined.
PanicFnLangItem, "panic", panic_fn, Target::Fn; PanicFnLangItem, sym::panic, panic_fn, Target::Fn;
PanicBoundsCheckFnLangItem, "panic_bounds_check", panic_bounds_check_fn, Target::Fn; PanicBoundsCheckFnLangItem, sym::panic_bounds_check, panic_bounds_check_fn, Target::Fn;
PanicInfoLangItem, "panic_info", panic_info, Target::Struct; PanicInfoLangItem, sym::panic_info, panic_info, Target::Struct;
PanicLocationLangItem, "panic_location", panic_location, Target::Struct; PanicLocationLangItem, sym::panic_location, panic_location, Target::Struct;
PanicImplLangItem, "panic_impl", panic_impl, Target::Fn; PanicImplLangItem, sym::panic_impl, panic_impl, Target::Fn;
// Libstd panic entry point. Necessary for const eval to be able to catch it // Libstd panic entry point. Necessary for const eval to be able to catch it
BeginPanicFnLangItem, "begin_panic", begin_panic_fn, Target::Fn; BeginPanicFnLangItem, sym::begin_panic, begin_panic_fn, Target::Fn;
ExchangeMallocFnLangItem, "exchange_malloc", exchange_malloc_fn, Target::Fn; ExchangeMallocFnLangItem, sym::exchange_malloc, exchange_malloc_fn, Target::Fn;
BoxFreeFnLangItem, "box_free", box_free_fn, Target::Fn; BoxFreeFnLangItem, sym::box_free, box_free_fn, Target::Fn;
DropInPlaceFnLangItem, "drop_in_place", drop_in_place_fn, Target::Fn; DropInPlaceFnLangItem, sym::drop_in_place, drop_in_place_fn, Target::Fn;
OomLangItem, "oom", oom, Target::Fn; OomLangItem, sym::oom, oom, Target::Fn;
AllocLayoutLangItem, "alloc_layout", alloc_layout, Target::Struct; AllocLayoutLangItem, sym::alloc_layout, alloc_layout, Target::Struct;
StartFnLangItem, "start", start_fn, Target::Fn; StartFnLangItem, sym::start, start_fn, Target::Fn;
CountCodeRegionFnLangItem, "count_code_region", count_code_region_fn, Target::Fn; CountCodeRegionFnLangItem, sym::count_code_region, count_code_region_fn, Target::Fn;
EhPersonalityLangItem, "eh_personality", eh_personality, Target::Fn; EhPersonalityLangItem, sym::eh_personality, eh_personality, Target::Fn;
EhCatchTypeinfoLangItem, "eh_catch_typeinfo", eh_catch_typeinfo, Target::Static; EhCatchTypeinfoLangItem, sym::eh_catch_typeinfo, eh_catch_typeinfo, Target::Static;
OwnedBoxLangItem, "owned_box", owned_box, Target::Struct; OwnedBoxLangItem, sym::owned_box, owned_box, Target::Struct;
PhantomDataItem, "phantom_data", phantom_data, Target::Struct; PhantomDataItem, sym::phantom_data, phantom_data, Target::Struct;
ManuallyDropItem, "manually_drop", manually_drop, Target::Struct; ManuallyDropItem, sym::manually_drop, manually_drop, Target::Struct;
MaybeUninitLangItem, "maybe_uninit", maybe_uninit, Target::Union; MaybeUninitLangItem, sym::maybe_uninit, maybe_uninit, Target::Union;
// Align offset for stride != 1; must not panic. // Align offset for stride != 1; must not panic.
AlignOffsetLangItem, "align_offset", align_offset_fn, Target::Fn; AlignOffsetLangItem, sym::align_offset, align_offset_fn, Target::Fn;
TerminationTraitLangItem, "termination", termination, Target::Trait; TerminationTraitLangItem, sym::termination, termination, Target::Trait;
TryTraitLangItem, "try", try_trait, Target::Trait; TryTraitLangItem, kw::Try, try_trait, Target::Trait;
} }

View file

@ -62,11 +62,11 @@ impl AssertModuleSource<'tcx> {
} else if attr.check_name(sym::rustc_partition_codegened) { } else if attr.check_name(sym::rustc_partition_codegened) {
(CguReuse::No, ComparisonKind::Exact) (CguReuse::No, ComparisonKind::Exact)
} else if attr.check_name(sym::rustc_expected_cgu_reuse) { } else if attr.check_name(sym::rustc_expected_cgu_reuse) {
match &*self.field(attr, sym::kind).as_str() { match self.field(attr, sym::kind) {
"no" => (CguReuse::No, ComparisonKind::Exact), sym::no => (CguReuse::No, ComparisonKind::Exact),
"pre-lto" => (CguReuse::PreLto, ComparisonKind::Exact), sym::pre_dash_lto => (CguReuse::PreLto, ComparisonKind::Exact),
"post-lto" => (CguReuse::PostLto, ComparisonKind::Exact), sym::post_dash_lto => (CguReuse::PostLto, ComparisonKind::Exact),
"any" => (CguReuse::PreLto, ComparisonKind::AtLeast), sym::any => (CguReuse::PreLto, ComparisonKind::AtLeast),
other => { other => {
self.tcx.sess.span_fatal( self.tcx.sess.span_fatal(
attr.span, attr.span,

View file

@ -53,7 +53,7 @@ pub fn add_configuration(
cfg.extend(target_features.into_iter().map(|feat| (tf, Some(feat)))); cfg.extend(target_features.into_iter().map(|feat| (tf, Some(feat))));
if sess.crt_static(None) { if sess.crt_static(None) {
cfg.insert((tf, Some(Symbol::intern("crt-static")))); cfg.insert((tf, Some(sym::crt_dash_static)));
} }
} }

View file

@ -679,8 +679,8 @@ impl<'a> CrateLoader<'a> {
// in terms of everyone has a compatible panic runtime format, that's // in terms of everyone has a compatible panic runtime format, that's
// performed later as part of the `dependency_format` module. // performed later as part of the `dependency_format` module.
let name = match desired_strategy { let name = match desired_strategy {
PanicStrategy::Unwind => Symbol::intern("panic_unwind"), PanicStrategy::Unwind => sym::panic_unwind,
PanicStrategy::Abort => Symbol::intern("panic_abort"), PanicStrategy::Abort => sym::panic_abort,
}; };
info!("panic runtime not found -- loading {}", name); info!("panic runtime not found -- loading {}", name);
@ -713,7 +713,7 @@ impl<'a> CrateLoader<'a> {
{ {
info!("loading profiler"); info!("loading profiler");
let name = Symbol::intern("profiler_builtins"); let name = sym::profiler_builtins;
let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None); let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None);
let data = self.cstore.get_crate_data(cnum); let data = self.cstore.get_crate_data(cnum);

View file

@ -2,7 +2,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty; use rustc_middle::ty;
use rustc_span::source_map::DesugaringKind; use rustc_span::source_map::DesugaringKind;
use rustc_span::{Span, Symbol}; use rustc_span::{sym, Span};
use crate::borrow_check::diagnostics::UseSpans; use crate::borrow_check::diagnostics::UseSpans;
use crate::borrow_check::prefixes::PrefixSet; use crate::borrow_check::prefixes::PrefixSet;
@ -394,10 +394,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
| ty::Opaque(def_id, _) => def_id, | ty::Opaque(def_id, _) => def_id,
_ => return err, _ => return err,
}; };
let is_option = let is_option = self.infcx.tcx.is_diagnostic_item(sym::option_type, def_id);
self.infcx.tcx.is_diagnostic_item(Symbol::intern("option_type"), def_id); let is_result = self.infcx.tcx.is_diagnostic_item(sym::result_type, def_id);
let is_result =
self.infcx.tcx.is_diagnostic_item(Symbol::intern("result_type"), def_id);
if (is_option || is_result) && use_spans.map_or(true, |v| !v.for_closure()) { if (is_option || is_result) && use_spans.map_or(true, |v| !v.for_closure()) {
err.span_suggestion( err.span_suggestion(
span, span,
@ -409,7 +407,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
); );
} else if matches!(span.desugaring_kind(), Some(DesugaringKind::ForLoop(_))) } else if matches!(span.desugaring_kind(), Some(DesugaringKind::ForLoop(_)))
&& self.infcx.tcx.is_diagnostic_item(Symbol::intern("vec_type"), def_id) && self.infcx.tcx.is_diagnostic_item(sym::vec_type, def_id)
{ {
// FIXME: suggest for anything that implements `IntoIterator`. // FIXME: suggest for anything that implements `IntoIterator`.
err.span_suggestion( err.span_suggestion(

View file

@ -57,7 +57,7 @@ impl LanguageItemCollector<'tcx> {
fn check_for_lang(&mut self, actual_target: Target, hir_id: HirId, attrs: &[Attribute]) { fn check_for_lang(&mut self, actual_target: Target, hir_id: HirId, attrs: &[Attribute]) {
if let Some((value, span)) = extract(&attrs) { if let Some((value, span)) = extract(&attrs) {
match ITEM_REFS.get(&*value.as_str()).cloned() { match ITEM_REFS.get(&value).cloned() {
// Known lang item with attribute on correct target. // Known lang item with attribute on correct target.
Some((item_index, expected_target)) if actual_target == expected_target => { Some((item_index, expected_target)) if actual_target == expected_target => {
let def_id = self.tcx.hir().local_def_id(hir_id); let def_id = self.tcx.hir().local_def_id(hir_id);

View file

@ -620,7 +620,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
// available as we'd like it to be. // available as we'd like it to be.
// FIXME: only remove `libc` when `stdbuild` is active. // FIXME: only remove `libc` when `stdbuild` is active.
// FIXME: remove special casing for `test`. // FIXME: remove special casing for `test`.
remaining_lib_features.remove(&Symbol::intern("libc")); remaining_lib_features.remove(&sym::libc);
remaining_lib_features.remove(&sym::test); remaining_lib_features.remove(&sym::test);
let check_features = |remaining_lib_features: &mut FxHashMap<_, _>, defined_features: &[_]| { let check_features = |remaining_lib_features: &mut FxHashMap<_, _>, defined_features: &[_]| {

View file

@ -81,7 +81,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
// `core::intrinsics::code_count_region()` is (currently) the only `extern` lang item // `core::intrinsics::code_count_region()` is (currently) the only `extern` lang item
// that is never actually linked. It is not a `weak_lang_item` that can be registered // that is never actually linked. It is not a `weak_lang_item` that can be registered
// when used, and should be registered here instead. // when used, and should be registered here instead.
if let Some((item_index, _)) = ITEM_REFS.get(&*name.as_str()).cloned() { if let Some((item_index, _)) = ITEM_REFS.get(&name).cloned() {
if self.items.items[item_index].is_none() { if self.items.items[item_index].is_none() {
let item_def_id = self.tcx.hir().local_def_id(hir_id).to_def_id(); let item_def_id = self.tcx.hir().local_def_id(hir_id).to_def_id();
self.items.items[item_index] = Some(item_def_id); self.items.items[item_index] = Some(item_def_id);

View file

@ -16,7 +16,7 @@ use rustc_middle::ty::{self, DefIdTree};
use rustc_session::Session; use rustc_session::Session;
use rustc_span::hygiene::MacroKind; use rustc_span::hygiene::MacroKind;
use rustc_span::source_map::SourceMap; use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{BytePos, MultiSpan, Span}; use rustc_span::{BytePos, MultiSpan, Span};
use crate::imports::{Import, ImportKind, ImportResolver}; use crate::imports::{Import, ImportKind, ImportResolver};
@ -882,8 +882,7 @@ impl<'a> Resolver<'a> {
); );
self.add_typo_suggestion(err, suggestion, ident.span); self.add_typo_suggestion(err, suggestion, ident.span);
if macro_kind == MacroKind::Derive && (ident.as_str() == "Send" || ident.as_str() == "Sync") if macro_kind == MacroKind::Derive && (ident.name == sym::Send || ident.name == sym::Sync) {
{
let msg = format!("unsafe traits like `{}` should be implemented explicitly", ident); let msg = format!("unsafe traits like `{}` should be implemented explicitly", ident);
err.span_note(ident.span, &msg); err.span_note(ident.span, &msg);
} }

View file

@ -1034,8 +1034,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
let initial_res = source_bindings[ns].get().map(|initial_binding| { let initial_res = source_bindings[ns].get().map(|initial_binding| {
all_ns_err = false; all_ns_err = false;
if let Some(target_binding) = target_bindings[ns].get() { if let Some(target_binding) = target_bindings[ns].get() {
// Note that as_str() de-gensyms the Symbol if target.name == kw::Underscore
if target.name.as_str() == "_"
&& initial_binding.is_extern_crate() && initial_binding.is_extern_crate()
&& !initial_binding.is_import() && !initial_binding.is_import()
{ {

View file

@ -2364,7 +2364,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
if let Some(params) = error { if let Some(params) = error {
// If there's no lifetime available, suggest `'static`. // If there's no lifetime available, suggest `'static`.
if self.report_elision_failure(&mut err, params) && lifetime_names.is_empty() { if self.report_elision_failure(&mut err, params) && lifetime_names.is_empty() {
lifetime_names.insert(Ident::from_str("'static")); lifetime_names.insert(Ident::with_dummy_span(kw::StaticLifetime));
} }
} }
self.add_missing_lifetime_specifiers_label( self.add_missing_lifetime_specifiers_label(

View file

@ -717,18 +717,20 @@ pub fn default_configuration(sess: &Session) -> CrateConfig {
let mut ret = FxHashSet::default(); let mut ret = FxHashSet::default();
ret.reserve(6); // the minimum number of insertions ret.reserve(6); // the minimum number of insertions
// Target bindings. // Target bindings.
ret.insert((Symbol::intern("target_os"), Some(Symbol::intern(os)))); ret.insert((sym::target_os, Some(Symbol::intern(os))));
if let Some(ref fam) = sess.target.target.options.target_family { if let Some(ref fam) = sess.target.target.options.target_family {
ret.insert((Symbol::intern("target_family"), Some(Symbol::intern(fam)))); ret.insert((sym::target_family, Some(Symbol::intern(fam))));
if fam == "windows" || fam == "unix" { if fam == "windows" {
ret.insert((Symbol::intern(fam), None)); ret.insert((sym::windows, None));
} else if fam == "unix" {
ret.insert((sym::unix, None));
} }
} }
ret.insert((Symbol::intern("target_arch"), Some(Symbol::intern(arch)))); ret.insert((sym::target_arch, Some(Symbol::intern(arch))));
ret.insert((Symbol::intern("target_endian"), Some(Symbol::intern(end)))); ret.insert((sym::target_endian, Some(Symbol::intern(end))));
ret.insert((Symbol::intern("target_pointer_width"), Some(Symbol::intern(wordsz)))); ret.insert((sym::target_pointer_width, Some(Symbol::intern(wordsz))));
ret.insert((Symbol::intern("target_env"), Some(Symbol::intern(env)))); ret.insert((sym::target_env, Some(Symbol::intern(env))));
ret.insert((Symbol::intern("target_vendor"), Some(Symbol::intern(vendor)))); ret.insert((sym::target_vendor, Some(Symbol::intern(vendor))));
if sess.target.target.options.has_elf_tls { if sess.target.target.options.has_elf_tls {
ret.insert((sym::target_thread_local, None)); ret.insert((sym::target_thread_local, None));
} }
@ -754,7 +756,7 @@ pub fn default_configuration(sess: &Session) -> CrateConfig {
} }
if sess.opts.debug_assertions { if sess.opts.debug_assertions {
ret.insert((Symbol::intern("debug_assertions"), None)); ret.insert((sym::debug_assertions, None));
} }
if sess.opts.crate_types.contains(&CrateType::ProcMacro) { if sess.opts.crate_types.contains(&CrateType::ProcMacro) {
ret.insert((sym::proc_macro, None)); ret.insert((sym::proc_macro, None));

View file

@ -129,17 +129,23 @@ symbols! {
abi_x86_interrupt, abi_x86_interrupt,
abort, abort,
aborts, aborts,
add,
add_assign,
address, address,
add_with_overflow, add_with_overflow,
advanced_slice_patterns, advanced_slice_patterns,
adx_target_feature, adx_target_feature,
alias, alias,
align, align,
align_offset,
alignstack, alignstack,
all, all,
alloc,
allocator, allocator,
allocator_internals, allocator_internals,
alloc_error_handler, alloc_error_handler,
alloc_layout,
alloc_zeroed,
allow, allow,
allowed, allowed,
allow_fail, allow_fail,
@ -156,15 +162,18 @@ symbols! {
ArgumentV1, ArgumentV1,
arith_offset, arith_offset,
arm_target_feature, arm_target_feature,
array,
asm, asm,
assert, assert,
assert_inhabited, assert_inhabited,
assert_receiver_is_total_eq,
assert_uninit_valid, assert_uninit_valid,
assert_zero_valid, assert_zero_valid,
associated_consts, associated_consts,
associated_type_bounds, associated_type_bounds,
associated_type_defaults, associated_type_defaults,
associated_types, associated_types,
as_str,
assume, assume,
assume_init, assume_init,
async_await, async_await,
@ -183,19 +192,29 @@ symbols! {
bin, bin,
bind_by_move_pattern_guards, bind_by_move_pattern_guards,
bindings_after_at, bindings_after_at,
bitand,
bitand_assign,
bitor,
bitor_assign,
bitreverse, bitreverse,
bitxor,
bitxor_assign,
block, block,
bool, bool,
borrowck_graphviz_format, borrowck_graphviz_format,
borrowck_graphviz_postflow, borrowck_graphviz_postflow,
borrowck_graphviz_preflow, borrowck_graphviz_preflow,
box_free,
box_patterns, box_patterns,
box_syntax, box_syntax,
braced_empty_structs, braced_empty_structs,
breakpoint, breakpoint,
bswap, bswap,
C, C,
call,
caller_location, caller_location,
call_mut,
call_once,
cdylib, cdylib,
ceilf32, ceilf32,
ceilf64, ceilf64,
@ -219,6 +238,7 @@ symbols! {
closure_to_fn_coercion, closure_to_fn_coercion,
cmp, cmp,
cmpxchg16b_target_feature, cmpxchg16b_target_feature,
coerce_unsized,
cold, cold,
column, column,
compile_error, compile_error,
@ -243,8 +263,10 @@ symbols! {
const_mut_refs, const_mut_refs,
const_panic, const_panic,
const_precise_live_drops, const_precise_live_drops,
const_ptr,
const_raw_ptr_deref, const_raw_ptr_deref,
const_raw_ptr_to_usize_cast, const_raw_ptr_to_usize_cast,
const_slice_ptr,
const_trait_bound_opt_out, const_trait_bound_opt_out,
const_trait_impl, const_trait_impl,
const_transmute, const_transmute,
@ -271,6 +293,7 @@ symbols! {
crate_name, crate_name,
crate_type, crate_type,
crate_visibility_modifier, crate_visibility_modifier,
crt_dash_static: "crt-static",
ctlz, ctlz,
ctlz_nonzero, ctlz_nonzero,
ctpop, ctpop,
@ -281,12 +304,16 @@ symbols! {
custom_inner_attributes, custom_inner_attributes,
custom_test_frameworks, custom_test_frameworks,
c_variadic, c_variadic,
dead_code,
dealloc,
debug, debug,
Debug, Debug,
debug_assertions,
debug_trait, debug_trait,
declare_lint_pass, declare_lint_pass,
decl_macro, decl_macro,
Decodable, Decodable,
decode,
Default, Default,
default_lib_allocator, default_lib_allocator,
default_type_parameter_fallback, default_type_parameter_fallback,
@ -299,7 +326,11 @@ symbols! {
derive, derive,
diagnostic, diagnostic,
direct, direct,
discriminant_kind,
discriminant_value, discriminant_value,
dispatch_from_dyn,
div,
div_assign,
doc, doc,
doc_alias, doc_alias,
doc_cfg, doc_cfg,
@ -316,16 +347,19 @@ symbols! {
double_braced_impl: "{{impl}}", double_braced_impl: "{{impl}}",
double_braced_misc: "{{misc}}", double_braced_misc: "{{misc}}",
double_braced_opaque: "{{opaque}}", double_braced_opaque: "{{opaque}}",
drop,
dropck_eyepatch, dropck_eyepatch,
dropck_parametricity, dropck_parametricity,
drop_in_place, drop_in_place,
drop_types_in_const, drop_types_in_const,
dylib, dylib,
dyn_trait, dyn_trait,
eh_catch_typeinfo,
eh_personality, eh_personality,
enable, enable,
enclosing_scope, enclosing_scope,
Encodable, Encodable,
encode,
env, env,
eq, eq,
Eq, Eq,
@ -334,6 +368,7 @@ symbols! {
Err, Err,
exact_div, exact_div,
except, except,
exchange_malloc,
exclusive_range_pattern, exclusive_range_pattern,
exhaustive_integer_patterns, exhaustive_integer_patterns,
exhaustive_patterns, exhaustive_patterns,
@ -354,7 +389,9 @@ symbols! {
extern_types, extern_types,
f16c_target_feature, f16c_target_feature,
f32, f32,
f32_runtime,
f64, f64,
f64_runtime,
fabsf32, fabsf32,
fabsf64, fabsf64,
fadd_fast, fadd_fast,
@ -375,11 +412,15 @@ symbols! {
fmt_internals, fmt_internals,
fmul_fast, fmul_fast,
fn_must_use, fn_must_use,
fn_mut,
fn_once,
fn_once_output,
forbid, forbid,
forget, forget,
format_args, format_args,
format_args_capture, format_args_capture,
format_args_nl, format_args_nl,
freeze,
frem_fast, frem_fast,
from, from,
From, From,
@ -388,23 +429,30 @@ symbols! {
from_generator, from_generator,
from_method, from_method,
from_ok, from_ok,
from_size_align_unchecked,
from_trait, from_trait,
from_usize, from_usize,
fsub_fast, fsub_fast,
fundamental, fundamental,
future, future,
Future, Future,
future_trait,
FxHashMap, FxHashMap,
FxHashSet, FxHashSet,
ge,
generator,
generators, generators,
generator_state,
generic_associated_types, generic_associated_types,
generic_param_attrs, generic_param_attrs,
gen_future, gen_future,
gen_kill, gen_kill,
get_context, get_context,
GlobalAlloc,
global_allocator, global_allocator,
global_asm, global_asm,
globs, globs,
gt,
half_open_range_patterns, half_open_range_patterns,
hash, hash,
Hash, Hash,
@ -467,10 +515,13 @@ symbols! {
lang, lang,
lang_items, lang_items,
lateout, lateout,
Layout,
lazy_normalization_consts, lazy_normalization_consts,
le,
let_chains, let_chains,
lhs, lhs,
lib, lib,
libc,
lifetime, lifetime,
likely, likely,
line, line,
@ -495,6 +546,7 @@ symbols! {
logf64, logf64,
log_syntax, log_syntax,
loop_break_value, loop_break_value,
lt,
macro_at_most_once_rep, macro_at_most_once_rep,
macro_escape, macro_escape,
macro_export, macro_export,
@ -506,6 +558,7 @@ symbols! {
macro_vis_matcher, macro_vis_matcher,
main, main,
managed_boxes, managed_boxes,
manually_drop,
marker, marker,
marker_trait_attr, marker_trait_attr,
masked, masked,
@ -513,6 +566,7 @@ symbols! {
match_default_bindings, match_default_bindings,
maxnumf32, maxnumf32,
maxnumf64, maxnumf64,
maybe_uninit,
maybe_uninit_uninit, maybe_uninit_uninit,
maybe_uninit_zeroed, maybe_uninit_zeroed,
may_dangle, may_dangle,
@ -538,16 +592,22 @@ symbols! {
movbe_target_feature, movbe_target_feature,
move_ref_pattern, move_ref_pattern,
move_val_init, move_val_init,
mul,
mul_assign,
mul_with_overflow, mul_with_overflow,
must_use, must_use,
mut_ptr,
mut_slice_ptr,
naked, naked,
naked_functions, naked_functions,
name, name,
ne,
nearbyintf32, nearbyintf32,
nearbyintf64, nearbyintf64,
needs_allocator, needs_allocator,
needs_drop, needs_drop,
needs_panic_runtime, needs_panic_runtime,
neg,
negate_unsigned, negate_unsigned,
negative_impls, negative_impls,
never, never,
@ -557,6 +617,7 @@ symbols! {
__next, __next,
next, next,
nll, nll,
no,
no_builtins, no_builtins,
no_core, no_core,
no_crate_inject, no_crate_inject,
@ -590,6 +651,7 @@ symbols! {
on, on,
on_unimplemented, on_unimplemented,
oom, oom,
opaque,
ops, ops,
optimize, optimize,
optimize_attribute, optimize_attribute,
@ -598,6 +660,7 @@ symbols! {
Option, Option,
option_env, option_env,
options, options,
option_type,
opt_out_copy, opt_out_copy,
or, or,
Ord, Ord,
@ -606,22 +669,30 @@ symbols! {
out, out,
Output, Output,
overlapping_marker_traits, overlapping_marker_traits,
owned_box,
packed, packed,
panic, panic,
panic_abort,
panic_bounds_check,
panic_handler, panic_handler,
panic_impl, panic_impl,
panic_implementation, panic_implementation,
panic_info,
panic_location,
panic_runtime, panic_runtime,
panic_unwind,
param_attrs, param_attrs,
parent_trait, parent_trait,
partial_cmp, partial_cmp,
PartialEq, PartialEq,
partial_ord,
PartialOrd, PartialOrd,
passes, passes,
pat, pat,
path, path,
pattern_parentheses, pattern_parentheses,
Pending, Pending,
phantom_data,
pin, pin,
Pin, Pin,
pinned, pinned,
@ -629,14 +700,17 @@ symbols! {
plugin, plugin,
plugin_registrar, plugin_registrar,
plugins, plugins,
pointer,
poll, poll,
Poll, Poll,
post_dash_lto: "post-lto",
powerpc_target_feature, powerpc_target_feature,
powf32, powf32,
powf64, powf64,
powif32, powif32,
powif64, powif64,
precise_pointer_size_matching, precise_pointer_size_matching,
pre_dash_lto: "pre-lto",
pref_align_of, pref_align_of,
prefetch_read_data, prefetch_read_data,
prefetch_read_instruction, prefetch_read_instruction,
@ -683,13 +757,18 @@ symbols! {
Rc, Rc,
readonly, readonly,
Ready, Ready,
realloc,
reason, reason,
receiver,
recursion_limit, recursion_limit,
reexport_test_harness_main, reexport_test_harness_main,
reference,
reflect, reflect,
register_attr, register_attr,
register_tool, register_tool,
relaxed_adts, relaxed_adts,
rem,
rem_assign,
repr, repr,
repr128, repr128,
repr_align, repr_align,
@ -701,6 +780,7 @@ symbols! {
re_rebalance_coherence, re_rebalance_coherence,
result, result,
Result, Result,
result_type,
Return, Return,
rhs, rhs,
rintf32, rintf32,
@ -776,6 +856,8 @@ symbols! {
rustc_unsafe_specialization_marker, rustc_unsafe_specialization_marker,
rustc_variance, rustc_variance,
rust_eh_personality, rust_eh_personality,
rust_eh_register_frames,
rust_eh_unregister_frames,
rustfmt, rustfmt,
rust_oom, rust_oom,
rvalue_static_promotion, rvalue_static_promotion,
@ -786,19 +868,83 @@ symbols! {
_Self, _Self,
self_in_typedefs, self_in_typedefs,
self_struct_ctor, self_struct_ctor,
semitransparent,
Send,
send_trait, send_trait,
shl,
shl_assign,
should_panic, should_panic,
shr,
shr_assign,
simd, simd,
simd_add,
simd_and,
simd_bitmask,
simd_cast,
simd_ceil,
simd_div,
simd_eq,
simd_extract, simd_extract,
simd_fabs,
simd_fcos,
simd_fexp,
simd_fexp2,
simd_ffi, simd_ffi,
simd_flog,
simd_flog10,
simd_flog2,
simd_floor,
simd_fma,
simd_fmax,
simd_fmin,
simd_fpow,
simd_fpowi,
simd_fsin,
simd_fsqrt,
simd_gather,
simd_ge,
simd_gt,
simd_insert, simd_insert,
simd_le,
simd_lt,
simd_mul,
simd_ne,
simd_or,
simd_reduce_add_ordered,
simd_reduce_add_unordered,
simd_reduce_all,
simd_reduce_and,
simd_reduce_any,
simd_reduce_max,
simd_reduce_max_nanless,
simd_reduce_min,
simd_reduce_min_nanless,
simd_reduce_mul_ordered,
simd_reduce_mul_unordered,
simd_reduce_or,
simd_reduce_xor,
simd_rem,
simd_saturating_add,
simd_saturating_sub,
simd_scatter,
simd_select,
simd_select_bitmask,
simd_shl,
simd_shr,
simd_sub,
simd_xor,
since, since,
sinf32, sinf32,
sinf64, sinf64,
size, size,
sized,
size_of, size_of,
size_of_val, size_of_val,
slice,
slice_alloc,
slice_patterns, slice_patterns,
slice_u8,
slice_u8_alloc,
slicing_syntax, slicing_syntax,
soft, soft,
Some, Some,
@ -820,24 +966,41 @@ symbols! {
stmt_expr_attributes, stmt_expr_attributes,
stop_after_dataflow, stop_after_dataflow,
str, str,
str_alloc,
stringify, stringify,
struct_field_attributes, struct_field_attributes,
struct_inherit, struct_inherit,
structural_match, structural_match,
structural_peq,
structural_teq,
struct_variant, struct_variant,
sty, sty,
sub,
sub_assign,
sub_with_overflow, sub_with_overflow,
suggestion, suggestion,
sym, sym,
sync,
Sync,
sync_trait, sync_trait,
Target,
target_arch,
target_endian,
target_env,
target_family,
target_feature, target_feature,
target_feature_11, target_feature_11,
target_has_atomic, target_has_atomic,
target_has_atomic_load_store, target_has_atomic_load_store,
target_os,
target_pointer_width,
target_target_vendor,
target_thread_local, target_thread_local,
target_vendor,
task, task,
_task_context, _task_context,
tbm_target_feature, tbm_target_feature,
termination,
termination_trait, termination_trait,
termination_trait_test, termination_trait_test,
test, test,
@ -865,6 +1028,7 @@ symbols! {
try_blocks, try_blocks,
try_trait, try_trait,
tt, tt,
tuple,
tuple_indexing, tuple_indexing,
two_phase, two_phase,
ty, ty,
@ -897,18 +1061,24 @@ symbols! {
underscore_imports, underscore_imports,
underscore_lifetimes, underscore_lifetimes,
uniform_paths, uniform_paths,
unit,
universal_impl_trait, universal_impl_trait,
unix,
unlikely, unlikely,
unmarked_api, unmarked_api,
unpin,
unreachable, unreachable,
unreachable_code, unreachable_code,
unrestricted_attribute_tokens, unrestricted_attribute_tokens,
unsafe_block_in_unsafe_fn, unsafe_block_in_unsafe_fn,
unsafe_cell,
unsafe_no_drop_flag, unsafe_no_drop_flag,
unsize,
unsized_locals, unsized_locals,
unsized_tuple_coercion, unsized_tuple_coercion,
unstable, unstable,
untagged_unions, untagged_unions,
unused_qualifications,
unwind, unwind,
unwind_attributes, unwind_attributes,
unwrap_or, unwrap_or,
@ -921,11 +1091,13 @@ symbols! {
va_copy, va_copy,
va_end, va_end,
val, val,
va_list,
var, var,
variant_count, variant_count,
va_start, va_start,
vec, vec,
Vec, Vec,
vec_type,
version, version,
vis, vis,
visible_private_types, visible_private_types,

View file

@ -6,7 +6,7 @@ use rustc_infer::infer::InferCtxt;
use rustc_middle::ty::{self, TraitRef, Ty, TyCtxt, WithConstness}; use rustc_middle::ty::{self, TraitRef, Ty, TyCtxt, WithConstness};
use rustc_middle::ty::{ToPredicate, TypeFoldable}; use rustc_middle::ty::{ToPredicate, TypeFoldable};
use rustc_session::DiagnosticMessageId; use rustc_session::DiagnosticMessageId;
use rustc_span::symbol::Ident; use rustc_span::symbol::{sym, Ident};
use rustc_span::Span; use rustc_span::Span;
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
@ -143,7 +143,11 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
let normalized_ty = fulfillcx.normalize_projection_type( let normalized_ty = fulfillcx.normalize_projection_type(
&self.infcx, &self.infcx,
self.param_env, self.param_env,
ty::ProjectionTy::from_ref_and_name(tcx, trait_ref, Ident::from_str("Target")), ty::ProjectionTy::from_ref_and_name(
tcx,
trait_ref,
Ident::with_dummy_span(sym::Target),
),
cause, cause,
); );
if let Err(e) = fulfillcx.select_where_possible(&self.infcx) { if let Err(e) = fulfillcx.select_where_possible(&self.infcx) {

View file

@ -1247,7 +1247,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
.generic_args() .generic_args()
.bindings .bindings
.iter() .iter()
.find_map(|b| match (b.ident.as_str() == "Output", &b.kind) { .find_map(|b| match (b.ident.name == sym::Output, &b.kind) {
(true, hir::TypeBindingKind::Equality { ty }) => { (true, hir::TypeBindingKind::Equality { ty }) => {
sess.source_map().span_to_snippet(ty.span).ok() sess.source_map().span_to_snippet(ty.span).ok()
} }

View file

@ -13,7 +13,7 @@ use rustc_middle::ty::adjustment::{
}; };
use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc_span::symbol::Ident; use rustc_span::symbol::{sym, Ident};
use rustc_span::Span; use rustc_span::Span;
use rustc_target::spec::abi; use rustc_target::spec::abi;
use rustc_trait_selection::autoderef::Autoderef; use rustc_trait_selection::autoderef::Autoderef;
@ -192,9 +192,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> Option<(Option<Adjustment<'tcx>>, MethodCallee<'tcx>)> { ) -> Option<(Option<Adjustment<'tcx>>, MethodCallee<'tcx>)> {
// Try the options that are least restrictive on the caller first. // Try the options that are least restrictive on the caller first.
for &(opt_trait_def_id, method_name, borrow) in &[ for &(opt_trait_def_id, method_name, borrow) in &[
(self.tcx.lang_items().fn_trait(), Ident::from_str("call"), true), (self.tcx.lang_items().fn_trait(), Ident::with_dummy_span(sym::call), true),
(self.tcx.lang_items().fn_mut_trait(), Ident::from_str("call_mut"), true), (self.tcx.lang_items().fn_mut_trait(), Ident::with_dummy_span(sym::call_mut), true),
(self.tcx.lang_items().fn_once_trait(), Ident::from_str("call_once"), false), (self.tcx.lang_items().fn_once_trait(), Ident::with_dummy_span(sym::call_once), false),
] { ] {
let trait_def_id = match opt_trait_def_id { let trait_def_id = match opt_trait_def_id {
Some(def_id) => def_id, Some(def_id) => def_id,

View file

@ -423,70 +423,81 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
}; };
let def_id = tcx.hir().local_def_id(it.hir_id).to_def_id(); let def_id = tcx.hir().local_def_id(it.hir_id).to_def_id();
let name = it.ident.as_str(); let name = it.ident.name;
let (n_tps, inputs, output) = match &*name { let (n_tps, inputs, output) = match name {
"simd_eq" | "simd_ne" | "simd_lt" | "simd_le" | "simd_gt" | "simd_ge" => { sym::simd_eq | sym::simd_ne | sym::simd_lt | sym::simd_le | sym::simd_gt | sym::simd_ge => {
(2, vec![param(0), param(0)], param(1)) (2, vec![param(0), param(0)], param(1))
} }
"simd_add" sym::simd_add
| "simd_sub" | sym::simd_sub
| "simd_mul" | sym::simd_mul
| "simd_rem" | sym::simd_rem
| "simd_div" | sym::simd_div
| "simd_shl" | sym::simd_shl
| "simd_shr" | sym::simd_shr
| "simd_and" | sym::simd_and
| "simd_or" | sym::simd_or
| "simd_xor" | sym::simd_xor
| "simd_fmin" | sym::simd_fmin
| "simd_fmax" | sym::simd_fmax
| "simd_fpow" | sym::simd_fpow
| "simd_saturating_add" | sym::simd_saturating_add
| "simd_saturating_sub" => (1, vec![param(0), param(0)], param(0)), | sym::simd_saturating_sub => (1, vec![param(0), param(0)], param(0)),
"simd_fsqrt" | "simd_fsin" | "simd_fcos" | "simd_fexp" | "simd_fexp2" | "simd_flog2" sym::simd_fsqrt
| "simd_flog10" | "simd_flog" | "simd_fabs" | "simd_floor" | "simd_ceil" => { | sym::simd_fsin
(1, vec![param(0)], param(0)) | sym::simd_fcos
| sym::simd_fexp
| sym::simd_fexp2
| sym::simd_flog2
| sym::simd_flog10
| sym::simd_flog
| sym::simd_fabs
| sym::simd_floor
| sym::simd_ceil => (1, vec![param(0)], param(0)),
sym::simd_fpowi => (1, vec![param(0), tcx.types.i32], param(0)),
sym::simd_fma => (1, vec![param(0), param(0), param(0)], param(0)),
sym::simd_gather => (3, vec![param(0), param(1), param(2)], param(0)),
sym::simd_scatter => (3, vec![param(0), param(1), param(2)], tcx.mk_unit()),
sym::simd_insert => (2, vec![param(0), tcx.types.u32, param(1)], param(0)),
sym::simd_extract => (2, vec![param(0), tcx.types.u32], param(1)),
sym::simd_cast => (2, vec![param(0)], param(1)),
sym::simd_bitmask => (2, vec![param(0)], param(1)),
sym::simd_select | sym::simd_select_bitmask => {
(2, vec![param(0), param(1), param(1)], param(1))
} }
"simd_fpowi" => (1, vec![param(0), tcx.types.i32], param(0)), sym::simd_reduce_all | sym::simd_reduce_any => (1, vec![param(0)], tcx.types.bool),
"simd_fma" => (1, vec![param(0), param(0), param(0)], param(0)), sym::simd_reduce_add_ordered | sym::simd_reduce_mul_ordered => {
"simd_gather" => (3, vec![param(0), param(1), param(2)], param(0)),
"simd_scatter" => (3, vec![param(0), param(1), param(2)], tcx.mk_unit()),
"simd_insert" => (2, vec![param(0), tcx.types.u32, param(1)], param(0)),
"simd_extract" => (2, vec![param(0), tcx.types.u32], param(1)),
"simd_cast" => (2, vec![param(0)], param(1)),
"simd_bitmask" => (2, vec![param(0)], param(1)),
"simd_select" | "simd_select_bitmask" => (2, vec![param(0), param(1), param(1)], param(1)),
"simd_reduce_all" | "simd_reduce_any" => (1, vec![param(0)], tcx.types.bool),
"simd_reduce_add_ordered" | "simd_reduce_mul_ordered" => {
(2, vec![param(0), param(1)], param(1)) (2, vec![param(0), param(1)], param(1))
} }
"simd_reduce_add_unordered" sym::simd_reduce_add_unordered
| "simd_reduce_mul_unordered" | sym::simd_reduce_mul_unordered
| "simd_reduce_and" | sym::simd_reduce_and
| "simd_reduce_or" | sym::simd_reduce_or
| "simd_reduce_xor" | sym::simd_reduce_xor
| "simd_reduce_min" | sym::simd_reduce_min
| "simd_reduce_max" | sym::simd_reduce_max
| "simd_reduce_min_nanless" | sym::simd_reduce_min_nanless
| "simd_reduce_max_nanless" => (2, vec![param(0)], param(1)), | sym::simd_reduce_max_nanless => (2, vec![param(0)], param(1)),
name if name.starts_with("simd_shuffle") => match name["simd_shuffle".len()..].parse() { name if name.as_str().starts_with("simd_shuffle") => {
Ok(n) => { match name.as_str()["simd_shuffle".len()..].parse() {
let params = vec![param(0), param(0), tcx.mk_array(tcx.types.u32, n)]; Ok(n) => {
(2, params, param(1)) let params = vec![param(0), param(0), tcx.mk_array(tcx.types.u32, n)];
(2, params, param(1))
}
Err(_) => {
struct_span_err!(
tcx.sess,
it.span,
E0439,
"invalid `simd_shuffle`, needs length: `{}`",
name
)
.emit();
return;
}
} }
Err(_) => { }
struct_span_err!(
tcx.sess,
it.span,
E0439,
"invalid `simd_shuffle`, needs length: `{}`",
name
)
.emit();
return;
}
},
_ => { _ => {
let msg = format!("unrecognized platform-specific intrinsic function: `{}`", name); let msg = format!("unrecognized platform-specific intrinsic function: `{}`", name);
tcx.sess.struct_span_err(it.span, &msg).emit(); tcx.sess.struct_span_err(it.span, &msg).emit();

View file

@ -17,7 +17,7 @@ use rustc_middle::ty::print::with_crate_prefix;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
}; };
use rustc_span::symbol::{kw, Ident}; use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{source_map, FileName, Span}; use rustc_span::{source_map, FileName, Span};
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
use rustc_trait_selection::traits::Obligation; use rustc_trait_selection::traits::Obligation;
@ -743,7 +743,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut fallback_span = true; let mut fallback_span = true;
let msg = "remove this method call"; let msg = "remove this method call";
if item_name.as_str() == "as_str" && actual.peel_refs().is_str() { if item_name.name == sym::as_str && actual.peel_refs().is_str() {
if let SelfSource::MethodCall(expr) = source { if let SelfSource::MethodCall(expr) = source {
let call_expr = let call_expr =
self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id)); self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));

View file

@ -13,7 +13,7 @@ use rustc_middle::ty::TyKind::{Adt, Array, Char, FnDef, Never, Ref, Str, Tuple,
use rustc_middle::ty::{ use rustc_middle::ty::{
self, suggest_constraining_type_param, Ty, TyCtxt, TypeFoldable, TypeVisitor, self, suggest_constraining_type_param, Ty, TyCtxt, TypeFoldable, TypeVisitor,
}; };
use rustc_span::symbol::Ident; use rustc_span::symbol::{sym, Ident};
use rustc_span::Span; use rustc_span::Span;
use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::infer::InferCtxtExt;
@ -702,16 +702,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}; };
let (opname, trait_did) = if let Op::Binary(op, IsAssign::Yes) = op { let (opname, trait_did) = if let Op::Binary(op, IsAssign::Yes) = op {
match op.node { match op.node {
hir::BinOpKind::Add => ("add_assign", lang.add_assign_trait()), hir::BinOpKind::Add => (sym::add_assign, lang.add_assign_trait()),
hir::BinOpKind::Sub => ("sub_assign", lang.sub_assign_trait()), hir::BinOpKind::Sub => (sym::sub_assign, lang.sub_assign_trait()),
hir::BinOpKind::Mul => ("mul_assign", lang.mul_assign_trait()), hir::BinOpKind::Mul => (sym::mul_assign, lang.mul_assign_trait()),
hir::BinOpKind::Div => ("div_assign", lang.div_assign_trait()), hir::BinOpKind::Div => (sym::div_assign, lang.div_assign_trait()),
hir::BinOpKind::Rem => ("rem_assign", lang.rem_assign_trait()), hir::BinOpKind::Rem => (sym::rem_assign, lang.rem_assign_trait()),
hir::BinOpKind::BitXor => ("bitxor_assign", lang.bitxor_assign_trait()), hir::BinOpKind::BitXor => (sym::bitxor_assign, lang.bitxor_assign_trait()),
hir::BinOpKind::BitAnd => ("bitand_assign", lang.bitand_assign_trait()), hir::BinOpKind::BitAnd => (sym::bitand_assign, lang.bitand_assign_trait()),
hir::BinOpKind::BitOr => ("bitor_assign", lang.bitor_assign_trait()), hir::BinOpKind::BitOr => (sym::bitor_assign, lang.bitor_assign_trait()),
hir::BinOpKind::Shl => ("shl_assign", lang.shl_assign_trait()), hir::BinOpKind::Shl => (sym::shl_assign, lang.shl_assign_trait()),
hir::BinOpKind::Shr => ("shr_assign", lang.shr_assign_trait()), hir::BinOpKind::Shr => (sym::shr_assign, lang.shr_assign_trait()),
hir::BinOpKind::Lt hir::BinOpKind::Lt
| hir::BinOpKind::Le | hir::BinOpKind::Le
| hir::BinOpKind::Ge | hir::BinOpKind::Ge
@ -725,30 +725,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} else if let Op::Binary(op, IsAssign::No) = op { } else if let Op::Binary(op, IsAssign::No) = op {
match op.node { match op.node {
hir::BinOpKind::Add => ("add", lang.add_trait()), hir::BinOpKind::Add => (sym::add, lang.add_trait()),
hir::BinOpKind::Sub => ("sub", lang.sub_trait()), hir::BinOpKind::Sub => (sym::sub, lang.sub_trait()),
hir::BinOpKind::Mul => ("mul", lang.mul_trait()), hir::BinOpKind::Mul => (sym::mul, lang.mul_trait()),
hir::BinOpKind::Div => ("div", lang.div_trait()), hir::BinOpKind::Div => (sym::div, lang.div_trait()),
hir::BinOpKind::Rem => ("rem", lang.rem_trait()), hir::BinOpKind::Rem => (sym::rem, lang.rem_trait()),
hir::BinOpKind::BitXor => ("bitxor", lang.bitxor_trait()), hir::BinOpKind::BitXor => (sym::bitxor, lang.bitxor_trait()),
hir::BinOpKind::BitAnd => ("bitand", lang.bitand_trait()), hir::BinOpKind::BitAnd => (sym::bitand, lang.bitand_trait()),
hir::BinOpKind::BitOr => ("bitor", lang.bitor_trait()), hir::BinOpKind::BitOr => (sym::bitor, lang.bitor_trait()),
hir::BinOpKind::Shl => ("shl", lang.shl_trait()), hir::BinOpKind::Shl => (sym::shl, lang.shl_trait()),
hir::BinOpKind::Shr => ("shr", lang.shr_trait()), hir::BinOpKind::Shr => (sym::shr, lang.shr_trait()),
hir::BinOpKind::Lt => ("lt", lang.partial_ord_trait()), hir::BinOpKind::Lt => (sym::lt, lang.partial_ord_trait()),
hir::BinOpKind::Le => ("le", lang.partial_ord_trait()), hir::BinOpKind::Le => (sym::le, lang.partial_ord_trait()),
hir::BinOpKind::Ge => ("ge", lang.partial_ord_trait()), hir::BinOpKind::Ge => (sym::ge, lang.partial_ord_trait()),
hir::BinOpKind::Gt => ("gt", lang.partial_ord_trait()), hir::BinOpKind::Gt => (sym::gt, lang.partial_ord_trait()),
hir::BinOpKind::Eq => ("eq", lang.eq_trait()), hir::BinOpKind::Eq => (sym::eq, lang.eq_trait()),
hir::BinOpKind::Ne => ("ne", lang.eq_trait()), hir::BinOpKind::Ne => (sym::ne, lang.eq_trait()),
hir::BinOpKind::And | hir::BinOpKind::Or => { hir::BinOpKind::And | hir::BinOpKind::Or => {
span_bug!(span, "&& and || are not overloadable") span_bug!(span, "&& and || are not overloadable")
} }
} }
} else if let Op::Unary(hir::UnOp::UnNot, _) = op { } else if let Op::Unary(hir::UnOp::UnNot, _) = op {
("not", lang.not_trait()) (sym::not, lang.not_trait())
} else if let Op::Unary(hir::UnOp::UnNeg, _) = op { } else if let Op::Unary(hir::UnOp::UnNeg, _) = op {
("neg", lang.neg_trait()) (sym::neg, lang.neg_trait())
} else { } else {
bug!("lookup_op_method: op not supported: {:?}", op) bug!("lookup_op_method: op not supported: {:?}", op)
}; };
@ -759,7 +759,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
); );
let method = trait_did.and_then(|trait_did| { let method = trait_did.and_then(|trait_did| {
let opname = Ident::from_str(opname); let opname = Ident::with_dummy_span(opname);
self.lookup_method_in_trait(span, opname, trait_did, lhs_ty, Some(other_tys)) self.lookup_method_in_trait(span, opname, trait_did, lhs_ty, Some(other_tys))
}); });

View file

@ -162,8 +162,8 @@ impl Cfg {
Cfg::Any(ref sub_cfgs) | Cfg::All(ref sub_cfgs) => { Cfg::Any(ref sub_cfgs) | Cfg::All(ref sub_cfgs) => {
sub_cfgs.first().map(Cfg::should_capitalize_first_letter).unwrap_or(false) sub_cfgs.first().map(Cfg::should_capitalize_first_letter).unwrap_or(false)
} }
Cfg::Cfg(name, _) => match &*name.as_str() { Cfg::Cfg(name, _) => match name {
"debug_assertions" | "target_endian" => true, sym::debug_assertions | sym::target_endian => true,
_ => false, _ => false,
}, },
} }
@ -347,12 +347,11 @@ impl<'a> fmt::Display for Html<'a> {
Cfg::False => fmt.write_str("nowhere"), Cfg::False => fmt.write_str("nowhere"),
Cfg::Cfg(name, value) => { Cfg::Cfg(name, value) => {
let n = &*name.as_str(); let human_readable = match (name, value) {
let human_readable = match (n, value) { (sym::unix, None) => "Unix",
("unix", None) => "Unix", (sym::windows, None) => "Windows",
("windows", None) => "Windows", (sym::debug_assertions, None) => "debug-assertions enabled",
("debug_assertions", None) => "debug-assertions enabled", (sym::target_os, Some(os)) => match &*os.as_str() {
("target_os", Some(os)) => match &*os.as_str() {
"android" => "Android", "android" => "Android",
"dragonfly" => "DragonFly BSD", "dragonfly" => "DragonFly BSD",
"emscripten" => "Emscripten", "emscripten" => "Emscripten",
@ -372,7 +371,7 @@ impl<'a> fmt::Display for Html<'a> {
"windows" => "Windows", "windows" => "Windows",
_ => "", _ => "",
}, },
("target_arch", Some(arch)) => match &*arch.as_str() { (sym::target_arch, Some(arch)) => match &*arch.as_str() {
"aarch64" => "AArch64", "aarch64" => "AArch64",
"arm" => "ARM", "arm" => "ARM",
"asmjs" => "JavaScript", "asmjs" => "JavaScript",
@ -388,7 +387,7 @@ impl<'a> fmt::Display for Html<'a> {
"x86_64" => "x86-64", "x86_64" => "x86-64",
_ => "", _ => "",
}, },
("target_vendor", Some(vendor)) => match &*vendor.as_str() { (sym::target_vendor, Some(vendor)) => match &*vendor.as_str() {
"apple" => "Apple", "apple" => "Apple",
"pc" => "PC", "pc" => "PC",
"rumprun" => "Rumprun", "rumprun" => "Rumprun",
@ -396,7 +395,7 @@ impl<'a> fmt::Display for Html<'a> {
"fortanix" => "Fortanix", "fortanix" => "Fortanix",
_ => "", _ => "",
}, },
("target_env", Some(env)) => match &*env.as_str() { (sym::target_env, Some(env)) => match &*env.as_str() {
"gnu" => "GNU", "gnu" => "GNU",
"msvc" => "MSVC", "msvc" => "MSVC",
"musl" => "musl", "musl" => "musl",
@ -405,9 +404,9 @@ impl<'a> fmt::Display for Html<'a> {
"sgx" => "SGX", "sgx" => "SGX",
_ => "", _ => "",
}, },
("target_endian", Some(endian)) => return write!(fmt, "{}-endian", endian), (sym::target_endian, Some(endian)) => return write!(fmt, "{}-endian", endian),
("target_pointer_width", Some(bits)) => return write!(fmt, "{}-bit", bits), (sym::target_pointer_width, Some(bits)) => return write!(fmt, "{}-bit", bits),
("target_feature", Some(feat)) => { (sym::target_feature, Some(feat)) => {
if self.1 { if self.1 {
return write!(fmt, "<code>{}</code>", feat); return write!(fmt, "<code>{}</code>", feat);
} else { } else {
@ -419,9 +418,14 @@ impl<'a> fmt::Display for Html<'a> {
if !human_readable.is_empty() { if !human_readable.is_empty() {
fmt.write_str(human_readable) fmt.write_str(human_readable)
} else if let Some(v) = value { } else if let Some(v) = value {
write!(fmt, "<code>{}=\"{}\"</code>", Escape(n), Escape(&v.as_str())) write!(
fmt,
"<code>{}=\"{}\"</code>",
Escape(&name.as_str()),
Escape(&v.as_str())
)
} else { } else {
write!(fmt, "<code>{}</code>", Escape(n)) write!(fmt, "<code>{}</code>", Escape(&name.as_str()))
} }
} }
} }

View file

@ -114,7 +114,7 @@ impl Clean<ExternalCrate> for CrateNum {
for attr in attrs.lists(sym::doc) { for attr in attrs.lists(sym::doc) {
if let Some(v) = attr.value_str() { if let Some(v) = attr.value_str() {
if attr.check_name(sym::primitive) { if attr.check_name(sym::primitive) {
prim = PrimitiveType::from_str(&v.as_str()); prim = PrimitiveType::from_symbol(v);
if prim.is_some() { if prim.is_some() {
break; break;
} }

View file

@ -21,7 +21,7 @@ use rustc_index::vec::IndexVec;
use rustc_middle::middle::stability; use rustc_middle::middle::stability;
use rustc_span::hygiene::MacroKind; use rustc_span::hygiene::MacroKind;
use rustc_span::source_map::DUMMY_SP; use rustc_span::source_map::DUMMY_SP;
use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{self, FileName}; use rustc_span::{self, FileName};
use rustc_target::abi::VariantIdx; use rustc_target::abi::VariantIdx;
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
@ -1230,33 +1230,33 @@ impl GetDefId for Type {
} }
impl PrimitiveType { impl PrimitiveType {
pub fn from_str(s: &str) -> Option<PrimitiveType> { pub fn from_symbol(s: Symbol) -> Option<PrimitiveType> {
match s { match s {
"isize" => Some(PrimitiveType::Isize), sym::isize => Some(PrimitiveType::Isize),
"i8" => Some(PrimitiveType::I8), sym::i8 => Some(PrimitiveType::I8),
"i16" => Some(PrimitiveType::I16), sym::i16 => Some(PrimitiveType::I16),
"i32" => Some(PrimitiveType::I32), sym::i32 => Some(PrimitiveType::I32),
"i64" => Some(PrimitiveType::I64), sym::i64 => Some(PrimitiveType::I64),
"i128" => Some(PrimitiveType::I128), sym::i128 => Some(PrimitiveType::I128),
"usize" => Some(PrimitiveType::Usize), sym::usize => Some(PrimitiveType::Usize),
"u8" => Some(PrimitiveType::U8), sym::u8 => Some(PrimitiveType::U8),
"u16" => Some(PrimitiveType::U16), sym::u16 => Some(PrimitiveType::U16),
"u32" => Some(PrimitiveType::U32), sym::u32 => Some(PrimitiveType::U32),
"u64" => Some(PrimitiveType::U64), sym::u64 => Some(PrimitiveType::U64),
"u128" => Some(PrimitiveType::U128), sym::u128 => Some(PrimitiveType::U128),
"bool" => Some(PrimitiveType::Bool), sym::bool => Some(PrimitiveType::Bool),
"char" => Some(PrimitiveType::Char), sym::char => Some(PrimitiveType::Char),
"str" => Some(PrimitiveType::Str), sym::str => Some(PrimitiveType::Str),
"f32" => Some(PrimitiveType::F32), sym::f32 => Some(PrimitiveType::F32),
"f64" => Some(PrimitiveType::F64), sym::f64 => Some(PrimitiveType::F64),
"array" => Some(PrimitiveType::Array), sym::array => Some(PrimitiveType::Array),
"slice" => Some(PrimitiveType::Slice), sym::slice => Some(PrimitiveType::Slice),
"tuple" => Some(PrimitiveType::Tuple), sym::tuple => Some(PrimitiveType::Tuple),
"unit" => Some(PrimitiveType::Unit), sym::unit => Some(PrimitiveType::Unit),
"pointer" => Some(PrimitiveType::RawPointer), sym::pointer => Some(PrimitiveType::RawPointer),
"reference" => Some(PrimitiveType::Reference), sym::reference => Some(PrimitiveType::Reference),
"fn" => Some(PrimitiveType::Fn), kw::Fn => Some(PrimitiveType::Fn),
"never" => Some(PrimitiveType::Never), sym::never => Some(PrimitiveType::Never),
_ => None, _ => None,
} }
} }

View file

@ -10,7 +10,10 @@
macro_rules! foo /* 0#0 */ { ($ x : ident) => { y + $ x } } macro_rules! foo /* 0#0 */ { ($ x : ident) => { y + $ x } }
fn bar /* 0#0 */() { let x /* 0#0 */ = 1; y /* 0#1 */ + x /* 0#0 */ } fn bar /* 0#0 */() {
let x /* 0#0 */ = 1;
y /* 0#1 */ + x /* 0#0 */
}
fn y /* 0#0 */() { } fn y /* 0#0 */() { }