diff --git a/Cargo.lock b/Cargo.lock index 5309c03ee23ae..28ff6b3b1ebf2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2056,6 +2056,7 @@ dependencies = [ name = "panic_abort" version = "0.0.0" dependencies = [ + "cfg-if", "compiler_builtins", "core", "libc", @@ -4552,6 +4553,7 @@ dependencies = [ name = "test" version = "0.0.0" dependencies = [ + "cfg-if", "core", "getopts", "libc", diff --git a/src/libpanic_abort/Cargo.toml b/src/libpanic_abort/Cargo.toml index 2bee0b716c750..dc385022440e0 100644 --- a/src/libpanic_abort/Cargo.toml +++ b/src/libpanic_abort/Cargo.toml @@ -11,6 +11,7 @@ bench = false doc = false [dependencies] +cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] } core = { path = "../libcore" } libc = { version = "0.2", default-features = false } compiler_builtins = "0.1.0" diff --git a/src/libpanic_abort/lib.rs b/src/libpanic_abort/lib.rs index 27056d5f934fd..95f3966228a2f 100644 --- a/src/libpanic_abort/lib.rs +++ b/src/libpanic_abort/lib.rs @@ -40,23 +40,26 @@ pub unsafe extern "C" fn __rust_panic_cleanup(_: *mut u8) -> *mut (dyn Any + Sen pub unsafe extern "C" fn __rust_start_panic(_payload: usize) -> u32 { abort(); - #[cfg(any(unix, target_os = "cloudabi"))] - unsafe fn abort() -> ! { - libc::abort(); - } - - #[cfg(any(windows, all(target_arch = "wasm32", not(target_os = "emscripten"))))] - unsafe fn abort() -> ! { - core::intrinsics::abort(); - } - - #[cfg(any(target_os = "hermit", all(target_vendor = "fortanix", target_env = "sgx")))] - unsafe fn abort() -> ! { - // call std::sys::abort_internal - extern "C" { - pub fn __rust_abort() -> !; + cfg_if::cfg_if! { + if #[cfg(any(unix, target_os = "cloudabi"))] { + unsafe fn abort() -> ! { + libc::abort(); + } + } else if #[cfg(any(target_os = "hermit", + all(target_vendor = "fortanix", target_env = "sgx") + ))] { + unsafe fn abort() -> ! { + // call std::sys::abort_internal + extern "C" { + pub fn __rust_abort() -> !; + } + __rust_abort(); + } + } else { + unsafe fn abort() -> ! { + core::intrinsics::abort(); + } } - __rust_abort(); } } diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs index f361354da2ac2..430062d4ac44e 100644 --- a/src/libpanic_unwind/lib.rs +++ b/src/libpanic_unwind/lib.rs @@ -41,21 +41,33 @@ cfg_if::cfg_if! { if #[cfg(target_os = "emscripten")] { #[path = "emcc.rs"] mod real_imp; - } else if #[cfg(target_arch = "wasm32")] { - #[path = "dummy.rs"] - mod real_imp; } else if #[cfg(target_os = "hermit")] { #[path = "hermit.rs"] mod real_imp; } else if #[cfg(target_env = "msvc")] { #[path = "seh.rs"] mod real_imp; - } else { + } else if #[cfg(any( + all(target_family = "windows", target_env = "gnu"), + target_os = "cloudabi", + target_family = "unix", + all(target_vendor = "fortanix", target_env = "sgx"), + ))] { // Rust runtime's startup objects depend on these symbols, so make them public. #[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))] pub use real_imp::eh_frame_registry::*; #[path = "gcc.rs"] mod real_imp; + } else { + // Targets that don't support unwinding. + // - arch=wasm32 + // - os=none ("bare metal" targets) + // - os=uefi + // - nvptx64-nvidia-cuda + // - avr-unknown-unknown + // - mipsel-sony-psp + #[path = "dummy.rs"] + mod real_imp; } } diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 2d5bd7e872bd5..f960bdecc579f 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -26,6 +26,7 @@ #![feature(in_band_lifetimes)] #![feature(negative_impls)] #![feature(optin_builtin_traits)] +#![feature(restricted_std)] #![feature(rustc_attrs)] #![feature(min_specialization)] #![recursion_limit = "256"] diff --git a/src/librustc_builtin_macros/deriving/bounds.rs b/src/librustc_builtin_macros/deriving/bounds.rs index a1c818caff3bf..cef0da60a61c8 100644 --- a/src/librustc_builtin_macros/deriving/bounds.rs +++ b/src/librustc_builtin_macros/deriving/bounds.rs @@ -16,9 +16,9 @@ pub fn expand_deriving_copy( let trait_def = TraitDef { span, attributes: Vec::new(), - path: path_std!(cx, marker::Copy), + path: path_std!(marker::Copy), additional_bounds: Vec::new(), - generics: LifetimeBounds::empty(), + generics: Bounds::empty(), is_unsafe: false, supports_unions: true, methods: Vec::new(), diff --git a/src/librustc_builtin_macros/deriving/clone.rs b/src/librustc_builtin_macros/deriving/clone.rs index 5a8648f2aaa4c..b307ee26c91d5 100644 --- a/src/librustc_builtin_macros/deriving/clone.rs +++ b/src/librustc_builtin_macros/deriving/clone.rs @@ -56,7 +56,7 @@ pub fn expand_deriving_clone( } } ItemKind::Union(..) => { - bounds = vec![Literal(path_std!(cx, marker::Copy))]; + bounds = vec![Literal(path_std!(marker::Copy))]; is_shallow = true; substructure = combine_substructure(Box::new(|c, s, sub| { cs_clone_shallow("Clone", c, s, sub, true) @@ -78,14 +78,14 @@ pub fn expand_deriving_clone( let trait_def = TraitDef { span, attributes: Vec::new(), - path: path_std!(cx, clone::Clone), + path: path_std!(clone::Clone), additional_bounds: bounds, - generics: LifetimeBounds::empty(), + generics: Bounds::empty(), is_unsafe: false, supports_unions: true, methods: vec![MethodDef { name: sym::clone, - generics: LifetimeBounds::empty(), + generics: Bounds::empty(), explicit_self: borrowed_explicit_self(), args: Vec::new(), ret_ty: Self_, diff --git a/src/librustc_builtin_macros/deriving/cmp/eq.rs b/src/librustc_builtin_macros/deriving/cmp/eq.rs index e1677ae70ccab..d1b799cd6a112 100644 --- a/src/librustc_builtin_macros/deriving/cmp/eq.rs +++ b/src/librustc_builtin_macros/deriving/cmp/eq.rs @@ -22,14 +22,14 @@ pub fn expand_deriving_eq( let trait_def = TraitDef { span, attributes: Vec::new(), - path: path_std!(cx, cmp::Eq), + path: path_std!(cmp::Eq), additional_bounds: Vec::new(), - generics: LifetimeBounds::empty(), + generics: Bounds::empty(), is_unsafe: false, supports_unions: true, methods: vec![MethodDef { name: sym::assert_receiver_is_total_eq, - generics: LifetimeBounds::empty(), + generics: Bounds::empty(), explicit_self: borrowed_explicit_self(), args: vec![], ret_ty: nil_ty(), @@ -43,13 +43,7 @@ pub fn expand_deriving_eq( associated_types: Vec::new(), }; - super::inject_impl_of_structural_trait( - cx, - span, - item, - path_std!(cx, marker::StructuralEq), - push, - ); + super::inject_impl_of_structural_trait(cx, span, item, path_std!(marker::StructuralEq), push); trait_def.expand_ext(cx, mitem, item, push, true) } diff --git a/src/librustc_builtin_macros/deriving/cmp/ord.rs b/src/librustc_builtin_macros/deriving/cmp/ord.rs index a9bc03db8b706..3bf3860d32307 100644 --- a/src/librustc_builtin_macros/deriving/cmp/ord.rs +++ b/src/librustc_builtin_macros/deriving/cmp/ord.rs @@ -20,17 +20,17 @@ pub fn expand_deriving_ord( let trait_def = TraitDef { span, attributes: Vec::new(), - path: path_std!(cx, cmp::Ord), + path: path_std!(cmp::Ord), additional_bounds: Vec::new(), - generics: LifetimeBounds::empty(), + generics: Bounds::empty(), is_unsafe: false, supports_unions: false, methods: vec![MethodDef { name: sym::cmp, - generics: LifetimeBounds::empty(), + generics: Bounds::empty(), explicit_self: borrowed_explicit_self(), - args: vec![(borrowed_self(), "other")], - ret_ty: Literal(path_std!(cx, cmp::Ordering)), + args: vec![(borrowed_self(), sym::other)], + ret_ty: Literal(path_std!(cmp::Ordering)), attributes: attrs, is_unsafe: false, unify_fieldless_variants: true, diff --git a/src/librustc_builtin_macros/deriving/cmp/partial_eq.rs b/src/librustc_builtin_macros/deriving/cmp/partial_eq.rs index e7d8f78118098..d8edd641acd52 100644 --- a/src/librustc_builtin_macros/deriving/cmp/partial_eq.rs +++ b/src/librustc_builtin_macros/deriving/cmp/partial_eq.rs @@ -69,9 +69,9 @@ pub fn expand_deriving_partial_eq( let attrs = vec![cx.attribute(inline)]; MethodDef { name: $name, - generics: LifetimeBounds::empty(), + generics: Bounds::empty(), explicit_self: borrowed_explicit_self(), - args: vec![(borrowed_self(), "other")], + args: vec![(borrowed_self(), sym::other)], ret_ty: Literal(path_local!(bool)), attributes: attrs, is_unsafe: false, @@ -85,7 +85,7 @@ pub fn expand_deriving_partial_eq( cx, span, item, - path_std!(cx, marker::StructuralPartialEq), + path_std!(marker::StructuralPartialEq), push, ); @@ -100,9 +100,9 @@ pub fn expand_deriving_partial_eq( let trait_def = TraitDef { span, attributes: Vec::new(), - path: path_std!(cx, cmp::PartialEq), + path: path_std!(cmp::PartialEq), additional_bounds: Vec::new(), - generics: LifetimeBounds::empty(), + generics: Bounds::empty(), is_unsafe: false, supports_unions: false, methods, diff --git a/src/librustc_builtin_macros/deriving/cmp/partial_ord.rs b/src/librustc_builtin_macros/deriving/cmp/partial_ord.rs index a3eb96fb782e5..39a747c856839 100644 --- a/src/librustc_builtin_macros/deriving/cmp/partial_ord.rs +++ b/src/librustc_builtin_macros/deriving/cmp/partial_ord.rs @@ -23,9 +23,9 @@ pub fn expand_deriving_partial_ord( let attrs = vec![cx.attribute(inline)]; MethodDef { name: $name, - generics: LifetimeBounds::empty(), + generics: Bounds::empty(), explicit_self: borrowed_explicit_self(), - args: vec![(borrowed_self(), "other")], + args: vec![(borrowed_self(), sym::other)], ret_ty: Literal(path_local!(bool)), attributes: attrs, is_unsafe: false, @@ -37,9 +37,9 @@ pub fn expand_deriving_partial_ord( }}; } - let ordering_ty = Literal(path_std!(cx, cmp::Ordering)); + let ordering_ty = Literal(path_std!(cmp::Ordering)); let ret_ty = Literal(Path::new_( - pathvec_std!(cx, option::Option), + pathvec_std!(option::Option), None, vec![Box::new(ordering_ty)], PathKind::Std, @@ -50,9 +50,9 @@ pub fn expand_deriving_partial_ord( let partial_cmp_def = MethodDef { name: sym::partial_cmp, - generics: LifetimeBounds::empty(), + generics: Bounds::empty(), explicit_self: borrowed_explicit_self(), - args: vec![(borrowed_self(), "other")], + args: vec![(borrowed_self(), sym::other)], ret_ty, attributes: attrs, is_unsafe: false, @@ -80,9 +80,9 @@ pub fn expand_deriving_partial_ord( let trait_def = TraitDef { span, attributes: vec![], - path: path_std!(cx, cmp::PartialOrd), + path: path_std!(cmp::PartialOrd), additional_bounds: vec![], - generics: LifetimeBounds::empty(), + generics: Bounds::empty(), is_unsafe: false, supports_unions: false, methods, diff --git a/src/librustc_builtin_macros/deriving/debug.rs b/src/librustc_builtin_macros/deriving/debug.rs index 6befeb746bd6d..76e21bc43c52d 100644 --- a/src/librustc_builtin_macros/deriving/debug.rs +++ b/src/librustc_builtin_macros/deriving/debug.rs @@ -18,22 +18,22 @@ pub fn expand_deriving_debug( ) { // &mut ::std::fmt::Formatter let fmtr = - Ptr(Box::new(Literal(path_std!(cx, fmt::Formatter))), Borrowed(None, ast::Mutability::Mut)); + Ptr(Box::new(Literal(path_std!(fmt::Formatter))), Borrowed(None, ast::Mutability::Mut)); let trait_def = TraitDef { span, attributes: Vec::new(), - path: path_std!(cx, fmt::Debug), + path: path_std!(fmt::Debug), additional_bounds: Vec::new(), - generics: LifetimeBounds::empty(), + generics: Bounds::empty(), is_unsafe: false, supports_unions: false, methods: vec![MethodDef { name: sym::fmt, - generics: LifetimeBounds::empty(), + generics: Bounds::empty(), explicit_self: borrowed_explicit_self(), - args: vec![(fmtr, "f")], - ret_ty: Literal(path_std!(cx, fmt::Result)), + args: vec![(fmtr, sym::f)], + ret_ty: Literal(path_std!(fmt::Result)), attributes: Vec::new(), is_unsafe: false, unify_fieldless_variants: false, @@ -62,7 +62,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> // We want to make sure we have the ctxt set so that we can use unstable methods let span = cx.with_def_site_ctxt(span); let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked)); - let builder = cx.ident_of("debug_trait_builder", span); + let builder = Ident::new(sym::debug_trait_builder, span); let builder_expr = cx.expr_ident(span, builder); let fmt = substr.nonself_args[0].clone(); @@ -71,7 +71,8 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> match vdata { ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => { // tuple struct/"normal" variant - let expr = cx.expr_method_call(span, fmt, cx.ident_of("debug_tuple", span), vec![name]); + let expr = + cx.expr_method_call(span, fmt, Ident::new(sym::debug_tuple, span), vec![name]); stmts.push(cx.stmt_let(span, true, builder, expr)); for field in fields { @@ -94,7 +95,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> ast::VariantData::Struct(..) => { // normal struct/struct variant let expr = - cx.expr_method_call(span, fmt, cx.ident_of("debug_struct", span), vec![name]); + cx.expr_method_call(span, fmt, Ident::new(sym::debug_struct, span), vec![name]); stmts.push(cx.stmt_let(DUMMY_SP, true, builder, expr)); for field in fields { @@ -117,7 +118,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> } } - let expr = cx.expr_method_call(span, builder_expr, cx.ident_of("finish", span), vec![]); + let expr = cx.expr_method_call(span, builder_expr, Ident::new(sym::finish, span), vec![]); stmts.push(cx.stmt_expr(expr)); let block = cx.block(span, stmts); diff --git a/src/librustc_builtin_macros/deriving/decodable.rs b/src/librustc_builtin_macros/deriving/decodable.rs index 0792be7326331..ce8c2dfe4d5a0 100644 --- a/src/librustc_builtin_macros/deriving/decodable.rs +++ b/src/librustc_builtin_macros/deriving/decodable.rs @@ -8,7 +8,7 @@ use rustc_ast::ast; use rustc_ast::ast::{Expr, MetaItem, Mutability}; use rustc_ast::ptr::P; use rustc_expand::base::{Annotatable, ExtCtxt}; -use rustc_span::symbol::{sym, Symbol}; +use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; pub fn expand_deriving_rustc_decodable( @@ -18,38 +18,37 @@ pub fn expand_deriving_rustc_decodable( item: &Annotatable, push: &mut dyn FnMut(Annotatable), ) { - let krate = "rustc_serialize"; - let typaram = "__D"; + let krate = sym::rustc_serialize; + let typaram = sym::__D; let trait_def = TraitDef { span, attributes: Vec::new(), - path: Path::new_(vec![krate, "Decodable"], None, vec![], PathKind::Global), + path: Path::new_(vec![krate, sym::Decodable], None, vec![], PathKind::Global), additional_bounds: Vec::new(), - generics: LifetimeBounds::empty(), + generics: Bounds::empty(), is_unsafe: false, supports_unions: false, methods: vec![MethodDef { name: sym::decode, - generics: LifetimeBounds { - lifetimes: Vec::new(), + generics: Bounds { bounds: vec![( typaram, - vec![Path::new_(vec![krate, "Decoder"], None, vec![], PathKind::Global)], + vec![Path::new_(vec![krate, sym::Decoder], None, vec![], PathKind::Global)], )], }, explicit_self: None, args: vec![( Ptr(Box::new(Literal(Path::new_local(typaram))), Borrowed(None, Mutability::Mut)), - "d", + sym::d, )], ret_ty: Literal(Path::new_( - pathvec_std!(cx, result::Result), + pathvec_std!(result::Result), None, vec![ Box::new(Self_), Box::new(Literal(Path::new_( - vec![typaram, "Error"], + vec![typaram, sym::Error], None, vec![], PathKind::Local, @@ -74,17 +73,17 @@ fn decodable_substructure( cx: &mut ExtCtxt<'_>, trait_span: Span, substr: &Substructure<'_>, - krate: &str, + krate: Symbol, ) -> P { let decoder = substr.nonself_args[0].clone(); let recurse = vec![ - cx.ident_of(krate, trait_span), - cx.ident_of("Decodable", trait_span), - cx.ident_of("decode", trait_span), + Ident::new(krate, trait_span), + Ident::new(sym::Decodable, trait_span), + Ident::new(sym::decode, trait_span), ]; let exprdecode = cx.expr_path(cx.path_global(trait_span, recurse)); // throw an underscore in front to suppress unused variable warnings - let blkarg = cx.ident_of("_d", trait_span); + let blkarg = Ident::new(sym::_d, trait_span); let blkdecoder = cx.expr_ident(trait_span, blkarg); match *substr.fields { @@ -93,7 +92,7 @@ fn decodable_substructure( Unnamed(ref fields, _) => fields.len(), Named(ref fields) => fields.len(), }; - let read_struct_field = cx.ident_of("read_struct_field", trait_span); + let read_struct_field = Ident::new(sym::read_struct_field, trait_span); let path = cx.path_ident(trait_span, substr.type_ident); let result = @@ -116,7 +115,7 @@ fn decodable_substructure( cx.expr_method_call( trait_span, decoder, - cx.ident_of("read_struct", trait_span), + Ident::new(sym::read_struct, trait_span), vec![ cx.expr_str(trait_span, substr.type_ident.name), cx.expr_usize(trait_span, nfields), @@ -125,11 +124,11 @@ fn decodable_substructure( ) } StaticEnum(_, ref fields) => { - let variant = cx.ident_of("i", trait_span); + let variant = Ident::new(sym::i, trait_span); let mut arms = Vec::with_capacity(fields.len() + 1); let mut variants = Vec::with_capacity(fields.len()); - let rvariant_arg = cx.ident_of("read_enum_variant_arg", trait_span); + let rvariant_arg = Ident::new(sym::read_enum_variant_arg, trait_span); for (i, &(ident, v_span, ref parts)) in fields.iter().enumerate() { variants.push(cx.expr_str(v_span, ident.name)); @@ -164,13 +163,13 @@ fn decodable_substructure( let result = cx.expr_method_call( trait_span, blkdecoder, - cx.ident_of("read_enum_variant", trait_span), + Ident::new(sym::read_enum_variant, trait_span), vec![variant_vec, lambda], ); cx.expr_method_call( trait_span, decoder, - cx.ident_of("read_enum", trait_span), + Ident::new(sym::read_enum, trait_span), vec![ cx.expr_str(trait_span, substr.type_ident.name), cx.lambda1(trait_span, result, blkarg), diff --git a/src/librustc_builtin_macros/deriving/default.rs b/src/librustc_builtin_macros/deriving/default.rs index 5dfb0e8f37c63..8ca1be1efb635 100644 --- a/src/librustc_builtin_macros/deriving/default.rs +++ b/src/librustc_builtin_macros/deriving/default.rs @@ -1,6 +1,5 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; -use crate::deriving::path_std; use rustc_ast::ast::{Expr, MetaItem}; use rustc_ast::ptr::P; @@ -21,14 +20,14 @@ pub fn expand_deriving_default( let trait_def = TraitDef { span, attributes: Vec::new(), - path: path_std!(cx, default::Default), + path: Path::new(vec![kw::Default, sym::Default]), additional_bounds: Vec::new(), - generics: LifetimeBounds::empty(), + generics: Bounds::empty(), is_unsafe: false, supports_unions: false, methods: vec![MethodDef { name: kw::Default, - generics: LifetimeBounds::empty(), + generics: Bounds::empty(), explicit_self: None, args: Vec::new(), ret_ty: Self_, diff --git a/src/librustc_builtin_macros/deriving/encodable.rs b/src/librustc_builtin_macros/deriving/encodable.rs index 4a90b7a193886..7a880357a5947 100644 --- a/src/librustc_builtin_macros/deriving/encodable.rs +++ b/src/librustc_builtin_macros/deriving/encodable.rs @@ -92,7 +92,7 @@ use crate::deriving::pathvec_std; use rustc_ast::ast::{Expr, ExprKind, MetaItem, Mutability}; use rustc_ast::ptr::P; use rustc_expand::base::{Annotatable, ExtCtxt}; -use rustc_span::symbol::{sym, Symbol}; +use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; pub fn expand_deriving_rustc_encodable( @@ -102,38 +102,42 @@ pub fn expand_deriving_rustc_encodable( item: &Annotatable, push: &mut dyn FnMut(Annotatable), ) { - let krate = "rustc_serialize"; - let typaram = "__S"; + let krate = sym::rustc_serialize; + let typaram = sym::__S; let trait_def = TraitDef { span, attributes: Vec::new(), - path: Path::new_(vec![krate, "Encodable"], None, vec![], PathKind::Global), + path: Path::new_(vec![krate, sym::Encodable], None, vec![], PathKind::Global), additional_bounds: Vec::new(), - generics: LifetimeBounds::empty(), + generics: Bounds::empty(), is_unsafe: false, supports_unions: false, methods: vec![MethodDef { name: sym::encode, - generics: LifetimeBounds { - lifetimes: Vec::new(), + generics: Bounds { bounds: vec![( typaram, - vec![Path::new_(vec![krate, "Encoder"], None, vec![], PathKind::Global)], + vec![Path::new_(vec![krate, sym::Encoder], None, vec![], PathKind::Global)], )], }, explicit_self: borrowed_explicit_self(), args: vec![( Ptr(Box::new(Literal(Path::new_local(typaram))), Borrowed(None, Mutability::Mut)), - "s", + // FIXME: we could use `sym::s` here, but making `s` a static + // symbol changes the symbol index ordering in a way that makes + // ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs + // fail. The linting code should be fixed so that its output + // does not depend on the symbol index ordering. + Symbol::intern("s"), )], ret_ty: Literal(Path::new_( - pathvec_std!(cx, result::Result), + pathvec_std!(result::Result), None, vec![ Box::new(Tuple(Vec::new())), Box::new(Literal(Path::new_( - vec![typaram, "Error"], + vec![typaram, sym::Error], None, vec![], PathKind::Local, @@ -158,24 +162,24 @@ fn encodable_substructure( cx: &mut ExtCtxt<'_>, trait_span: Span, substr: &Substructure<'_>, - krate: &'static str, + krate: Symbol, ) -> P { let encoder = substr.nonself_args[0].clone(); // throw an underscore in front to suppress unused variable warnings - let blkarg = cx.ident_of("_e", trait_span); + let blkarg = Ident::new(sym::_e, trait_span); let blkencoder = cx.expr_ident(trait_span, blkarg); let fn_path = cx.expr_path(cx.path_global( trait_span, vec![ - cx.ident_of(krate, trait_span), - cx.ident_of("Encodable", trait_span), - cx.ident_of("encode", trait_span), + Ident::new(krate, trait_span), + Ident::new(sym::Encodable, trait_span), + Ident::new(sym::encode, trait_span), ], )); match *substr.fields { Struct(_, ref fields) => { - let emit_struct_field = cx.ident_of("emit_struct_field", trait_span); + let emit_struct_field = Ident::new(sym::emit_struct_field, trait_span); let mut stmts = Vec::new(); for (i, &FieldInfo { name, ref self_, span, .. }) in fields.iter().enumerate() { let name = match name { @@ -215,7 +219,7 @@ fn encodable_substructure( cx.expr_method_call( trait_span, encoder, - cx.ident_of("emit_struct", trait_span), + Ident::new(sym::emit_struct, trait_span), vec![ cx.expr_str(trait_span, substr.type_ident.name), cx.expr_usize(trait_span, fields.len()), @@ -231,7 +235,7 @@ fn encodable_substructure( // actually exist. let me = cx.stmt_let(trait_span, false, blkarg, encoder); let encoder = cx.expr_ident(trait_span, blkarg); - let emit_variant_arg = cx.ident_of("emit_enum_variant_arg", trait_span); + let emit_variant_arg = Ident::new(sym::emit_enum_variant_arg, trait_span); let mut stmts = Vec::new(); if !fields.is_empty() { let last = fields.len() - 1; @@ -264,7 +268,7 @@ fn encodable_substructure( let call = cx.expr_method_call( trait_span, blkencoder, - cx.ident_of("emit_enum_variant", trait_span), + Ident::new(sym::emit_enum_variant, trait_span), vec![ name, cx.expr_usize(trait_span, idx), @@ -276,7 +280,7 @@ fn encodable_substructure( let ret = cx.expr_method_call( trait_span, encoder, - cx.ident_of("emit_enum", trait_span), + Ident::new(sym::emit_enum, trait_span), vec![cx.expr_str(trait_span, substr.type_ident.name), blk], ); cx.expr_block(cx.block(trait_span, vec![me, cx.stmt_expr(ret)])) diff --git a/src/librustc_builtin_macros/deriving/generic/mod.rs b/src/librustc_builtin_macros/deriving/generic/mod.rs index 050774aa24c96..c43d1cf1888c4 100644 --- a/src/librustc_builtin_macros/deriving/generic/mod.rs +++ b/src/librustc_builtin_macros/deriving/generic/mod.rs @@ -191,7 +191,7 @@ use rustc_span::source_map::respan; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; -use ty::{LifetimeBounds, Path, Ptr, PtrTy, Self_, Ty}; +use ty::{Bounds, Path, Ptr, PtrTy, Self_, Ty}; use crate::deriving; @@ -204,14 +204,14 @@ pub struct TraitDef<'a> { pub attributes: Vec, /// Path of the trait, including any type parameters - pub path: Path<'a>, + pub path: Path, /// Additional bounds required of any type parameters of the type, /// other than the current trait - pub additional_bounds: Vec>, + pub additional_bounds: Vec, /// Any extra lifetimes and/or bounds, e.g., `D: serialize::Decoder` - pub generics: LifetimeBounds<'a>, + pub generics: Bounds, /// Is it an `unsafe` trait? pub is_unsafe: bool, @@ -221,14 +221,14 @@ pub struct TraitDef<'a> { pub methods: Vec>, - pub associated_types: Vec<(Ident, Ty<'a>)>, + pub associated_types: Vec<(Ident, Ty)>, } pub struct MethodDef<'a> { /// name of the method pub name: Symbol, /// List of generics, e.g., `R: rand::Rng` - pub generics: LifetimeBounds<'a>, + pub generics: Bounds, /// Whether there is a self argument (outer Option) i.e., whether /// this is a static function, and whether it is a pointer (inner @@ -236,10 +236,10 @@ pub struct MethodDef<'a> { pub explicit_self: Option>, /// Arguments other than the self argument - pub args: Vec<(Ty<'a>, &'a str)>, + pub args: Vec<(Ty, Symbol)>, /// Returns type - pub ret_ty: Ty<'a>, + pub ret_ty: Ty, pub attributes: Vec, @@ -865,7 +865,7 @@ impl<'a> MethodDef<'a> { for (ty, name) in self.args.iter() { let ast_ty = ty.to_ty(cx, trait_.span, type_ident, generics); - let ident = cx.ident_of(name, trait_.span); + let ident = Ident::new(*name, trait_.span); arg_tys.push((ident, ast_ty)); let arg_expr = cx.expr_ident(trait_.span, ident); @@ -1170,8 +1170,10 @@ impl<'a> MethodDef<'a> { ) .collect::>(); - let self_arg_idents = - self_arg_names.iter().map(|name| cx.ident_of(name, sp)).collect::>(); + let self_arg_idents = self_arg_names + .iter() + .map(|name| Ident::from_str_and_span(name, sp)) + .collect::>(); // The `vi_idents` will be bound, solely in the catch-all, to // a series of let statements mapping each self_arg to an int @@ -1180,7 +1182,7 @@ impl<'a> MethodDef<'a> { .iter() .map(|name| { let vi_suffix = format!("{}_vi", &name[..]); - cx.ident_of(&vi_suffix[..], trait_.span) + Ident::from_str_and_span(&vi_suffix, trait_.span) }) .collect::>(); @@ -1568,7 +1570,7 @@ impl<'a> TraitDef<'a> { let mut ident_exprs = Vec::new(); for (i, struct_field) in struct_def.fields().iter().enumerate() { let sp = struct_field.span.with_ctxt(self.span.ctxt()); - let ident = cx.ident_of(&format!("{}_{}", prefix, i), self.span); + let ident = Ident::from_str_and_span(&format!("{}_{}", prefix, i), self.span); paths.push(ident.with_span_pos(sp)); let val = cx.expr_path(cx.path_ident(sp, ident)); let val = if use_temporaries { val } else { cx.expr_deref(sp, val) }; diff --git a/src/librustc_builtin_macros/deriving/generic/ty.rs b/src/librustc_builtin_macros/deriving/generic/ty.rs index 609feb6f259d6..51314dbcffc06 100644 --- a/src/librustc_builtin_macros/deriving/generic/ty.rs +++ b/src/librustc_builtin_macros/deriving/generic/ty.rs @@ -8,7 +8,7 @@ use rustc_ast::ast::{self, Expr, GenericArg, GenericParamKind, Generics, SelfKin use rustc_ast::ptr::P; use rustc_expand::base::ExtCtxt; use rustc_span::source_map::{respan, DUMMY_SP}; -use rustc_span::symbol::{kw, Ident}; +use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::Span; /// The types of pointers @@ -24,10 +24,10 @@ pub enum PtrTy { /// A path, e.g., `::std::option::Option::` (global). Has support /// for type parameters and a lifetime. #[derive(Clone)] -pub struct Path<'a> { - path: Vec<&'a str>, +pub struct Path { + path: Vec, lifetime: Option, - params: Vec>>, + params: Vec>, kind: PathKind, } @@ -38,19 +38,19 @@ pub enum PathKind { Std, } -impl<'a> Path<'a> { - pub fn new(path: Vec<&str>) -> Path<'_> { +impl Path { + pub fn new(path: Vec) -> Path { Path::new_(path, None, Vec::new(), PathKind::Std) } - pub fn new_local(path: &str) -> Path<'_> { + pub fn new_local(path: Symbol) -> Path { Path::new_(vec![path], None, Vec::new(), PathKind::Local) } - pub fn new_<'r>( - path: Vec<&'r str>, + pub fn new_( + path: Vec, lifetime: Option, - params: Vec>>, + params: Vec>, kind: PathKind, - ) -> Path<'r> { + ) -> Path { Path { path, lifetime, params, kind } } @@ -70,7 +70,7 @@ impl<'a> Path<'a> { self_ty: Ident, self_generics: &Generics, ) -> ast::Path { - let mut idents = self.path.iter().map(|s| cx.ident_of(*s, span)).collect(); + let mut idents = self.path.iter().map(|s| Ident::new(*s, span)).collect(); let lt = mk_lifetimes(cx, span, &self.lifetime); let tys: Vec> = self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect(); @@ -94,21 +94,21 @@ impl<'a> Path<'a> { /// A type. Supports pointers, Self, and literals. #[derive(Clone)] -pub enum Ty<'a> { +pub enum Ty { Self_, /// &/Box/ Ty - Ptr(Box>, PtrTy), + Ptr(Box, PtrTy), /// `mod::mod::Type<[lifetime], [Params...]>`, including a plain type /// parameter, and things like `i32` - Literal(Path<'a>), + Literal(Path), /// includes unit - Tuple(Vec>), + Tuple(Vec), } pub fn borrowed_ptrty() -> PtrTy { Borrowed(None, ast::Mutability::Not) } -pub fn borrowed(ty: Box>) -> Ty<'_> { +pub fn borrowed(ty: Box) -> Ty { Ptr(ty, borrowed_ptrty()) } @@ -116,11 +116,11 @@ pub fn borrowed_explicit_self() -> Option> { Some(Some(borrowed_ptrty())) } -pub fn borrowed_self<'r>() -> Ty<'r> { +pub fn borrowed_self() -> Ty { borrowed(Box::new(Self_)) } -pub fn nil_ty<'r>() -> Ty<'r> { +pub fn nil_ty() -> Ty { Tuple(Vec::new()) } @@ -132,7 +132,7 @@ fn mk_lifetimes(cx: &ExtCtxt<'_>, span: Span, lt: &Option) -> Vec Ty<'a> { +impl Ty { pub fn to_ty( &self, cx: &ExtCtxt<'_>, @@ -199,9 +199,9 @@ impl<'a> Ty<'a> { fn mk_ty_param( cx: &ExtCtxt<'_>, span: Span, - name: &str, + name: Symbol, attrs: &[ast::Attribute], - bounds: &[Path<'_>], + bounds: &[Path], self_ident: Ident, self_generics: &Generics, ) -> ast::GenericParam { @@ -212,7 +212,7 @@ fn mk_ty_param( cx.trait_bound(path) }) .collect(); - cx.typaram(span, cx.ident_of(name, span), attrs.to_owned(), bounds, None) + cx.typaram(span, Ident::new(name, span), attrs.to_owned(), bounds, None) } fn mk_generics(params: Vec, span: Span) -> Generics { @@ -223,16 +223,15 @@ fn mk_generics(params: Vec, span: Span) -> Generics { } } -/// Lifetimes and bounds on type parameters +/// Bounds on type parameters. #[derive(Clone)] -pub struct LifetimeBounds<'a> { - pub lifetimes: Vec<(&'a str, Vec<&'a str>)>, - pub bounds: Vec<(&'a str, Vec>)>, +pub struct Bounds { + pub bounds: Vec<(Symbol, Vec)>, } -impl<'a> LifetimeBounds<'a> { - pub fn empty() -> LifetimeBounds<'a> { - LifetimeBounds { lifetimes: Vec::new(), bounds: Vec::new() } +impl Bounds { + pub fn empty() -> Bounds { + Bounds { bounds: Vec::new() } } pub fn to_generics( &self, @@ -242,18 +241,12 @@ impl<'a> LifetimeBounds<'a> { self_generics: &Generics, ) -> Generics { let generic_params = self - .lifetimes + .bounds .iter() - .map(|&(lt, ref bounds)| { - let bounds = bounds - .iter() - .map(|b| ast::GenericBound::Outlives(cx.lifetime(span, Ident::from_str(b)))); - cx.lifetime_def(span, Ident::from_str(lt), vec![], bounds.collect()) - }) - .chain(self.bounds.iter().map(|t| { + .map(|t| { let (name, ref bounds) = *t; mk_ty_param(cx, span, name, &[], &bounds, self_ty, self_generics) - })) + }) .collect(); mk_generics(generic_params, span) diff --git a/src/librustc_builtin_macros/deriving/hash.rs b/src/librustc_builtin_macros/deriving/hash.rs index f975b75f0be13..d7195188085f0 100644 --- a/src/librustc_builtin_macros/deriving/hash.rs +++ b/src/librustc_builtin_macros/deriving/hash.rs @@ -15,9 +15,9 @@ pub fn expand_deriving_hash( item: &Annotatable, push: &mut dyn FnMut(Annotatable), ) { - let path = Path::new_(pathvec_std!(cx, hash::Hash), None, vec![], PathKind::Std); + let path = Path::new_(pathvec_std!(hash::Hash), None, vec![], PathKind::Std); - let typaram = "__H"; + let typaram = sym::__H; let arg = Path::new_local(typaram); let hash_trait_def = TraitDef { @@ -25,17 +25,14 @@ pub fn expand_deriving_hash( attributes: Vec::new(), path, additional_bounds: Vec::new(), - generics: LifetimeBounds::empty(), + generics: Bounds::empty(), is_unsafe: false, supports_unions: false, methods: vec![MethodDef { name: sym::hash, - generics: LifetimeBounds { - lifetimes: Vec::new(), - bounds: vec![(typaram, vec![path_std!(cx, hash::Hasher)])], - }, + generics: Bounds { bounds: vec![(typaram, vec![path_std!(hash::Hasher)])] }, explicit_self: borrowed_explicit_self(), - args: vec![(Ptr(Box::new(Literal(arg)), Borrowed(None, Mutability::Mut)), "state")], + args: vec![(Ptr(Box::new(Literal(arg)), Borrowed(None, Mutability::Mut)), sym::state)], ret_ty: nil_ty(), attributes: vec![], is_unsafe: false, diff --git a/src/librustc_builtin_macros/deriving/mod.rs b/src/librustc_builtin_macros/deriving/mod.rs index 6cee21fc6e69d..33c0edde98f0b 100644 --- a/src/librustc_builtin_macros/deriving/mod.rs +++ b/src/librustc_builtin_macros/deriving/mod.rs @@ -7,11 +7,11 @@ use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; macro path_local($x:ident) { - generic::ty::Path::new_local(stringify!($x)) + generic::ty::Path::new_local(sym::$x) } -macro pathvec_std($cx:expr, $($rest:ident)::+) {{ - vec![ $( stringify!($rest) ),+ ] +macro pathvec_std($($rest:ident)::+) {{ + vec![ $( sym::$rest ),+ ] }} macro path_std($($x:tt)*) { @@ -84,7 +84,7 @@ fn inject_impl_of_structural_trait( cx: &mut ExtCtxt<'_>, span: Span, item: &Annotatable, - structural_path: generic::ty::Path<'_>, + structural_path: generic::ty::Path, push: &mut dyn FnMut(Annotatable), ) { let item = match *item { diff --git a/src/librustc_builtin_macros/format.rs b/src/librustc_builtin_macros/format.rs index 2becbe2f6758a..55eab24b8a510 100644 --- a/src/librustc_builtin_macros/format.rs +++ b/src/librustc_builtin_macros/format.rs @@ -578,31 +578,31 @@ impl<'a, 'b> Context<'a, 'b> { self.count_args_index_offset = sofar; } - fn rtpath(ecx: &ExtCtxt<'_>, s: &str) -> Vec { - ecx.std_path(&[sym::fmt, sym::rt, sym::v1, Symbol::intern(s)]) + fn rtpath(ecx: &ExtCtxt<'_>, s: Symbol) -> Vec { + ecx.std_path(&[sym::fmt, sym::rt, sym::v1, s]) } fn build_count(&self, c: parse::Count) -> P { let sp = self.macsp; let count = |c, arg| { - let mut path = Context::rtpath(self.ecx, "Count"); - path.push(self.ecx.ident_of(c, sp)); + let mut path = Context::rtpath(self.ecx, sym::Count); + path.push(Ident::new(c, sp)); match arg { Some(arg) => self.ecx.expr_call_global(sp, path, vec![arg]), None => self.ecx.expr_path(self.ecx.path_global(sp, path)), } }; match c { - parse::CountIs(i) => count("Is", Some(self.ecx.expr_usize(sp, i))), + parse::CountIs(i) => count(sym::Is, Some(self.ecx.expr_usize(sp, i))), parse::CountIsParam(i) => { // This needs mapping too, as `i` is referring to a macro // argument. If `i` is not found in `count_positions` then // the error had already been emitted elsewhere. let i = self.count_positions.get(&i).cloned().unwrap_or(0) + self.count_args_index_offset; - count("Param", Some(self.ecx.expr_usize(sp, i))) + count(sym::Param, Some(self.ecx.expr_usize(sp, i))) } - parse::CountImplied => count("Implied", None), + parse::CountImplied => count(sym::Implied, None), // should never be the case, names are already resolved parse::CountIsName(_) => panic!("should never happen"), } @@ -690,40 +690,40 @@ impl<'a, 'b> Context<'a, 'b> { // Build the format let fill = self.ecx.expr_lit(sp, ast::LitKind::Char(fill)); let align = |name| { - let mut p = Context::rtpath(self.ecx, "Alignment"); - p.push(self.ecx.ident_of(name, sp)); + let mut p = Context::rtpath(self.ecx, sym::Alignment); + p.push(Ident::new(name, sp)); self.ecx.path_global(sp, p) }; let align = match arg.format.align { - parse::AlignLeft => align("Left"), - parse::AlignRight => align("Right"), - parse::AlignCenter => align("Center"), - parse::AlignUnknown => align("Unknown"), + parse::AlignLeft => align(sym::Left), + parse::AlignRight => align(sym::Right), + parse::AlignCenter => align(sym::Center), + parse::AlignUnknown => align(sym::Unknown), }; let align = self.ecx.expr_path(align); let flags = self.ecx.expr_u32(sp, arg.format.flags); let prec = self.build_count(arg.format.precision); let width = self.build_count(arg.format.width); - let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, "FormatSpec")); + let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, sym::FormatSpec)); let fmt = self.ecx.expr_struct( sp, path, vec![ - self.ecx.field_imm(sp, self.ecx.ident_of("fill", sp), fill), - self.ecx.field_imm(sp, self.ecx.ident_of("align", sp), align), - self.ecx.field_imm(sp, self.ecx.ident_of("flags", sp), flags), - self.ecx.field_imm(sp, self.ecx.ident_of("precision", sp), prec), - self.ecx.field_imm(sp, self.ecx.ident_of("width", sp), width), + self.ecx.field_imm(sp, Ident::new(sym::fill, sp), fill), + self.ecx.field_imm(sp, Ident::new(sym::align, sp), align), + self.ecx.field_imm(sp, Ident::new(sym::flags, sp), flags), + self.ecx.field_imm(sp, Ident::new(sym::precision, sp), prec), + self.ecx.field_imm(sp, Ident::new(sym::width, sp), width), ], ); - let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, "Argument")); + let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, sym::Argument)); Some(self.ecx.expr_struct( sp, path, vec![ - self.ecx.field_imm(sp, self.ecx.ident_of("position", sp), pos), - self.ecx.field_imm(sp, self.ecx.ident_of("format", sp), fmt), + self.ecx.field_imm(sp, Ident::new(sym::position, sp), pos), + self.ecx.field_imm(sp, Ident::new(sym::format, sp), fmt), ], )) } @@ -740,7 +740,7 @@ impl<'a, 'b> Context<'a, 'b> { let mut heads = Vec::with_capacity(self.args.len()); let names_pos: Vec<_> = (0..self.args.len()) - .map(|i| self.ecx.ident_of(&format!("arg{}", i), self.macsp)) + .map(|i| Ident::from_str_and_span(&format!("arg{}", i), self.macsp)) .collect(); // First, build up the static array which will become our precompiled diff --git a/src/librustc_builtin_macros/global_allocator.rs b/src/librustc_builtin_macros/global_allocator.rs index f8a9a97b2a50e..89446a1aa96f9 100644 --- a/src/librustc_builtin_macros/global_allocator.rs +++ b/src/librustc_builtin_macros/global_allocator.rs @@ -58,7 +58,7 @@ impl AllocFnFactory<'_, '_> { let mut abi_args = Vec::new(); let mut i = 0; let mut mk = || { - let name = self.cx.ident_of(&format!("arg{}", i), self.span); + let name = Ident::from_str_and_span(&format!("arg{}", i), self.span); i += 1; name }; @@ -72,7 +72,7 @@ impl AllocFnFactory<'_, '_> { let kind = ItemKind::Fn(ast::Defaultness::Final, sig, Generics::default(), block); let item = self.cx.item( self.span, - self.cx.ident_of(&self.kind.fn_name(method.name), self.span), + Ident::from_str_and_span(&self.kind.fn_name(method.name), self.span), self.attrs(), kind, ); diff --git a/src/librustc_builtin_macros/proc_macro_harness.rs b/src/librustc_builtin_macros/proc_macro_harness.rs index 7cc9c1f76631e..f044ce41e879e 100644 --- a/src/librustc_builtin_macros/proc_macro_harness.rs +++ b/src/librustc_builtin_macros/proc_macro_harness.rs @@ -384,12 +384,12 @@ fn mk_decls( let proc_macro = Ident::new(sym::proc_macro, span); let krate = cx.item(span, proc_macro, Vec::new(), ast::ItemKind::ExternCrate(None)); - let bridge = cx.ident_of("bridge", span); - let client = cx.ident_of("client", span); - let proc_macro_ty = cx.ident_of("ProcMacro", span); - let custom_derive = cx.ident_of("custom_derive", span); - let attr = cx.ident_of("attr", span); - let bang = cx.ident_of("bang", span); + let bridge = Ident::new(sym::bridge, span); + let client = Ident::new(sym::client, span); + let proc_macro_ty = Ident::new(sym::ProcMacro, span); + let custom_derive = Ident::new(sym::custom_derive, span); + let attr = Ident::new(sym::attr, span); + let bang = Ident::new(sym::bang, span); let krate_ref = RefCell::new(ast_krate); @@ -447,7 +447,7 @@ fn mk_decls( let decls_static = cx .item_static( span, - cx.ident_of("_DECLS", span), + Ident::new(sym::_DECLS, span), cx.ty_rptr( span, cx.ty( diff --git a/src/librustc_builtin_macros/test.rs b/src/librustc_builtin_macros/test.rs index d62f34bab1a31..460f947a792af 100644 --- a/src/librustc_builtin_macros/test.rs +++ b/src/librustc_builtin_macros/test.rs @@ -108,22 +108,38 @@ pub fn expand_test_or_bench( let test_id = Ident::new(sym::test, attr_sp); // creates test::$name - let test_path = |name| cx.path(sp, vec![test_id, cx.ident_of(name, sp)]); + let test_path = |name| cx.path(sp, vec![test_id, Ident::from_str_and_span(name, sp)]); // creates test::ShouldPanic::$name - let should_panic_path = - |name| cx.path(sp, vec![test_id, cx.ident_of("ShouldPanic", sp), cx.ident_of(name, sp)]); + let should_panic_path = |name| { + cx.path( + sp, + vec![ + test_id, + Ident::from_str_and_span("ShouldPanic", sp), + Ident::from_str_and_span(name, sp), + ], + ) + }; // creates test::TestType::$name - let test_type_path = - |name| cx.path(sp, vec![test_id, cx.ident_of("TestType", sp), cx.ident_of(name, sp)]); + let test_type_path = |name| { + cx.path( + sp, + vec![ + test_id, + Ident::from_str_and_span("TestType", sp), + Ident::from_str_and_span(name, sp), + ], + ) + }; // creates $name: $expr - let field = |name, expr| cx.field_imm(sp, cx.ident_of(name, sp), expr); + let field = |name, expr| cx.field_imm(sp, Ident::from_str_and_span(name, sp), expr); let test_fn = if is_bench { // A simple ident for a lambda - let b = cx.ident_of("b", attr_sp); + let b = Ident::from_str_and_span("b", attr_sp); cx.expr_call( sp, diff --git a/src/librustc_builtin_macros/test_harness.rs b/src/librustc_builtin_macros/test_harness.rs index 98e42ebf46f2a..98c5c6936d779 100644 --- a/src/librustc_builtin_macros/test_harness.rs +++ b/src/librustc_builtin_macros/test_harness.rs @@ -270,7 +270,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P { let mut test_runner = cx .test_runner .clone() - .unwrap_or(ecx.path(sp, vec![test_id, ecx.ident_of(runner_name, sp)])); + .unwrap_or(ecx.path(sp, vec![test_id, Ident::from_str_and_span(runner_name, sp)])); test_runner.span = sp; diff --git a/src/librustc_error_codes/error_codes/E0723.md b/src/librustc_error_codes/error_codes/E0723.md index 394ee057b0b0c..95d47ab21cbd3 100644 --- a/src/librustc_error_codes/error_codes/E0723.md +++ b/src/librustc_error_codes/error_codes/E0723.md @@ -1,4 +1,4 @@ -An feature unstable in `const` contexts was used. +An unstable feature in `const` contexts was used. Erroneous code example: diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs index 3e48224ef9f20..64e2d5b3a467c 100644 --- a/src/librustc_expand/base.rs +++ b/src/librustc_expand/base.rs @@ -1061,9 +1061,6 @@ impl<'a> ExtCtxt<'a> { pub fn set_trace_macros(&mut self, x: bool) { self.ecfg.trace_mac = x } - pub fn ident_of(&self, st: &str, sp: Span) -> Ident { - Ident::from_str_and_span(st, sp) - } pub fn std_path(&self, components: &[Symbol]) -> Vec { let def_site = self.with_def_site_ctxt(DUMMY_SP); iter::once(Ident::new(kw::DollarCrate, def_site)) diff --git a/src/librustc_expand/build.rs b/src/librustc_expand/build.rs index 20d2ea0a215d4..81ff4b3157845 100644 --- a/src/librustc_expand/build.rs +++ b/src/librustc_expand/build.rs @@ -368,7 +368,7 @@ impl<'a> ExtCtxt<'a> { let err = self.std_path(&[sym::result, sym::Result, sym::Err]); let err_path = self.path_global(sp, err); - let binding_variable = self.ident_of("__try_var", sp); + let binding_variable = Ident::new(sym::__try_var, sp); let binding_pat = self.pat_ident(sp, binding_variable); let binding_expr = self.expr_ident(sp, binding_variable); diff --git a/src/librustc_middle/mir/query.rs b/src/librustc_middle/mir/query.rs index 560a8421c1797..b311f8344bb6d 100644 --- a/src/librustc_middle/mir/query.rs +++ b/src/librustc_middle/mir/query.rs @@ -8,7 +8,7 @@ use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_index::bit_set::BitMatrix; use rustc_index::vec::IndexVec; -use rustc_span::{Span, Symbol}; +use rustc_span::Span; use rustc_target::abi::VariantIdx; use smallvec::SmallVec; use std::cell::Cell; @@ -18,7 +18,7 @@ use super::{Field, SourceInfo}; #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)] pub enum UnsafetyViolationKind { - /// Only permitted in regular `fn`s, prohibitted in `const fn`s. + /// Only permitted in regular `fn`s, prohibited in `const fn`s. General, /// Permitted both in `const fn`s and regular `fn`s. GeneralAndConstFn, @@ -35,13 +35,97 @@ pub enum UnsafetyViolationKind { UnsafeFnBorrowPacked, } +#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)] +pub enum UnsafetyViolationDetails { + CallToUnsafeFunction, + UseOfInlineAssembly, + InitializingTypeWith, + CastOfPointerToInt, + BorrowOfPackedField, + UseOfMutableStatic, + UseOfExternStatic, + DerefOfRawPointer, + AssignToNonCopyUnionField, + AccessToUnionField, + MutationOfLayoutConstrainedField, + BorrowOfLayoutConstrainedField, + CallToFunctionWith, +} + +impl UnsafetyViolationDetails { + pub fn description_and_note(&self) -> (&'static str, &'static str) { + use UnsafetyViolationDetails::*; + match self { + CallToUnsafeFunction => ( + "call to unsafe function", + "consult the function's documentation for information on how to avoid undefined \ + behavior", + ), + UseOfInlineAssembly => ( + "use of inline assembly", + "inline assembly is entirely unchecked and can cause undefined behavior", + ), + InitializingTypeWith => ( + "initializing type with `rustc_layout_scalar_valid_range` attr", + "initializing a layout restricted type's field with a value outside the valid \ + range is undefined behavior", + ), + CastOfPointerToInt => { + ("cast of pointer to int", "casting pointers to integers in constants") + } + BorrowOfPackedField => ( + "borrow of packed field", + "fields of packed structs might be misaligned: dereferencing a misaligned pointer \ + or even just creating a misaligned reference is undefined behavior", + ), + UseOfMutableStatic => ( + "use of mutable static", + "mutable statics can be mutated by multiple threads: aliasing violations or data \ + races will cause undefined behavior", + ), + UseOfExternStatic => ( + "use of extern static", + "extern statics are not controlled by the Rust type system: invalid data, \ + aliasing violations or data races will cause undefined behavior", + ), + DerefOfRawPointer => ( + "dereference of raw pointer", + "raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules \ + and cause data races: all of these are undefined behavior", + ), + AssignToNonCopyUnionField => ( + "assignment to non-`Copy` union field", + "the previous content of the field will be dropped, which causes undefined \ + behavior if the field was not properly initialized", + ), + AccessToUnionField => ( + "access to union field", + "the field may not be properly initialized: using uninitialized data will cause \ + undefined behavior", + ), + MutationOfLayoutConstrainedField => ( + "mutation of layout constrained field", + "mutating layout constrained fields cannot statically be checked for valid values", + ), + BorrowOfLayoutConstrainedField => ( + "borrow of layout constrained field with interior mutability", + "references to fields of layout constrained fields lose the constraints. Coupled \ + with interior mutability, the field can be changed to invalid values", + ), + CallToFunctionWith => ( + "call to function with `#[target_feature]`", + "can only be called if the required target features are available", + ), + } + } +} + #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)] pub struct UnsafetyViolation { pub source_info: SourceInfo, pub lint_root: hir::HirId, - pub description: Symbol, - pub details: Symbol, pub kind: UnsafetyViolationKind, + pub details: UnsafetyViolationDetails, } #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] diff --git a/src/librustc_middle/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs index b50d2852c1c5c..043d85cb6efa6 100644 --- a/src/librustc_middle/ty/print/pretty.rs +++ b/src/librustc_middle/ty/print/pretty.rs @@ -1440,12 +1440,12 @@ impl Printer<'tcx> for FmtPrinter<'_, 'tcx, F> { // FIXME(eddyb) `name` should never be empty, but it // currently is for `extern { ... }` "foreign modules". - let name = disambiguated_data.data.as_symbol().as_str(); - if !name.is_empty() { + let name = disambiguated_data.data.as_symbol(); + if name != kw::Invalid { if !self.empty_path { write!(self, "::")?; } - if Ident::from_str(&name).is_raw_guess() { + if Ident::with_dummy_span(name).is_raw_guess() { write!(self, "r#")?; } write!(self, "{}", name)?; diff --git a/src/librustc_middle/ty/query/profiling_support.rs b/src/librustc_middle/ty/query/profiling_support.rs index 3c44662441890..0683dc0201129 100644 --- a/src/librustc_middle/ty/query/profiling_support.rs +++ b/src/librustc_middle/ty/query/profiling_support.rs @@ -60,12 +60,12 @@ impl<'p, 'c, 'tcx> QueryKeyStringBuilder<'p, 'c, 'tcx> { match def_key.disambiguated_data.data { DefPathData::CrateRoot => { - name = self.tcx.original_crate_name(def_id.krate).as_str(); + name = self.tcx.original_crate_name(def_id.krate); dis = ""; end_index = 3; } other => { - name = other.as_symbol().as_str(); + name = other.as_symbol(); if def_key.disambiguated_data.disambiguator == 0 { dis = ""; end_index = 3; @@ -79,10 +79,11 @@ impl<'p, 'c, 'tcx> QueryKeyStringBuilder<'p, 'c, 'tcx> { } } + let name = &*name.as_str(); let components = [ StringComponent::Ref(parent_string_id), StringComponent::Value("::"), - StringComponent::Value(&name[..]), + StringComponent::Value(name), StringComponent::Value(dis), ]; diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 2605d45f8101e..81d7ac0892622 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -12,7 +12,7 @@ use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::lint::builtin::{SAFE_PACKED_BORROWS, UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE}; use rustc_session::lint::Level; -use rustc_span::symbol::{sym, Symbol}; +use rustc_span::symbol::sym; use std::ops::Bound; @@ -86,10 +86,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { let sig = func_ty.fn_sig(self.tcx); if let hir::Unsafety::Unsafe = sig.unsafety() { self.require_unsafe( - "call to unsafe function", - "consult the function's documentation for information on how to avoid \ - undefined behavior", UnsafetyViolationKind::GeneralAndConstFn, + UnsafetyViolationDetails::CallToUnsafeFunction, ) } @@ -99,9 +97,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { } TerminatorKind::InlineAsm { .. } => self.require_unsafe( - "use of inline assembly", - "inline assembly is entirely unchecked and can cause undefined behavior", UnsafetyViolationKind::General, + UnsafetyViolationDetails::UseOfInlineAssembly, ), } self.super_terminator(terminator, location); @@ -122,9 +119,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { } StatementKind::LlvmInlineAsm { .. } => self.require_unsafe( - "use of inline assembly", - "inline assembly is entirely unchecked and can cause undefined behavior", UnsafetyViolationKind::General, + UnsafetyViolationDetails::UseOfInlineAssembly, ), } self.super_statement(statement, location); @@ -138,10 +134,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { match self.tcx.layout_scalar_valid_range(def.did) { (Bound::Unbounded, Bound::Unbounded) => {} _ => self.require_unsafe( - "initializing type with `rustc_layout_scalar_valid_range` attr", - "initializing a layout restricted type's field with a value \ - outside the valid range is undefined behavior", UnsafetyViolationKind::GeneralAndConstFn, + UnsafetyViolationDetails::InitializingTypeWith, ), } } @@ -163,9 +157,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { match (cast_in, cast_out) { (CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) => { self.require_unsafe( - "cast of pointer to int", - "casting pointers to integers in constants", UnsafetyViolationKind::General, + UnsafetyViolationDetails::CastOfPointerToInt, ); } _ => {} @@ -190,11 +183,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { if context.is_borrow() { if util::is_disaligned(self.tcx, self.body, self.param_env, *place) { self.require_unsafe( - "borrow of packed field", - "fields of packed structs might be misaligned: dereferencing a \ - misaligned pointer or even just creating a misaligned reference \ - is undefined behavior", UnsafetyViolationKind::BorrowPacked, + UnsafetyViolationDetails::BorrowOfPackedField, ); } } @@ -204,11 +194,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { if context.is_borrow() { if util::is_disaligned(self.tcx, self.body, self.param_env, *place) { self.require_unsafe( - "borrow of packed field", - "fields of packed structs might be misaligned: dereferencing a \ - misaligned pointer or even just creating a misaligned reference \ - is undefined behavior", UnsafetyViolationKind::BorrowPacked, + UnsafetyViolationDetails::BorrowOfPackedField, ); } } @@ -219,19 +206,14 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { if let Some(box LocalInfo::StaticRef { def_id, .. }) = decl.local_info { if self.tcx.is_mutable_static(def_id) { self.require_unsafe( - "use of mutable static", - "mutable statics can be mutated by multiple threads: aliasing \ - violations or data races will cause undefined behavior", UnsafetyViolationKind::General, + UnsafetyViolationDetails::UseOfMutableStatic, ); return; } else if self.tcx.is_foreign_item(def_id) { self.require_unsafe( - "use of extern static", - "extern statics are not controlled by the Rust type system: \ - invalid data, aliasing violations or data races will cause \ - undefined behavior", UnsafetyViolationKind::General, + UnsafetyViolationDetails::UseOfExternStatic, ); return; } @@ -246,11 +228,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { let base_ty = Place::ty_from(place.local, proj_base, self.body, self.tcx).ty; match base_ty.kind { ty::RawPtr(..) => self.require_unsafe( - "dereference of raw pointer", - "raw pointers may be NULL, dangling or unaligned; they can violate \ - aliasing rules and cause data races: all of these are undefined \ - behavior", UnsafetyViolationKind::General, + UnsafetyViolationDetails::DerefOfRawPointer, ), ty::Adt(adt, _) => { if adt.is_union() { @@ -271,21 +250,16 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { self.param_env, ) { self.require_unsafe( - "assignment to non-`Copy` union field", - "the previous content of the field will be dropped, which \ - causes undefined behavior if the field was not properly \ - initialized", UnsafetyViolationKind::GeneralAndConstFn, + UnsafetyViolationDetails::AssignToNonCopyUnionField, ) } else { // write to non-move union, safe } } else { self.require_unsafe( - "access to union field", - "the field may not be properly initialized: using \ - uninitialized data will cause undefined behavior", UnsafetyViolationKind::GeneralAndConstFn, + UnsafetyViolationDetails::AccessToUnionField, ) } } @@ -298,12 +272,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { } impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { - fn require_unsafe( - &mut self, - description: &'static str, - details: &'static str, - kind: UnsafetyViolationKind, - ) { + fn require_unsafe(&mut self, kind: UnsafetyViolationKind, details: UnsafetyViolationDetails) { let source_info = self.source_info; let lint_root = self.body.source_scopes[self.source_info.scope] .local_data @@ -311,13 +280,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { .assert_crate_local() .lint_root; self.register_violations( - &[UnsafetyViolation { - source_info, - lint_root, - description: Symbol::intern(description), - details: Symbol::intern(details), - kind, - }], + &[UnsafetyViolation { source_info, lint_root, kind, details }], &[], ); } @@ -434,12 +397,8 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { if self.tcx.layout_scalar_valid_range(def.did) != (Bound::Unbounded, Bound::Unbounded) { - let (description, details) = if is_mut_use { - ( - "mutation of layout constrained field", - "mutating layout constrained fields cannot statically be \ - checked for valid values", - ) + let details = if is_mut_use { + UnsafetyViolationDetails::MutationOfLayoutConstrainedField // Check `is_freeze` as late as possible to avoid cycle errors // with opaque types. @@ -448,21 +407,11 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { .ty .is_freeze(self.tcx.at(self.source_info.span), self.param_env) { - ( - "borrow of layout constrained field with interior \ - mutability", - "references to fields of layout constrained fields \ - lose the constraints. Coupled with interior mutability, \ - the field can be changed to invalid values", - ) + UnsafetyViolationDetails::BorrowOfLayoutConstrainedField } else { continue; }; - self.require_unsafe( - description, - details, - UnsafetyViolationKind::GeneralAndConstFn, - ); + self.require_unsafe(UnsafetyViolationKind::GeneralAndConstFn, details); } } } @@ -480,9 +429,8 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { // Is `callee_features` a subset of `calling_features`? if !callee_features.iter().all(|feature| self_features.contains(feature)) { self.require_unsafe( - "call to function with `#[target_feature]`", - "can only be called if the required target features are available", UnsafetyViolationKind::GeneralAndConstFn, + UnsafetyViolationDetails::CallToFunctionWith, ) } } @@ -675,9 +623,9 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { let UnsafetyCheckResult { violations, unsafe_blocks } = tcx.unsafety_check_result(def_id); - for &UnsafetyViolation { source_info, lint_root, description, details, kind } in - violations.iter() - { + for &UnsafetyViolation { source_info, lint_root, kind, details } in violations.iter() { + let (description, note) = details.description_and_note(); + // Report an error. let unsafe_fn_msg = if unsafe_op_in_unsafe_fn_allowed(tcx, lint_root) { " function or" } else { "" }; @@ -693,8 +641,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { description, unsafe_fn_msg, ) - .span_label(source_info.span, &*description.as_str()) - .note(&details.as_str()) + .span_label(source_info.span, description) + .note(note) .emit(); } UnsafetyViolationKind::BorrowPacked => { @@ -712,7 +660,7 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { "{} is unsafe and requires unsafe{} block (error E0133)", description, unsafe_fn_msg, )) - .note(&details.as_str()) + .note(note) .emit() }, ) @@ -727,8 +675,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { "{} is unsafe and requires unsafe block (error E0133)", description, )) - .span_label(source_info.span, &*description.as_str()) - .note(&details.as_str()) + .span_label(source_info.span, description) + .note(note) .emit(); }, ), @@ -756,8 +704,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { "{} is unsafe and requires unsafe block (error E0133)", description, )) - .span_label(source_info.span, &*description.as_str()) - .note(&details.as_str()) + .span_label(source_info.span, description) + .note(note) .emit(); }) } diff --git a/src/librustc_passes/stability.rs b/src/librustc_passes/stability.rs index 76bc6b6c85f02..5d972c70d1392 100644 --- a/src/librustc_passes/stability.rs +++ b/src/librustc_passes/stability.rs @@ -502,7 +502,8 @@ impl Visitor<'tcx> for Checker<'tcx> { match item.kind { hir::ItemKind::ExternCrate(_) => { // compiler-generated `extern crate` items have a dummy span. - if item.span.is_dummy() { + // `std` is still checked for the `restricted-std` feature. + if item.span.is_dummy() && item.ident.as_str() != "std" { return; } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 8db27babd058b..45253fc878222 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -111,12 +111,17 @@ impl<'a> Resolver<'a> { (self.cstore().crate_name_untracked(def_id.krate), None) } else { let def_key = self.cstore().def_key(def_id); - ( - // This unwrap is safe: crates must always have a name - def_key.disambiguated_data.data.get_opt_name().unwrap(), - // This unwrap is safe since we know this isn't the root - Some(self.get_module(DefId { index: def_key.parent.unwrap(), ..def_id })), - ) + let name = def_key + .disambiguated_data + .data + .get_opt_name() + .expect("given a DefId that wasn't a module"); + // This unwrap is safe since we know this isn't the root + let parent = Some(self.get_module(DefId { + index: def_key.parent.expect("failed to get parent for module"), + ..def_id + })); + (name, parent) }; // Allocate and return a new module with the information we found diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index c3686ca4899bc..686385e24ece8 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2978,7 +2978,7 @@ impl<'a> Resolver<'a> { span: Span, path_str: &str, ns: Namespace, - module_id: LocalDefId, + module_id: DefId, ) -> Result<(ast::Path, Res), ()> { let path = if path_str.starts_with("::") { ast::Path { @@ -2998,7 +2998,7 @@ impl<'a> Resolver<'a> { .collect(), } }; - let module = self.module_map.get(&module_id).copied().unwrap_or(self.graph_root); + let module = self.get_module(module_id); let parent_scope = &ParentScope::module(module); let res = self.resolve_ast_path(&path, ns, parent_scope).map_err(|_| ())?; Ok((path, res)) diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index ccb6ccb57fa40..5d332ddf5f3df 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -122,19 +122,28 @@ symbols! { // There is currently no checking that all symbols are used; that would be // nice to have. Symbols { + Alignment, Arc, + Argument, ArgumentV1, Arguments, C, + Center, Clone, Copy, + Count, Debug, Decodable, + Decoder, Default, Encodable, + Encoder, Eq, Equal, Err, + Error, + FormatSpec, + Formatter, From, Future, FxHashMap, @@ -143,11 +152,15 @@ symbols! { Hash, HashMap, HashSet, + Hasher, + Implied, Input, IntoIterator, + Is, ItemContext, Iterator, Layout, + Left, LintPass, None, Ok, @@ -155,11 +168,13 @@ symbols! { Ord, Ordering, Output, + Param, PartialEq, PartialOrd, Pending, Pin, Poll, + ProcMacro, ProcMacroHack, ProceduralMasqueradeDummyType, Range, @@ -172,20 +187,31 @@ symbols! { Ready, Result, Return, + Right, RustcDecodable, RustcEncodable, Send, Some, + StructuralEq, + StructuralPartialEq, Sync, Target, Try, Ty, TyCtxt, TyKind, + Unknown, Vec, Yield, + _DECLS, _Self, + __D, + __H, + __S, __next, + __try_var, + _d, + _e, _task_context, aarch64_target_feature, abi, @@ -226,6 +252,7 @@ symbols! { allowed, always, and, + and_then, any, arbitrary_enum_discriminant, arbitrary_self_types, @@ -256,6 +283,7 @@ symbols! { automatically_derived, avx512_target_feature, await_macro, + bang, begin_panic, bench, bin, @@ -278,6 +306,7 @@ symbols! { box_syntax, braced_empty_structs, breakpoint, + bridge, bswap, c_variadic, call, @@ -299,6 +328,7 @@ symbols! { cfg_target_vendor, cfg_version, char, + client, clippy, clone, clone_closures, @@ -370,11 +400,15 @@ symbols! { custom_derive, custom_inner_attributes, custom_test_frameworks, + d, dead_code, dealloc, debug, debug_assertions, + debug_struct, debug_trait, + debug_trait_builder, + debug_tuple, decl_macro, declare_lint_pass, decode, @@ -421,6 +455,11 @@ symbols! { dyn_trait, eh_catch_typeinfo, eh_personality, + emit_enum, + emit_enum_variant, + emit_enum_variant_arg, + emit_struct, + emit_struct_field, enable, enclosing_scope, encode, @@ -448,6 +487,7 @@ symbols! { extern_prelude, extern_types, external_doc, + f, f16c_target_feature, f32, f32_runtime, @@ -464,6 +504,9 @@ symbols! { field, field_init_shorthand, file, + fill, + finish, + flags, float_to_int_unchecked, floorf32, floorf64, @@ -478,6 +521,7 @@ symbols! { fn_once_output, forbid, forget, + format, format_args, format_args_capture, format_args_nl, @@ -519,6 +563,7 @@ symbols! { html_no_source, html_playground_url, html_root_url, + i, i128, i128_type, i16, @@ -606,6 +651,7 @@ symbols! { main, managed_boxes, manually_drop, + map, marker, marker_trait_attr, masked, @@ -708,6 +754,7 @@ symbols! { options, or, or_patterns, + other, out, overlapping_marker_traits, owned_box, @@ -739,6 +786,7 @@ symbols! { plugins, pointer, poll, + position, post_dash_lto: "post-lto", powerpc_target_feature, powf32, @@ -747,6 +795,7 @@ symbols! { powif64, pre_dash_lto: "pre-lto", precise_pointer_size_matching, + precision, pref_align_of, prefetch_read_data, prefetch_read_instruction, @@ -783,6 +832,11 @@ symbols! { raw_identifiers, raw_ref_op, re_rebalance_coherence, + read_enum, + read_enum_variant, + read_enum_variant_arg, + read_struct, + read_struct_field, readonly, realloc, reason, @@ -872,6 +926,7 @@ symbols! { rustc_promotable, rustc_regions, rustc_reservation_impl, + rustc_serialize, rustc_specialization_trait, rustc_stable, rustc_std_internal_symbol, @@ -976,6 +1031,7 @@ symbols! { stable, staged_api, start, + state, static_in_const, static_nobundle, static_recursion, @@ -1123,6 +1179,7 @@ symbols! { wasm_import_module, wasm_target_feature, while_let, + width, windows, windows_subsystem, wrapping_add, diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs index 79d5c148ce4fe..a9b045cee6087 100644 --- a/src/librustc_trait_selection/traits/error_reporting/mod.rs +++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs @@ -26,7 +26,7 @@ use rustc_middle::ty::{ TypeFoldable, WithConstness, }; use rustc_session::DiagnosticMessageId; -use rustc_span::symbol::sym; +use rustc_span::symbol::{kw, sym}; use rustc_span::{ExpnKind, MultiSpan, Span, DUMMY_SP}; use std::fmt; @@ -1524,7 +1524,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { (self.tcx.sess.source_map().span_to_snippet(span), &obligation.cause.code) { let generics = self.tcx.generics_of(*def_id); - if generics.params.iter().any(|p| p.name.as_str() != "Self") + if generics.params.iter().any(|p| p.name != kw::SelfUpper) && !snippet.ends_with('>') { // FIXME: To avoid spurious suggestions in functions where type arguments diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 9a9630f095886..f575548ddd638 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -322,12 +322,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let self_ty = self.tables.borrow().node_type(method_expr[0].hir_id); let self_ty = format!("{:?}", self_ty); - let name = method_path.ident.as_str(); + let name = method_path.ident.name; let is_as_ref_able = (self_ty.starts_with("&std::option::Option") || self_ty.starts_with("&std::result::Result") || self_ty.starts_with("std::option::Option") || self_ty.starts_with("std::result::Result")) - && (name == "map" || name == "and_then"); + && (name == sym::map || name == sym::and_then); match (is_as_ref_able, self.sess().source_map().span_to_snippet(*method_span)) { (true, Ok(src)) => { let suggestion = format!("as_ref().{}", src); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 00315675fafe3..6a52974534f8b 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -430,7 +430,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt DUMMY_SP, extern_name, TypeNS, - LocalDefId { local_def_index: CRATE_DEF_INDEX }, + LocalDefId { local_def_index: CRATE_DEF_INDEX }.to_def_id(), ) .unwrap_or_else(|()| { panic!("Unable to resolve external crate {}", extern_name) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 31e35125dac57..f872ed7010c75 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2230,12 +2230,15 @@ fn stability_tags(item: &clean::Item) -> String { tags += &tag_html("deprecated", message); } - if let Some(stab) = item.stability.as_ref().filter(|s| s.level == stability::Unstable) { - if stab.feature.as_deref() == Some("rustc_private") { - tags += &tag_html("internal", "Internal"); - } else { - tags += &tag_html("unstable", "Experimental"); - } + // The "rustc_private" crates are permanently unstable so it makes no sense + // to render "unstable" everywhere. + if item + .stability + .as_ref() + .map(|s| s.level == stability::Unstable && s.feature.as_deref() != Some("rustc_private")) + == Some(true) + { + tags += &tag_html("unstable", "Experimental"); } if let Some(ref cfg) = item.attrs.cfg { @@ -2286,15 +2289,13 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec { )); } - if let Some(stab) = item.stability.as_ref().filter(|stab| stab.level == stability::Unstable) { - let is_rustc_private = stab.feature.as_deref() == Some("rustc_private"); - - let mut message = if is_rustc_private { - "⚙️ This is an internal compiler API." - } else { - "🔬 This is a nightly-only experimental API." - } - .to_owned(); + // Render unstable items. But don't render "rustc_private" crates (internal compiler crates). + // Those crates are permanently unstable so it makes no sense to render "unstable" everywhere. + if let Some(stab) = item.stability.as_ref().filter(|stab| { + stab.level == stability::Unstable && stab.feature.as_deref() != Some("rustc_private") + }) { + let mut message = + "🔬 This is a nightly-only experimental API.".to_owned(); if let Some(feature) = stab.feature.as_deref() { let mut feature = format!("{}", Escape(&feature)); @@ -2310,17 +2311,6 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec { } if let Some(unstable_reason) = &stab.unstable_reason { - // Provide a more informative message than the compiler help. - let unstable_reason = if is_rustc_private { - "This crate is being loaded from the sysroot, a permanently unstable location \ - for private compiler dependencies. It is not intended for general use. Prefer \ - using a public version of this crate from \ - [crates.io](https://crates.io) via [`Cargo.toml`]\ - (https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html)." - } else { - unstable_reason - }; - let mut ids = cx.id_map.borrow_mut(); message = format!( "
{}{}
", @@ -2336,8 +2326,7 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec { ); } - let class = if is_rustc_private { "internal" } else { "unstable" }; - stability.push(format!("
{}
", class, message)); + stability.push(format!("
{}
", message)); } if let Some(ref cfg) = item.attrs.cfg { diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css index b436997da5816..1326acec51ce1 100644 --- a/src/librustdoc/html/static/themes/ayu.css +++ b/src/librustdoc/html/static/themes/ayu.css @@ -108,7 +108,7 @@ pre { } .sidebar .version { - border-bottom-color: #DDD; + border-bottom-color: #424c57; } .sidebar-title { @@ -198,7 +198,7 @@ pre.rust .comment, pre.rust .doccomment { } nav:not(.sidebar) { - border-bottom-color: #e0e0e0; + border-bottom-color: #424c57; } nav.main .current { border-top-color: #5c6773; @@ -216,10 +216,6 @@ a { color: #39AFD7; } -.stab.internal a { - color: #304FFE; -} - .collapse-toggle { color: #999; } @@ -227,22 +223,19 @@ a { #crate-search { color: #c5c5c5; background-color: #141920; - border-radius: 4px; - box-shadow: none; - border-color: #5c6773; + box-shadow: 0 0 0 1px #424c57,0 0 0 2px transparent; + border-color: #424c57; } .search-input { color: #ffffff; background-color: #141920; - box-shadow: none; + box-shadow: 0 0 0 1px #424c57,0 0 0 2px transparent; transition: box-shadow 150ms ease-in-out; - border-radius: 4px; - margin-left: 8px; } #crate-search+.search-input:focus { - box-shadow: 0px 6px 20px 0px black; + box-shadow: 0 0 0 1px #148099,0 0 0 2px transparent; } .search-focus:disabled { @@ -254,7 +247,6 @@ a { } .stab.unstable, -.stab.internal, .stab.deprecated, .stab.portability { color: #c5c5c5; @@ -462,7 +454,6 @@ pre.rust .doccomment {} .content .highlighted.type {} pre.rust .kw-2,pre.rust .prelude-ty {} .content span.trait,.content a.trait,.block a.current.trait {} -.stab.internal {} @media (max-width: 700px) { .sidebar-menu { diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index f4ca67f8540a9..dc15220aa0690 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -172,10 +172,6 @@ a { color: #D2991D; } -.stab.internal a { - color: #304FFE; -} - a.test-arrow { color: #dedede; } @@ -214,7 +210,6 @@ a.test-arrow { } .stab.unstable { background: #FFF5D6; border-color: #FFC600; color: #2f2f2f; } -.stab.internal { background: #FFB9B3; border-color: #B71C1C; color: #2f2f2f; } .stab.deprecated { background: #F3DFFF; border-color: #7F0087; color: #2f2f2f; } .stab.portability { background: #C4ECFF; border-color: #7BA5DB; color: #2f2f2f; } diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index b5a0ba4775c24..64d59ca411a87 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -173,10 +173,6 @@ a { color: #3873AD; } -.stab.internal a { - color: #304FFE; -} - a.test-arrow { color: #f5f5f5; } @@ -215,7 +211,6 @@ a.test-arrow { } .stab.unstable { background: #FFF5D6; border-color: #FFC600; } -.stab.internal { background: #FFB9B3; border-color: #B71C1C; } .stab.deprecated { background: #F3DFFF; border-color: #7F0087; } .stab.portability { background: #C4ECFF; border-color: #7BA5DB; } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index f707c1a3e1a10..b1db1328392e7 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -8,7 +8,7 @@ use rustc_hir::def::{ Namespace::{self, *}, PerNS, Res, }; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::DefId; use rustc_middle::ty; use rustc_resolve::ParentScope; use rustc_session::lint; @@ -50,7 +50,8 @@ enum ErrorKind { struct LinkCollector<'a, 'tcx> { cx: &'a DocContext<'tcx>, - mod_ids: Vec, + // NOTE: this may not necessarily be a module in the current crate + mod_ids: Vec, } impl<'a, 'tcx> LinkCollector<'a, 'tcx> { @@ -62,7 +63,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { &self, path_str: &str, current_item: &Option, - module_id: LocalDefId, + module_id: DefId, ) -> Result<(Res, Option), ErrorKind> { let cx = self.cx; @@ -124,7 +125,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { } /// Resolves a string as a macro. - fn macro_resolve(&self, path_str: &str, parent_id: Option) -> Option { + fn macro_resolve(&self, path_str: &str, parent_id: Option) -> Option { let cx = self.cx; let path = ast::Path::from_ident(Ident::from_str(path_str)); cx.enter_resolver(|resolver| { @@ -142,8 +143,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { if let Some(res) = resolver.all_macros().get(&Symbol::intern(path_str)) { return Some(res.map_id(|_| panic!("unexpected id"))); } - if let Some(module_id) = parent_id.or(self.mod_ids.last().cloned()) { - let module_id = cx.tcx.hir().local_def_id(module_id); + if let Some(module_id) = parent_id { if let Ok((_, res)) = resolver.resolve_str_path_error(DUMMY_SP, path_str, MacroNS, module_id) { @@ -167,15 +167,14 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { disambiguator: Option<&str>, ns: Namespace, current_item: &Option, - parent_id: Option, + parent_id: Option, extra_fragment: &Option, item_opt: Option<&Item>, ) -> Result<(Res, Option), ErrorKind> { let cx = self.cx; // In case we're in a module, try to resolve the relative path. - if let Some(module_id) = parent_id.or(self.mod_ids.last().cloned()) { - let module_id = cx.tcx.hir().local_def_id(module_id); + if let Some(module_id) = parent_id { let result = cx.enter_resolver(|resolver| { resolver.resolve_str_path_error(DUMMY_SP, &path_str, ns, module_id) }); @@ -445,40 +444,40 @@ fn is_derive_trait_collision(ns: &PerNS>) -> bool { impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { fn fold_item(&mut self, mut item: Item) -> Option { - let item_hir_id = if item.is_mod() { - if let Some(def_id) = item.def_id.as_local() { - Some(self.cx.tcx.hir().as_local_hir_id(def_id)) - } else { - debug!("attempting to fold on a non-local item: {:?}", item); - return self.fold_item_recur(item); - } - } else { - None - }; + use rustc_middle::ty::DefIdTree; - // FIXME: get the resolver to work with non-local resolve scopes. - let parent_node = self.cx.as_local_hir_id(item.def_id).and_then(|hir_id| { - // FIXME: this fails hard for impls in non-module scope, but is necessary for the - // current `resolve()` implementation. - match self.cx.as_local_hir_id(self.cx.tcx.parent_module(hir_id).to_def_id()).unwrap() { - id if id != hir_id => Some(id), - _ => None, + let parent_node = if item.is_fake() { + // FIXME: is this correct? + None + } else { + let mut current = item.def_id; + // The immediate parent might not always be a module. + // Find the first parent which is. + loop { + if let Some(parent) = self.cx.tcx.parent(current) { + if self.cx.tcx.def_kind(parent) == DefKind::Mod { + break Some(parent); + } + current = parent; + } else { + break None; + } } - }); + }; if parent_node.is_some() { - debug!("got parent node for {:?} {:?}, id {:?}", item.type_(), item.name, item.def_id); + trace!("got parent node for {:?} {:?}, id {:?}", item.type_(), item.name, item.def_id); } let current_item = match item.inner { ModuleItem(..) => { if item.attrs.inner_docs { - if item_hir_id.unwrap() != hir::CRATE_HIR_ID { item.name.clone() } else { None } + if item.def_id.is_top_level_module() { item.name.clone() } else { None } } else { - match parent_node.or(self.mod_ids.last().cloned()) { - Some(parent) if parent != hir::CRATE_HIR_ID => { + match parent_node.or(self.mod_ids.last().copied()) { + Some(parent) if !parent.is_top_level_module() => { // FIXME: can we pull the parent module's name from elsewhere? - Some(self.cx.tcx.hir().name(parent).to_string()) + Some(self.cx.tcx.item_name(parent).to_string()) } _ => None, } @@ -488,18 +487,22 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { for_.def_id().map(|did| self.cx.tcx.item_name(did).to_string()) } // we don't display docs on `extern crate` items anyway, so don't process them. - ExternCrateItem(..) => return self.fold_item_recur(item), + ExternCrateItem(..) => { + debug!("ignoring extern crate item {:?}", item.def_id); + return self.fold_item_recur(item); + } ImportItem(Import::Simple(ref name, ..)) => Some(name.clone()), MacroItem(..) => None, _ => item.name.clone(), }; if item.is_mod() && item.attrs.inner_docs { - self.mod_ids.push(item_hir_id.unwrap()); + self.mod_ids.push(item.def_id); } let cx = self.cx; let dox = item.attrs.collapsed_doc_value().unwrap_or_else(String::new); + trace!("got documentation '{}'", dox); look_for_tests(&cx, &dox, &item, true); @@ -541,6 +544,8 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { }); for (ori_link, link_range) in markdown_links(&dox) { + trace!("considering link '{}'", ori_link); + // Bail early for real links. if ori_link.contains('/') { continue; @@ -641,8 +646,11 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { // we've already pushed this node onto the resolution stack but // for outer comments we explicitly try and resolve against the // parent_node first. - let base_node = - if item.is_mod() && item.attrs.inner_docs { None } else { parent_node }; + let base_node = if item.is_mod() && item.attrs.inner_docs { + self.mod_ids.last().copied() + } else { + parent_node + }; // replace `Self` with suitable item's parent name if path_str.starts_with("Self::") { @@ -826,7 +834,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { } if item.is_mod() && !item.attrs.inner_docs { - self.mod_ids.push(item_hir_id.unwrap()); + self.mod_ids.push(item.def_id); } if item.is_mod() { @@ -864,6 +872,7 @@ fn build_diagnostic( Some(hir_id) => hir_id, None => { // If non-local, no need to check anything. + info!("ignoring warning from parent crate: {}", err_msg); return; } }; diff --git a/src/libstd/build.rs b/src/libstd/build.rs index 743a1778fbda3..eb2753d62457a 100644 --- a/src/libstd/build.rs +++ b/src/libstd/build.rs @@ -62,5 +62,29 @@ fn main() { } println!("cargo:rustc-link-lib=c"); println!("cargo:rustc-link-lib=compiler_rt"); + } else if (target.contains("sgx") && target.contains("fortanix")) + || target.contains("hermit") + || target.contains("l4re") + || target.contains("redox") + || target.contains("haiku") + || target.contains("vxworks") + || target.contains("wasm32") + || target.contains("asmjs") + { + // These platforms don't have any special requirements. + } else { + // This is for Cargo's build-std support, to mark std as unstable for + // typically no_std platforms. + // This covers: + // - os=none ("bare metal" targets) + // - mipsel-sony-psp + // - nvptx64-nvidia-cuda + // - avr-unknown-unknown + // - tvos (aarch64-apple-tvos, x86_64-apple-tvos) + // - uefi (x86_64-unknown-uefi, i686-unknown-uefi) + // - JSON targets + // - Any new targets that have not been explicitly added above. + println!("cargo:rustc-cfg=feature=\"restricted-std\""); } + println!("cargo:rustc-env=STD_ENV_ARCH={}", env::var("CARGO_CFG_TARGET_ARCH").unwrap()); } diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 97c20ca9459ef..6489e0709cb91 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -882,7 +882,7 @@ pub mod consts { /// - s390x /// - sparc64 #[stable(feature = "env", since = "1.0.0")] - pub const ARCH: &str = super::arch::ARCH; + pub const ARCH: &str = env!("STD_ENV_ARCH"); /// The family of the operating system. Example value is `unix`. /// @@ -966,81 +966,6 @@ pub mod consts { pub const EXE_EXTENSION: &str = os::EXE_EXTENSION; } -#[cfg(target_arch = "x86")] -mod arch { - pub const ARCH: &str = "x86"; -} - -#[cfg(target_arch = "x86_64")] -mod arch { - pub const ARCH: &str = "x86_64"; -} - -#[cfg(target_arch = "arm")] -mod arch { - pub const ARCH: &str = "arm"; -} - -#[cfg(target_arch = "aarch64")] -mod arch { - pub const ARCH: &str = "aarch64"; -} - -#[cfg(target_arch = "mips")] -mod arch { - pub const ARCH: &str = "mips"; -} - -#[cfg(target_arch = "mips64")] -mod arch { - pub const ARCH: &str = "mips64"; -} - -#[cfg(target_arch = "powerpc")] -mod arch { - pub const ARCH: &str = "powerpc"; -} - -#[cfg(target_arch = "powerpc64")] -mod arch { - pub const ARCH: &str = "powerpc64"; -} - -#[cfg(target_arch = "s390x")] -mod arch { - pub const ARCH: &str = "s390x"; -} - -#[cfg(target_arch = "sparc64")] -mod arch { - pub const ARCH: &str = "sparc64"; -} - -#[cfg(target_arch = "le32")] -mod arch { - pub const ARCH: &str = "le32"; -} - -#[cfg(target_arch = "asmjs")] -mod arch { - pub const ARCH: &str = "asmjs"; -} - -#[cfg(target_arch = "wasm32")] -mod arch { - pub const ARCH: &str = "wasm32"; -} - -#[cfg(target_arch = "hexagon")] -mod arch { - pub const ARCH: &'static str = "hexagon"; -} - -#[cfg(target_arch = "riscv64")] -mod arch { - pub const ARCH: &'static str = "riscv64"; -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index cbc24009a949a..b5ba0da7ae50d 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -198,7 +198,8 @@ //! [primitive types]: ../book/ch03-02-data-types.html //! [rust-discord]: https://discord.gg/rust-lang -#![stable(feature = "rust1", since = "1.0.0")] +#![cfg_attr(not(feature = "restricted-std"), stable(feature = "rust1", since = "1.0.0"))] +#![cfg_attr(feature = "restricted-std", unstable(feature = "restricted_std", issue = "none"))] #![doc( html_root_url = "https://doc.rust-lang.org/nightly/", html_playground_url = "https://play.rust-lang.org/", @@ -554,3 +555,9 @@ include!("primitive_docs.rs"); // the rustdoc documentation for the existing keywords. Using `include!` // because rustdoc only looks for these modules at the crate level. include!("keyword_docs.rs"); + +// This is required to avoid an unstable error when `restricted-std` is not +// enabled. The use of #![feature(restricted_std)] in rustc-std-workspace-std +// is unconditional, so the unstable feature needs to be defined somewhere. +#[cfg_attr(not(feature = "restricted-std"), unstable(feature = "restricted_std", issue = "none"))] +mod __restricted_std_workaround {} diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index 2250c0d4203ef..9b90bfd68b50f 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -694,7 +694,6 @@ mod tests { #[test] #[cfg_attr(target_os = "emscripten", ignore)] - #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn wait_timeout_wait() { let m = Arc::new(Mutex::new(())); let c = Arc::new(Condvar::new()); @@ -714,7 +713,6 @@ mod tests { #[test] #[cfg_attr(target_os = "emscripten", ignore)] - #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn wait_timeout_while_wait() { let m = Arc::new(Mutex::new(())); let c = Arc::new(Condvar::new()); @@ -739,7 +737,6 @@ mod tests { #[test] #[cfg_attr(target_os = "emscripten", ignore)] - #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn wait_timeout_while_wake() { let pair = Arc::new((Mutex::new(false), Condvar::new())); let pair_copy = pair.clone(); @@ -763,7 +760,6 @@ mod tests { #[test] #[cfg_attr(target_os = "emscripten", ignore)] - #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn wait_timeout_wake() { let m = Arc::new(Mutex::new(())); let c = Arc::new(Condvar::new()); diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index d6cc811154f11..3ff50e9f21347 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -2088,7 +2088,6 @@ mod tests { } #[test] - #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn oneshot_single_thread_recv_timeout() { let (tx, rx) = channel(); tx.send(()).unwrap(); @@ -2099,7 +2098,6 @@ mod tests { } #[test] - #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn stress_recv_timeout_two_threads() { let (tx, rx) = channel(); let stress = stress_factor() + 100; @@ -2130,7 +2128,6 @@ mod tests { } #[test] - #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn recv_timeout_upgrade() { let (tx, rx) = channel::<()>(); let timeout = Duration::from_millis(1); @@ -2142,7 +2139,6 @@ mod tests { } #[test] - #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn stress_recv_timeout_shared() { let (tx, rx) = channel(); let stress = stress_factor() + 100; @@ -2173,7 +2169,6 @@ mod tests { } #[test] - #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn very_long_recv_timeout_wont_panic() { let (tx, rx) = channel::<()>(); let join_handle = thread::spawn(move || rx.recv_timeout(Duration::from_secs(u64::MAX))); @@ -2195,7 +2190,6 @@ mod tests { } #[test] - #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn shared_recv_timeout() { let (tx, rx) = channel(); let total = 5; @@ -2425,7 +2419,6 @@ mod sync_tests { } #[test] - #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn recv_timeout() { let (tx, rx) = sync_channel::(1); assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Err(RecvTimeoutError::Timeout)); @@ -2517,7 +2510,6 @@ mod sync_tests { } #[test] - #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn stress_recv_timeout_two_threads() { let (tx, rx) = sync_channel::(0); @@ -2543,7 +2535,6 @@ mod sync_tests { } #[test] - #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn stress_recv_timeout_shared() { const AMT: u32 = 1000; const NTHREADS: u32 = 8; diff --git a/src/libstd/sys/mod.rs b/src/libstd/sys/mod.rs index 875ff1af92013..7b5fac922d08a 100644 --- a/src/libstd/sys/mod.rs +++ b/src/libstd/sys/mod.rs @@ -48,7 +48,8 @@ cfg_if::cfg_if! { mod sgx; pub use self::sgx::*; } else { - compile_error!("libstd doesn't compile for this platform yet"); + mod unsupported; + pub use self::unsupported::*; } } diff --git a/src/libstd/sys/sgx/abi/usercalls/mod.rs b/src/libstd/sys/sgx/abi/usercalls/mod.rs index ae803ee47a6cb..73f1b951e7430 100644 --- a/src/libstd/sys/sgx/abi/usercalls/mod.rs +++ b/src/libstd/sys/sgx/abi/usercalls/mod.rs @@ -1,6 +1,8 @@ use crate::cmp; -use crate::io::{Error as IoError, IoSlice, IoSliceMut, Result as IoResult}; -use crate::time::Duration; +use crate::convert::TryFrom; +use crate::io::{Error as IoError, ErrorKind, IoSlice, IoSliceMut, Result as IoResult}; +use crate::sys::rand::rdrand64; +use crate::time::{Duration, Instant}; pub(crate) mod alloc; #[macro_use] @@ -149,10 +151,94 @@ pub fn exit(panic: bool) -> ! { /// Usercall `wait`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] -pub fn wait(event_mask: u64, timeout: u64) -> IoResult { +pub fn wait(event_mask: u64, mut timeout: u64) -> IoResult { + if timeout != WAIT_NO && timeout != WAIT_INDEFINITE { + // We don't want people to rely on accuracy of timeouts to make + // security decisions in an SGX enclave. That's why we add a random + // amount not exceeding +/- 10% to the timeout value to discourage + // people from relying on accuracy of timeouts while providing a way + // to make things work in other cases. Note that in the SGX threat + // model the enclave runner which is serving the wait usercall is not + // trusted to ensure accurate timeouts. + if let Ok(timeout_signed) = i64::try_from(timeout) { + let tenth = timeout_signed / 10; + let deviation = (rdrand64() as i64).checked_rem(tenth).unwrap_or(0); + timeout = timeout_signed.saturating_add(deviation) as _; + } + } unsafe { raw::wait(event_mask, timeout).from_sgx_result() } } +/// This function makes an effort to wait for a non-spurious event at least as +/// long as `duration`. Note that in general there is no guarantee about accuracy +/// of time and timeouts in SGX model. The enclave runner serving usercalls may +/// lie about current time and/or ignore timeout values. +/// +/// Once the event is observed, `should_wake_up` will be used to determine +/// whether or not the event was spurious. +#[unstable(feature = "sgx_platform", issue = "56975")] +pub fn wait_timeout(event_mask: u64, duration: Duration, should_wake_up: F) +where + F: Fn() -> bool, +{ + // Calls the wait usercall and checks the result. Returns true if event was + // returned, and false if WouldBlock/TimedOut was returned. + // If duration is None, it will use WAIT_NO. + fn wait_checked(event_mask: u64, duration: Option) -> bool { + let timeout = duration.map_or(raw::WAIT_NO, |duration| { + cmp::min((u64::MAX - 1) as u128, duration.as_nanos()) as u64 + }); + match wait(event_mask, timeout) { + Ok(eventset) => { + if event_mask == 0 { + rtabort!("expected wait() to return Err, found Ok."); + } + rtassert!(eventset != 0 && eventset & !event_mask == 0); + true + } + Err(e) => { + rtassert!(e.kind() == ErrorKind::TimedOut || e.kind() == ErrorKind::WouldBlock); + false + } + } + } + + match wait_checked(event_mask, Some(duration)) { + false => return, // timed out + true if should_wake_up() => return, // woken up + true => {} // spurious event + } + + // Drain all cached events. + // Note that `event_mask != 0` is implied if we get here. + loop { + match wait_checked(event_mask, None) { + false => break, // no more cached events + true if should_wake_up() => return, // woken up + true => {} // spurious event + } + } + + // Continue waiting, but take note of time spent waiting so we don't wait + // forever. We intentionally don't call `Instant::now()` before this point + // to avoid the cost of the `insecure_time` usercall in case there are no + // spurious wakeups. + + let start = Instant::now(); + let mut remaining = duration; + loop { + match wait_checked(event_mask, Some(remaining)) { + false => return, // timed out + true if should_wake_up() => return, // woken up + true => {} // spurious event + } + remaining = match duration.checked_sub(start.elapsed()) { + Some(remaining) => remaining, + None => break, + } + } +} + /// Usercall `send`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] pub fn send(event_set: u64, tcs: Option) -> IoResult<()> { diff --git a/src/libstd/sys/sgx/condvar.rs b/src/libstd/sys/sgx/condvar.rs index 9c5c086184d68..ed6dbcf497147 100644 --- a/src/libstd/sys/sgx/condvar.rs +++ b/src/libstd/sys/sgx/condvar.rs @@ -31,8 +31,10 @@ impl Condvar { mutex.lock() } - pub unsafe fn wait_timeout(&self, _mutex: &Mutex, _dur: Duration) -> bool { - rtabort!("timeout not supported in SGX"); + pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { + let success = WaitQueue::wait_timeout(&self.inner, dur, || mutex.unlock()); + mutex.lock(); + success } #[inline] diff --git a/src/libstd/sys/sgx/mod.rs b/src/libstd/sys/sgx/mod.rs index a4968ff7d4f54..1d32eb2542434 100644 --- a/src/libstd/sys/sgx/mod.rs +++ b/src/libstd/sys/sgx/mod.rs @@ -137,8 +137,8 @@ pub extern "C" fn __rust_abort() { abort_internal(); } -pub fn hashmap_random_keys() -> (u64, u64) { - fn rdrand64() -> u64 { +pub mod rand { + pub fn rdrand64() -> u64 { unsafe { let mut ret: u64 = 0; for _ in 0..10 { @@ -149,7 +149,10 @@ pub fn hashmap_random_keys() -> (u64, u64) { rtabort!("Failed to obtain random data"); } } - (rdrand64(), rdrand64()) +} + +pub fn hashmap_random_keys() -> (u64, u64) { + (self::rand::rdrand64(), self::rand::rdrand64()) } pub use crate::sys_common::{AsInner, FromInner, IntoInner}; diff --git a/src/libstd/sys/sgx/thread.rs b/src/libstd/sys/sgx/thread.rs index 9b515eb82de35..5895f70436efa 100644 --- a/src/libstd/sys/sgx/thread.rs +++ b/src/libstd/sys/sgx/thread.rs @@ -73,8 +73,8 @@ impl Thread { // FIXME: could store this pointer in TLS somewhere } - pub fn sleep(_dur: Duration) { - rtabort!("can't sleep"); // FIXME + pub fn sleep(dur: Duration) { + usercalls::wait_timeout(0, dur, || true); } pub fn join(self) { diff --git a/src/libstd/sys/sgx/waitqueue.rs b/src/libstd/sys/sgx/waitqueue.rs index 6e50f161b3b41..070afa55f3019 100644 --- a/src/libstd/sys/sgx/waitqueue.rs +++ b/src/libstd/sys/sgx/waitqueue.rs @@ -1,16 +1,17 @@ +//! A simple queue implementation for synchronization primitives. +//! +//! This queue is used to implement condition variable and mutexes. +//! +//! Users of this API are expected to use the `WaitVariable` type. Since +//! that type is not `Sync`, it needs to be protected by e.g., a `SpinMutex` to +//! allow shared access. +//! +//! Since userspace may send spurious wake-ups, the wakeup event state is +//! recorded in the enclave. The wakeup event state is protected by a spinlock. +//! The queue and associated wait state are stored in a `WaitVariable`. use crate::num::NonZeroUsize; -/// A simple queue implementation for synchronization primitives. -/// -/// This queue is used to implement condition variable and mutexes. -/// -/// Users of this API are expected to use the `WaitVariable` type. Since -/// that type is not `Sync`, it needs to be protected by e.g., a `SpinMutex` to -/// allow shared access. -/// -/// Since userspace may send spurious wake-ups, the wakeup event state is -/// recorded in the enclave. The wakeup event state is protected by a spinlock. -/// The queue and associated wait state are stored in a `WaitVariable`. use crate::ops::{Deref, DerefMut}; +use crate::time::Duration; use super::abi::thread; use super::abi::usercalls; @@ -158,6 +159,34 @@ impl WaitQueue { } } + /// Adds the calling thread to the `WaitVariable`'s wait queue, then wait + /// until a wakeup event or timeout. If event was observed, returns true. + /// If not, it will remove the calling thread from the wait queue. + pub fn wait_timeout( + lock: &SpinMutex>, + timeout: Duration, + before_wait: F, + ) -> bool { + // very unsafe: check requirements of UnsafeList::push + unsafe { + let mut entry = UnsafeListEntry::new(SpinMutex::new(WaitEntry { + tcs: thread::current(), + wake: false, + })); + let entry_lock = lock.lock().queue.inner.push(&mut entry); + before_wait(); + usercalls::wait_timeout(EV_UNPARK, timeout, || entry_lock.lock().wake); + // acquire the wait queue's lock first to avoid deadlock. + let mut guard = lock.lock(); + let success = entry_lock.lock().wake; + if !success { + // nobody is waking us up, so remove our entry from the wait queue. + guard.queue.inner.remove(&mut entry); + } + success + } + } + /// Either find the next waiter on the wait queue, or return the mutex /// guard unchanged. /// @@ -325,6 +354,31 @@ mod unsafe_list { Some((*first.as_ptr()).value.as_ref().unwrap()) } } + + /// Removes an entry from the list. + /// + /// # Safety + /// + /// The caller must ensure that `entry` has been pushed onto `self` + /// prior to this call and has not moved since then. + pub unsafe fn remove(&mut self, entry: &mut UnsafeListEntry) { + rtassert!(!self.is_empty()); + // BEFORE: + // /----\ next ---> /-----\ next ---> /----\ + // ... |prev| |entry| |next| ... + // \----/ <--- prev \-----/ <--- prev \----/ + // + // AFTER: + // /----\ next ---> /----\ + // ... |prev| |next| ... + // \----/ <--- prev \----/ + let mut prev = entry.prev; + let mut next = entry.next; + prev.as_mut().next = next; + next.as_mut().prev = prev; + entry.next = NonNull::dangling(); + entry.prev = NonNull::dangling(); + } } #[cfg(test)] @@ -354,6 +408,51 @@ mod unsafe_list { } } + #[test] + fn push_remove() { + unsafe { + let mut node = UnsafeListEntry::new(1234); + let mut list = UnsafeList::new(); + assert_eq!(list.push(&mut node), &1234); + list.remove(&mut node); + assert_empty(&mut list); + } + } + + #[test] + fn push_remove_pop() { + unsafe { + let mut node1 = UnsafeListEntry::new(11); + let mut node2 = UnsafeListEntry::new(12); + let mut node3 = UnsafeListEntry::new(13); + let mut node4 = UnsafeListEntry::new(14); + let mut node5 = UnsafeListEntry::new(15); + let mut list = UnsafeList::new(); + assert_eq!(list.push(&mut node1), &11); + assert_eq!(list.push(&mut node2), &12); + assert_eq!(list.push(&mut node3), &13); + assert_eq!(list.push(&mut node4), &14); + assert_eq!(list.push(&mut node5), &15); + + list.remove(&mut node1); + assert_eq!(list.pop().unwrap(), &12); + list.remove(&mut node3); + assert_eq!(list.pop().unwrap(), &14); + list.remove(&mut node5); + assert_empty(&mut list); + + assert_eq!(list.push(&mut node1), &11); + assert_eq!(list.pop().unwrap(), &11); + assert_empty(&mut list); + + assert_eq!(list.push(&mut node3), &13); + assert_eq!(list.push(&mut node4), &14); + list.remove(&mut node3); + list.remove(&mut node4); + assert_empty(&mut list); + } + } + #[test] fn complex_pushes_pops() { unsafe { @@ -474,7 +573,7 @@ mod spin_mutex { use super::*; use crate::sync::Arc; use crate::thread; - use crate::time::{Duration, SystemTime}; + use crate::time::Duration; #[test] fn sleep() { @@ -485,11 +584,7 @@ mod spin_mutex { *mutex2.lock() = 1; }); - // "sleep" for 50ms - // FIXME: https://github.com/fortanix/rust-sgx/issues/31 - let start = SystemTime::now(); - let max = Duration::from_millis(50); - while start.elapsed().unwrap() < max {} + thread::sleep(Duration::from_millis(50)); assert_eq!(*guard, 0); drop(guard); diff --git a/src/libstd/sys/unsupported/alloc.rs b/src/libstd/sys/unsupported/alloc.rs new file mode 100644 index 0000000000000..8d5d0a2f5ccd1 --- /dev/null +++ b/src/libstd/sys/unsupported/alloc.rs @@ -0,0 +1,22 @@ +use crate::alloc::{GlobalAlloc, Layout, System}; + +#[stable(feature = "alloc_system_type", since = "1.28.0")] +unsafe impl GlobalAlloc for System { + #[inline] + unsafe fn alloc(&self, _layout: Layout) -> *mut u8 { + 0 as *mut u8 + } + + #[inline] + unsafe fn alloc_zeroed(&self, _layout: Layout) -> *mut u8 { + 0 as *mut u8 + } + + #[inline] + unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {} + + #[inline] + unsafe fn realloc(&self, _ptr: *mut u8, _layout: Layout, _new_size: usize) -> *mut u8 { + 0 as *mut u8 + } +} diff --git a/src/libstd/sys/unsupported/args.rs b/src/libstd/sys/unsupported/args.rs new file mode 100644 index 0000000000000..71d0c5fa13e18 --- /dev/null +++ b/src/libstd/sys/unsupported/args.rs @@ -0,0 +1,38 @@ +use crate::ffi::OsString; + +pub unsafe fn init(_argc: isize, _argv: *const *const u8) {} +pub unsafe fn cleanup() {} + +pub struct Args {} + +pub fn args() -> Args { + Args {} +} + +impl Args { + pub fn inner_debug(&self) -> &[OsString] { + &[] + } +} + +impl Iterator for Args { + type Item = OsString; + fn next(&mut self) -> Option { + None + } + fn size_hint(&self) -> (usize, Option) { + (0, Some(0)) + } +} + +impl ExactSizeIterator for Args { + fn len(&self) -> usize { + 0 + } +} + +impl DoubleEndedIterator for Args { + fn next_back(&mut self) -> Option { + None + } +} diff --git a/src/libstd/sys/wasm/cmath.rs b/src/libstd/sys/unsupported/cmath.rs similarity index 100% rename from src/libstd/sys/wasm/cmath.rs rename to src/libstd/sys/unsupported/cmath.rs diff --git a/src/libstd/sys/unsupported/common.rs b/src/libstd/sys/unsupported/common.rs new file mode 100644 index 0000000000000..80311d26819ad --- /dev/null +++ b/src/libstd/sys/unsupported/common.rs @@ -0,0 +1,48 @@ +use crate::io as std_io; + +pub mod memchr { + pub use core::slice::memchr::{memchr, memrchr}; +} + +pub use crate::sys_common::os_str_bytes as os_str; + +// This is not necessarily correct. May want to consider making it part of the +// spec definition? +use crate::os::raw::c_char; + +#[cfg(not(test))] +pub fn init() {} + +pub fn unsupported() -> std_io::Result { + Err(unsupported_err()) +} + +pub fn unsupported_err() -> std_io::Error { + std_io::Error::new(std_io::ErrorKind::Other, "operation not supported on this platform") +} + +pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind { + crate::io::ErrorKind::Other +} + +pub fn abort_internal() -> ! { + core::intrinsics::abort(); +} + +pub fn hashmap_random_keys() -> (u64, u64) { + (1, 2) +} + +// This enum is used as the storage for a bunch of types which can't actually +// exist. +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] +pub enum Void {} + +pub unsafe fn strlen(mut s: *const c_char) -> usize { + let mut n = 0; + while *s != 0 { + n += 1; + s = s.offset(1); + } + return n; +} diff --git a/src/libstd/sys/wasm/condvar.rs b/src/libstd/sys/unsupported/condvar.rs similarity index 84% rename from src/libstd/sys/wasm/condvar.rs rename to src/libstd/sys/unsupported/condvar.rs index 9fd781c728215..a578eee8ccce2 100644 --- a/src/libstd/sys/wasm/condvar.rs +++ b/src/libstd/sys/unsupported/condvar.rs @@ -18,11 +18,11 @@ impl Condvar { pub unsafe fn notify_all(&self) {} pub unsafe fn wait(&self, _mutex: &Mutex) { - panic!("can't block with web assembly") + panic!("condvar wait not supported") } pub unsafe fn wait_timeout(&self, _mutex: &Mutex, _dur: Duration) -> bool { - panic!("can't block with web assembly"); + panic!("condvar wait not supported"); } #[inline] diff --git a/src/libstd/sys/unsupported/env.rs b/src/libstd/sys/unsupported/env.rs new file mode 100644 index 0000000000000..d2efec506c56b --- /dev/null +++ b/src/libstd/sys/unsupported/env.rs @@ -0,0 +1,9 @@ +pub mod os { + pub const FAMILY: &str = ""; + pub const OS: &str = ""; + pub const DLL_PREFIX: &str = ""; + pub const DLL_SUFFIX: &str = ""; + pub const DLL_EXTENSION: &str = ""; + pub const EXE_SUFFIX: &str = ""; + pub const EXE_EXTENSION: &str = ""; +} diff --git a/src/libstd/sys/wasm/fs.rs b/src/libstd/sys/unsupported/fs.rs similarity index 100% rename from src/libstd/sys/wasm/fs.rs rename to src/libstd/sys/unsupported/fs.rs diff --git a/src/libstd/sys/wasm/io.rs b/src/libstd/sys/unsupported/io.rs similarity index 100% rename from src/libstd/sys/wasm/io.rs rename to src/libstd/sys/unsupported/io.rs diff --git a/src/libstd/sys/unsupported/mod.rs b/src/libstd/sys/unsupported/mod.rs new file mode 100644 index 0000000000000..87f655eecd54e --- /dev/null +++ b/src/libstd/sys/unsupported/mod.rs @@ -0,0 +1,24 @@ +pub mod alloc; +pub mod args; +pub mod cmath; +pub mod condvar; +pub mod env; +pub mod fs; +pub mod io; +pub mod mutex; +pub mod net; +pub mod os; +pub mod path; +pub mod pipe; +pub mod process; +pub mod rwlock; +pub mod stack_overflow; +pub mod stdio; +pub mod thread; +#[cfg(target_thread_local)] +pub mod thread_local_dtor; +pub mod thread_local_key; +pub mod time; + +mod common; +pub use common::*; diff --git a/src/libstd/sys/wasm/mutex.rs b/src/libstd/sys/unsupported/mutex.rs similarity index 82% rename from src/libstd/sys/wasm/mutex.rs rename to src/libstd/sys/unsupported/mutex.rs index 7aaf1b3a343b6..9ef8af52eb5c2 100644 --- a/src/libstd/sys/wasm/mutex.rs +++ b/src/libstd/sys/unsupported/mutex.rs @@ -5,9 +5,10 @@ pub struct Mutex { } unsafe impl Send for Mutex {} -unsafe impl Sync for Mutex {} // no threads on wasm +unsafe impl Sync for Mutex {} // no threads on this platform impl Mutex { + #[rustc_const_stable(feature = "const_sys_mutex_new", since = "1.0.0")] pub const fn new() -> Mutex { Mutex { locked: UnsafeCell::new(false) } } @@ -42,8 +43,8 @@ impl Mutex { pub unsafe fn destroy(&self) {} } -// All empty stubs because wasm has no threads yet, so lock acquisition always -// succeeds. +// All empty stubs because this platform does not yet support threads, so lock +// acquisition always succeeds. pub struct ReentrantMutex {} impl ReentrantMutex { diff --git a/src/libstd/sys/wasm/net.rs b/src/libstd/sys/unsupported/net.rs similarity index 100% rename from src/libstd/sys/wasm/net.rs rename to src/libstd/sys/unsupported/net.rs diff --git a/src/libstd/sys/wasm/os.rs b/src/libstd/sys/unsupported/os.rs similarity index 82% rename from src/libstd/sys/wasm/os.rs rename to src/libstd/sys/unsupported/os.rs index 91afdc8a5a0cc..0615780c24212 100644 --- a/src/libstd/sys/wasm/os.rs +++ b/src/libstd/sys/unsupported/os.rs @@ -1,10 +1,9 @@ +use super::{unsupported, Void}; use crate::error::Error as StdError; use crate::ffi::{OsStr, OsString}; use crate::fmt; use crate::io; use crate::path::{self, PathBuf}; -use crate::str; -use crate::sys::{unsupported, Void}; pub fn errno() -> i32 { 0 @@ -48,14 +47,14 @@ where impl fmt::Display for JoinPathsError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - "not supported on wasm yet".fmt(f) + "not supported on this platform yet".fmt(f) } } impl StdError for JoinPathsError { #[allow(deprecated)] fn description(&self) -> &str { - "not supported on wasm yet" + "not supported on this platform yet" } } @@ -73,7 +72,7 @@ impl Iterator for Env { } pub fn env() -> Env { - panic!("not supported on web assembly") + panic!("not supported on this platform") } pub fn getenv(_: &OsStr) -> io::Result> { @@ -81,15 +80,15 @@ pub fn getenv(_: &OsStr) -> io::Result> { } pub fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> { - Err(io::Error::new(io::ErrorKind::Other, "cannot set env vars on wasm32-unknown-unknown")) + Err(io::Error::new(io::ErrorKind::Other, "cannot set env vars on this platform")) } pub fn unsetenv(_: &OsStr) -> io::Result<()> { - Err(io::Error::new(io::ErrorKind::Other, "cannot unset env vars on wasm32-unknown-unknown")) + Err(io::Error::new(io::ErrorKind::Other, "cannot unset env vars on this platform")) } pub fn temp_dir() -> PathBuf { - panic!("no filesystem on wasm") + panic!("no filesystem on this platform") } pub fn home_dir() -> Option { @@ -97,11 +96,9 @@ pub fn home_dir() -> Option { } pub fn exit(_code: i32) -> ! { - unsafe { - crate::arch::wasm32::unreachable(); - } + crate::intrinsics::abort() } pub fn getpid() -> u32 { - panic!("no pids on wasm") + panic!("no pids on this platform") } diff --git a/src/libstd/sys/wasm/path.rs b/src/libstd/sys/unsupported/path.rs similarity index 100% rename from src/libstd/sys/wasm/path.rs rename to src/libstd/sys/unsupported/path.rs diff --git a/src/libstd/sys/wasm/pipe.rs b/src/libstd/sys/unsupported/pipe.rs similarity index 100% rename from src/libstd/sys/wasm/pipe.rs rename to src/libstd/sys/unsupported/pipe.rs diff --git a/src/libstd/sys/wasm/process.rs b/src/libstd/sys/unsupported/process.rs similarity index 100% rename from src/libstd/sys/wasm/process.rs rename to src/libstd/sys/unsupported/process.rs diff --git a/src/libstd/sys/wasm/rwlock.rs b/src/libstd/sys/unsupported/rwlock.rs similarity index 95% rename from src/libstd/sys/wasm/rwlock.rs rename to src/libstd/sys/unsupported/rwlock.rs index a59944482e9e9..d37f34ac9352d 100644 --- a/src/libstd/sys/wasm/rwlock.rs +++ b/src/libstd/sys/unsupported/rwlock.rs @@ -5,7 +5,7 @@ pub struct RWLock { } unsafe impl Send for RWLock {} -unsafe impl Sync for RWLock {} // no threads on wasm +unsafe impl Sync for RWLock {} // no threads on this platform impl RWLock { pub const fn new() -> RWLock { diff --git a/src/libstd/sys/wasm/stack_overflow.rs b/src/libstd/sys/unsupported/stack_overflow.rs similarity index 100% rename from src/libstd/sys/wasm/stack_overflow.rs rename to src/libstd/sys/unsupported/stack_overflow.rs diff --git a/src/libstd/sys/wasm/stdio.rs b/src/libstd/sys/unsupported/stdio.rs similarity index 100% rename from src/libstd/sys/wasm/stdio.rs rename to src/libstd/sys/unsupported/stdio.rs diff --git a/src/libstd/sys/unsupported/thread.rs b/src/libstd/sys/unsupported/thread.rs new file mode 100644 index 0000000000000..20ae309db30d7 --- /dev/null +++ b/src/libstd/sys/unsupported/thread.rs @@ -0,0 +1,41 @@ +use super::{unsupported, Void}; +use crate::ffi::CStr; +use crate::io; +use crate::time::Duration; + +pub struct Thread(Void); + +pub const DEFAULT_MIN_STACK_SIZE: usize = 4096; + +impl Thread { + // unsafe: see thread::Builder::spawn_unchecked for safety requirements + pub unsafe fn new(_stack: usize, _p: Box) -> io::Result { + unsupported() + } + + pub fn yield_now() { + // do nothing + } + + pub fn set_name(_name: &CStr) { + // nope + } + + pub fn sleep(_dur: Duration) { + panic!("can't sleep"); + } + + pub fn join(self) { + match self.0 {} + } +} + +pub mod guard { + pub type Guard = !; + pub unsafe fn current() -> Option { + None + } + pub unsafe fn init() -> Option { + None + } +} diff --git a/src/libstd/sys/wasm/thread_local_dtor.rs b/src/libstd/sys/unsupported/thread_local_dtor.rs similarity index 100% rename from src/libstd/sys/wasm/thread_local_dtor.rs rename to src/libstd/sys/unsupported/thread_local_dtor.rs diff --git a/src/libstd/sys/wasm/thread_local_key.rs b/src/libstd/sys/unsupported/thread_local_key.rs similarity index 55% rename from src/libstd/sys/wasm/thread_local_key.rs rename to src/libstd/sys/unsupported/thread_local_key.rs index f8be9863ed56f..c31b61cbf56d3 100644 --- a/src/libstd/sys/wasm/thread_local_key.rs +++ b/src/libstd/sys/unsupported/thread_local_key.rs @@ -2,25 +2,25 @@ pub type Key = usize; #[inline] pub unsafe fn create(_dtor: Option) -> Key { - panic!("should not be used on the wasm target"); + panic!("should not be used on this target"); } #[inline] pub unsafe fn set(_key: Key, _value: *mut u8) { - panic!("should not be used on the wasm target"); + panic!("should not be used on this target"); } #[inline] pub unsafe fn get(_key: Key) -> *mut u8 { - panic!("should not be used on the wasm target"); + panic!("should not be used on this target"); } #[inline] pub unsafe fn destroy(_key: Key) { - panic!("should not be used on the wasm target"); + panic!("should not be used on this target"); } #[inline] pub fn requires_synchronized_create() -> bool { - panic!("should not be used on the wasm target"); + panic!("should not be used on this target"); } diff --git a/src/libstd/sys/wasm/time.rs b/src/libstd/sys/unsupported/time.rs similarity index 91% rename from src/libstd/sys/wasm/time.rs rename to src/libstd/sys/unsupported/time.rs index d9edc7fdc4451..8aaf1777f2427 100644 --- a/src/libstd/sys/wasm/time.rs +++ b/src/libstd/sys/unsupported/time.rs @@ -10,7 +10,7 @@ pub const UNIX_EPOCH: SystemTime = SystemTime(Duration::from_secs(0)); impl Instant { pub fn now() -> Instant { - panic!("time not implemented on wasm32-unknown-unknown") + panic!("time not implemented on this platform") } pub const fn zero() -> Instant { @@ -36,7 +36,7 @@ impl Instant { impl SystemTime { pub fn now() -> SystemTime { - panic!("time not implemented on wasm32-unknown-unknown") + panic!("time not implemented on this platform") } pub fn sub_time(&self, other: &SystemTime) -> Result { diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs index 85f5282034ff1..2704ff484f991 100644 --- a/src/libstd/sys/wasi/mod.rs +++ b/src/libstd/sys/wasi/mod.rs @@ -16,21 +16,18 @@ use crate::io as std_io; use crate::mem; -use crate::os::raw::c_char; pub mod alloc; pub mod args; -#[path = "../wasm/cmath.rs"] +#[path = "../unsupported/cmath.rs"] pub mod cmath; -#[path = "../wasm/condvar.rs"] +#[path = "../unsupported/condvar.rs"] pub mod condvar; pub mod env; pub mod fd; pub mod fs; pub mod io; -#[path = "../wasm/memchr.rs"] -pub mod memchr; -#[path = "../wasm/mutex.rs"] +#[path = "../unsupported/mutex.rs"] pub mod mutex; pub mod net; pub mod os; @@ -39,28 +36,22 @@ pub mod ext; pub mod path; pub mod pipe; pub mod process; -#[path = "../wasm/rwlock.rs"] +#[path = "../unsupported/rwlock.rs"] pub mod rwlock; -#[path = "../wasm/stack_overflow.rs"] +#[path = "../unsupported/stack_overflow.rs"] pub mod stack_overflow; pub mod stdio; pub mod thread; -#[path = "../wasm/thread_local_dtor.rs"] +#[path = "../unsupported/thread_local_dtor.rs"] pub mod thread_local_dtor; -#[path = "../wasm/thread_local_key.rs"] +#[path = "../unsupported/thread_local_key.rs"] pub mod thread_local_key; pub mod time; -#[cfg(not(test))] -pub fn init() {} - -pub fn unsupported() -> std_io::Result { - Err(unsupported_err()) -} - -pub fn unsupported_err() -> std_io::Error { - std_io::Error::new(std_io::ErrorKind::Other, "operation not supported on wasm yet") -} +#[path = "../unsupported/common.rs"] +#[allow(unused)] +mod common; +pub use common::*; pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind { use std_io::ErrorKind::*; @@ -86,20 +77,6 @@ pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind { } } -// This enum is used as the storage for a bunch of types which can't actually -// exist. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] -pub enum Void {} - -pub unsafe fn strlen(mut s: *const c_char) -> usize { - let mut n = 0; - while *s != 0 { - n += 1; - s = s.offset(1); - } - return n; -} - pub fn abort_internal() -> ! { unsafe { libc::abort() } } diff --git a/src/libstd/sys/wasm/memchr.rs b/src/libstd/sys/wasm/memchr.rs deleted file mode 100644 index 9967482197eb3..0000000000000 --- a/src/libstd/sys/wasm/memchr.rs +++ /dev/null @@ -1 +0,0 @@ -pub use core::slice::memchr::{memchr, memrchr}; diff --git a/src/libstd/sys/wasm/mod.rs b/src/libstd/sys/wasm/mod.rs index 6939596e52d78..3de5890404357 100644 --- a/src/libstd/sys/wasm/mod.rs +++ b/src/libstd/sys/wasm/mod.rs @@ -14,25 +14,35 @@ //! compiling for wasm. That way it's a compile time error for something that's //! guaranteed to be a runtime error! -use crate::os::raw::c_char; - pub mod alloc; pub mod args; +#[path = "../unsupported/cmath.rs"] pub mod cmath; pub mod env; +#[path = "../unsupported/fs.rs"] pub mod fs; +#[path = "../unsupported/io.rs"] pub mod io; -pub mod memchr; +#[path = "../unsupported/net.rs"] pub mod net; +#[path = "../unsupported/os.rs"] pub mod os; +#[path = "../unsupported/path.rs"] pub mod path; +#[path = "../unsupported/pipe.rs"] pub mod pipe; +#[path = "../unsupported/process.rs"] pub mod process; +#[path = "../unsupported/stack_overflow.rs"] pub mod stack_overflow; +#[path = "../unsupported/stdio.rs"] pub mod stdio; pub mod thread; +#[path = "../unsupported/thread_local_dtor.rs"] pub mod thread_local_dtor; +#[path = "../unsupported/thread_local_key.rs"] pub mod thread_local_key; +#[path = "../unsupported/time.rs"] pub mod time; pub use crate::sys_common::os_str_bytes as os_str; @@ -46,50 +56,15 @@ cfg_if::cfg_if! { #[path = "rwlock_atomics.rs"] pub mod rwlock; } else { + #[path = "../unsupported/condvar.rs"] pub mod condvar; + #[path = "../unsupported/mutex.rs"] pub mod mutex; + #[path = "../unsupported/rwlock.rs"] pub mod rwlock; } } -#[cfg(not(test))] -pub fn init() {} - -pub fn unsupported() -> crate::io::Result { - Err(unsupported_err()) -} - -pub fn unsupported_err() -> crate::io::Error { - crate::io::Error::new(crate::io::ErrorKind::Other, "operation not supported on wasm yet") -} - -pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind { - crate::io::ErrorKind::Other -} - -// This enum is used as the storage for a bunch of types which can't actually -// exist. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] -pub enum Void {} - -pub unsafe fn strlen(mut s: *const c_char) -> usize { - let mut n = 0; - while *s != 0 { - n += 1; - s = s.offset(1); - } - return n; -} - -pub fn abort_internal() -> ! { - unsafe { crate::arch::wasm32::unreachable() } -} - -// We don't have randomness yet, but I totally used a random number generator to -// generate these numbers. -// -// More seriously though this is just for DOS protection in hash maps. It's ok -// if we don't do that on wasm just yet. -pub fn hashmap_random_keys() -> (u64, u64) { - (1, 2) -} +#[path = "../unsupported/common.rs"] +mod common; +pub use common::*; diff --git a/src/libstd/sys_common/mod.rs b/src/libstd/sys_common/mod.rs index e57bb267cbd0f..840f9093e00f1 100644 --- a/src/libstd/sys_common/mod.rs +++ b/src/libstd/sys_common/mod.rs @@ -51,13 +51,9 @@ pub mod condvar; pub mod fs; pub mod io; pub mod mutex; -#[cfg(any(doc, // see `mod os`, docs are generated for multiple platforms - unix, - target_os = "redox", - target_os = "cloudabi", - target_os = "hermit", - target_arch = "wasm32", - all(target_vendor = "fortanix", target_env = "sgx")))] +// `doc` is required because `sys/mod.rs` imports `unix/ext/mod.rs` on Windows +// when generating documentation. +#[cfg(any(doc, not(windows)))] pub mod os_str_bytes; pub mod poison; pub mod process; @@ -74,6 +70,7 @@ cfg_if::cfg_if! { if #[cfg(any(target_os = "cloudabi", target_os = "l4re", target_os = "hermit", + feature = "restricted-std", all(target_arch = "wasm32", not(target_os = "emscripten")), all(target_vendor = "fortanix", target_env = "sgx")))] { pub use crate::sys::net; diff --git a/src/libstd/sys_common/mutex.rs b/src/libstd/sys_common/mutex.rs index 899fc6a723530..e66d8994147e1 100644 --- a/src/libstd/sys_common/mutex.rs +++ b/src/libstd/sys_common/mutex.rs @@ -17,6 +17,7 @@ impl Mutex { /// Also, until `init` is called, behavior is undefined if this /// mutex is ever used reentrantly, i.e., `raw_lock` or `try_lock` /// are called by the thread currently holding the lock. + #[rustc_const_stable(feature = "const_sys_mutex_new", since = "1.0.0")] pub const fn new() -> Mutex { Mutex(imp::Mutex::new()) } diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index d354a9b1842c2..202867258f1e4 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -1741,7 +1741,6 @@ mod tests { } #[test] - #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn test_park_timeout_unpark_not_called() { for _ in 0..10 { thread::park_timeout(Duration::from_millis(10)); @@ -1749,7 +1748,6 @@ mod tests { } #[test] - #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn test_park_timeout_unpark_called_other_thread() { for _ in 0..10 { let th = thread::current(); @@ -1764,7 +1762,6 @@ mod tests { } #[test] - #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn sleep_ms_smoke() { thread::sleep(Duration::from_millis(2)); } diff --git a/src/libtest/Cargo.toml b/src/libtest/Cargo.toml index 1667334871d5e..a4748c5a46628 100644 --- a/src/libtest/Cargo.toml +++ b/src/libtest/Cargo.toml @@ -10,6 +10,7 @@ path = "lib.rs" crate-type = ["dylib", "rlib"] [dependencies] +cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] } getopts = { version = "0.2.21", features = ['rustc-dep-of-std'] } term = { path = "../libterm" } std = { path = "../libstd" } diff --git a/src/libtest/helpers/concurrency.rs b/src/libtest/helpers/concurrency.rs index e8f3820558a6d..2fe87247e3acf 100644 --- a/src/libtest/helpers/concurrency.rs +++ b/src/libtest/helpers/concurrency.rs @@ -14,61 +14,36 @@ pub fn get_concurrency() -> usize { } Err(..) => num_cpus(), }; +} - #[cfg(windows)] - #[allow(nonstandard_style)] - fn num_cpus() -> usize { - #[repr(C)] - struct SYSTEM_INFO { - wProcessorArchitecture: u16, - wReserved: u16, - dwPageSize: u32, - lpMinimumApplicationAddress: *mut u8, - lpMaximumApplicationAddress: *mut u8, - dwActiveProcessorMask: *mut u8, - dwNumberOfProcessors: u32, - dwProcessorType: u32, - dwAllocationGranularity: u32, - wProcessorLevel: u16, - wProcessorRevision: u16, - } - extern "system" { - fn GetSystemInfo(info: *mut SYSTEM_INFO) -> i32; - } - unsafe { - let mut sysinfo = std::mem::zeroed(); - GetSystemInfo(&mut sysinfo); - sysinfo.dwNumberOfProcessors as usize +cfg_if::cfg_if! { + if #[cfg(windows)] { + #[allow(nonstandard_style)] + fn num_cpus() -> usize { + #[repr(C)] + struct SYSTEM_INFO { + wProcessorArchitecture: u16, + wReserved: u16, + dwPageSize: u32, + lpMinimumApplicationAddress: *mut u8, + lpMaximumApplicationAddress: *mut u8, + dwActiveProcessorMask: *mut u8, + dwNumberOfProcessors: u32, + dwProcessorType: u32, + dwAllocationGranularity: u32, + wProcessorLevel: u16, + wProcessorRevision: u16, + } + extern "system" { + fn GetSystemInfo(info: *mut SYSTEM_INFO) -> i32; + } + unsafe { + let mut sysinfo = std::mem::zeroed(); + GetSystemInfo(&mut sysinfo); + sysinfo.dwNumberOfProcessors as usize + } } - } - - #[cfg(target_os = "vxworks")] - fn num_cpus() -> usize { - // FIXME: Implement num_cpus on vxWorks - 1 - } - - #[cfg(target_os = "redox")] - fn num_cpus() -> usize { - // FIXME: Implement num_cpus on Redox - 1 - } - - #[cfg(target_os = "hermit")] - fn num_cpus() -> usize { - // FIXME: Implement num_cpus on HermitCore - 1 - } - - #[cfg(any( - all(target_arch = "wasm32", not(target_os = "emscripten")), - all(target_vendor = "fortanix", target_env = "sgx") - ))] - fn num_cpus() -> usize { - 1 - } - - #[cfg(any( + } else if #[cfg(any( target_os = "android", target_os = "cloudabi", target_os = "emscripten", @@ -78,23 +53,46 @@ pub fn get_concurrency() -> usize { target_os = "macos", target_os = "solaris", target_os = "illumos", - ))] - fn num_cpus() -> usize { - unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize } - } - - #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd"))] - fn num_cpus() -> usize { - use std::ptr; + ))] { + fn num_cpus() -> usize { + unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize } + } + } else if #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd"))] { + fn num_cpus() -> usize { + use std::ptr; - let mut cpus: libc::c_uint = 0; - let mut cpus_size = std::mem::size_of_val(&cpus); + let mut cpus: libc::c_uint = 0; + let mut cpus_size = std::mem::size_of_val(&cpus); - unsafe { - cpus = libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as libc::c_uint; + unsafe { + cpus = libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as libc::c_uint; + } + if cpus < 1 { + let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0]; + unsafe { + libc::sysctl( + mib.as_mut_ptr(), + 2, + &mut cpus as *mut _ as *mut _, + &mut cpus_size as *mut _ as *mut _, + ptr::null_mut(), + 0, + ); + } + if cpus < 1 { + cpus = 1; + } + } + cpus as usize } - if cpus < 1 { + } else if #[cfg(target_os = "openbsd")] { + fn num_cpus() -> usize { + use std::ptr; + + let mut cpus: libc::c_uint = 0; + let mut cpus_size = std::mem::size_of_val(&cpus); let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0]; + unsafe { libc::sysctl( mib.as_mut_ptr(), @@ -108,43 +106,12 @@ pub fn get_concurrency() -> usize { if cpus < 1 { cpus = 1; } + cpus as usize } - cpus as usize - } - - #[cfg(target_os = "openbsd")] - fn num_cpus() -> usize { - use std::ptr; - - let mut cpus: libc::c_uint = 0; - let mut cpus_size = std::mem::size_of_val(&cpus); - let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0]; - - unsafe { - libc::sysctl( - mib.as_mut_ptr(), - 2, - &mut cpus as *mut _ as *mut _, - &mut cpus_size as *mut _ as *mut _, - ptr::null_mut(), - 0, - ); - } - if cpus < 1 { - cpus = 1; + } else { + // FIXME: implement on vxWorks, Redox, HermitCore, Haiku, l4re + fn num_cpus() -> usize { + 1 } - cpus as usize - } - - #[cfg(target_os = "haiku")] - fn num_cpus() -> usize { - // FIXME: implement - 1 - } - - #[cfg(target_os = "l4re")] - fn num_cpus() -> usize { - // FIXME: implement - 1 } } diff --git a/src/libtest/helpers/isatty.rs b/src/libtest/helpers/isatty.rs index 831094f7545c1..874ecc3764572 100644 --- a/src/libtest/helpers/isatty.rs +++ b/src/libtest/helpers/isatty.rs @@ -1,34 +1,32 @@ //! Helper module which provides a function to test //! if stdout is a tty. -#[cfg(any( - target_os = "cloudabi", - target_os = "hermit", - all(target_arch = "wasm32", not(target_os = "emscripten")), - all(target_vendor = "fortanix", target_env = "sgx") -))] -pub fn stdout_isatty() -> bool { - // FIXME: Implement isatty on SGX - false -} -#[cfg(unix)] -pub fn stdout_isatty() -> bool { - unsafe { libc::isatty(libc::STDOUT_FILENO) != 0 } -} -#[cfg(windows)] -pub fn stdout_isatty() -> bool { - type DWORD = u32; - type BOOL = i32; - type HANDLE = *mut u8; - type LPDWORD = *mut u32; - const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD; - extern "system" { - fn GetStdHandle(which: DWORD) -> HANDLE; - fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: LPDWORD) -> BOOL; - } - unsafe { - let handle = GetStdHandle(STD_OUTPUT_HANDLE); - let mut out = 0; - GetConsoleMode(handle, &mut out) != 0 +cfg_if::cfg_if! { + if #[cfg(unix)] { + pub fn stdout_isatty() -> bool { + unsafe { libc::isatty(libc::STDOUT_FILENO) != 0 } + } + } else if #[cfg(windows)] { + pub fn stdout_isatty() -> bool { + type DWORD = u32; + type BOOL = i32; + type HANDLE = *mut u8; + type LPDWORD = *mut u32; + const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD; + extern "system" { + fn GetStdHandle(which: DWORD) -> HANDLE; + fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: LPDWORD) -> BOOL; + } + unsafe { + let handle = GetStdHandle(STD_OUTPUT_HANDLE); + let mut out = 0; + GetConsoleMode(handle, &mut out) != 0 + } + } + } else { + // FIXME: Implement isatty on SGX + pub fn stdout_isatty() -> bool { + false + } } } diff --git a/src/libunwind/lib.rs b/src/libunwind/lib.rs index cc025da1af555..c4d10ab177be9 100644 --- a/src/libunwind/lib.rs +++ b/src/libunwind/lib.rs @@ -9,12 +9,31 @@ cfg_if::cfg_if! { if #[cfg(target_env = "msvc")] { - // no extra unwinder support needed - } else if #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] { - // no unwinder on the system! - } else { + // Windows MSVC no extra unwinder support needed + } else if #[cfg(any( + target_os = "l4re", + target_os = "none", + ))] { + // These "unix" family members do not have unwinder. + // Note this also matches x86_64-linux-kernel. + } else if #[cfg(any( + unix, + windows, + target_os = "cloudabi", + all(target_vendor = "fortanix", target_env = "sgx"), + ))] { mod libunwind; pub use libunwind::*; + } else { + // no unwinder on the system! + // - wasm32 (not emscripten, which is "unix" family) + // - os=none ("bare metal" targets) + // - os=hermit + // - os=uefi + // - os=cuda + // - nvptx64-nvidia-cuda + // - mipsel-sony-psp + // - Any new targets not listed above. } } diff --git a/src/test/run-make-fulldeps/compiler-rt-works-on-mingw/Makefile b/src/test/run-make-fulldeps/compiler-rt-works-on-mingw/Makefile index d7d078e56b2e7..0cf5d1855212d 100644 --- a/src/test/run-make-fulldeps/compiler-rt-works-on-mingw/Makefile +++ b/src/test/run-make-fulldeps/compiler-rt-works-on-mingw/Makefile @@ -1,6 +1,6 @@ -include ../tools.mk -# only-mingw +# only-windows-gnu all: $(CXX) foo.cpp -c -o $(TMPDIR)/foo.o diff --git a/src/test/run-make-fulldeps/include_bytes_deps/Makefile b/src/test/run-make-fulldeps/include_bytes_deps/Makefile index ce79cec67dc37..f91af88efe1b7 100644 --- a/src/test/run-make-fulldeps/include_bytes_deps/Makefile +++ b/src/test/run-make-fulldeps/include_bytes_deps/Makefile @@ -1,10 +1,6 @@ -include ../tools.mk -# ignore-windows # ignore-freebsd -# FIXME: on windows `rustc --dep-info` produces Makefile dependency with -# windows native paths (e.g. `c:\path\to\libfoo.a`) -# but msys make seems to fail to recognize such paths, so test fails. all: $(RUSTC) --emit dep-info main.rs diff --git a/src/test/run-make-fulldeps/intrinsic-unreachable/Makefile b/src/test/run-make-fulldeps/intrinsic-unreachable/Makefile index 483091ad4ee8b..2037728568e24 100644 --- a/src/test/run-make-fulldeps/intrinsic-unreachable/Makefile +++ b/src/test/run-make-fulldeps/intrinsic-unreachable/Makefile @@ -1,6 +1,6 @@ -include ../tools.mk -# ignore-windows +# ignore-windows-msvc # # Because of Windows exception handling, the code is not necessarily any shorter. # https://github.com/llvm-mirror/llvm/commit/64b2297786f7fd6f5fa24cdd4db0298fbf211466 diff --git a/src/test/run-make-fulldeps/issue-51671/Makefile b/src/test/run-make-fulldeps/issue-51671/Makefile index 3027ee578c79f..ba3d3b7100745 100644 --- a/src/test/run-make-fulldeps/issue-51671/Makefile +++ b/src/test/run-make-fulldeps/issue-51671/Makefile @@ -1,6 +1,6 @@ -include ../tools.mk -# ignore-windows +# ignore-windows-msvc all: $(RUSTC) --emit=obj app.rs diff --git a/src/test/run-make-fulldeps/libs-search-path/Makefile b/src/test/run-make-fulldeps/libs-search-path/Makefile deleted file mode 100644 index f31036ffa1959..0000000000000 --- a/src/test/run-make-fulldeps/libs-search-path/Makefile +++ /dev/null @@ -1,10 +0,0 @@ --include ../tools.mk - -# only-mingw - -all: empty.rs - cp -r $(shell cygpath -u $(shell $(RUSTC) --print sysroot)) $(TMPDIR)/sysroot - $(RUSTC) --target $(TARGET) --sysroot $(TMPDIR)/sysroot -L$(TMPDIR)/obj -Z print-link-args empty.rs | $(CGREP) 'lib\\crt2.o' - mkdir -p $(TMPDIR)/obj - mv $(TMPDIR)/sysroot/lib/rustlib/$(TARGET)/lib/crt2.o $(TMPDIR)/obj/crt2.o - $(RUSTC) --target $(TARGET) --sysroot $(TMPDIR)/sysroot -L$(TMPDIR)/obj -Z print-link-args empty.rs | $(CGREP) 'obj\\crt2.o' diff --git a/src/test/run-make-fulldeps/libs-search-path/empty.rs b/src/test/run-make-fulldeps/libs-search-path/empty.rs deleted file mode 100644 index f328e4d9d04c3..0000000000000 --- a/src/test/run-make-fulldeps/libs-search-path/empty.rs +++ /dev/null @@ -1 +0,0 @@ -fn main() {} diff --git a/src/test/run-make-fulldeps/redundant-libs/Makefile b/src/test/run-make-fulldeps/redundant-libs/Makefile index 9486e07d21bf7..8468d102bec83 100644 --- a/src/test/run-make-fulldeps/redundant-libs/Makefile +++ b/src/test/run-make-fulldeps/redundant-libs/Makefile @@ -1,8 +1,6 @@ -include ../tools.mk -ifdef IS_WINDOWS -all: -else +# ignore-windows-msvc # rustc will remove one of the two redundant references to foo below. Depending # on which one gets removed, we'll get a linker error on SOME platforms (like @@ -23,5 +21,3 @@ RUSTC_FLAGS = \ all: $(call DYLIB,foo) $(call STATICLIB,bar) $(call STATICLIB,baz) $(RUSTC) $(RUSTC_FLAGS) main.rs $(call RUN,main) - -endif diff --git a/src/test/run-make-fulldeps/symbol-visibility/Makefile b/src/test/run-make-fulldeps/symbol-visibility/Makefile index 7901866015bf2..ed88a88a0bb8c 100644 --- a/src/test/run-make-fulldeps/symbol-visibility/Makefile +++ b/src/test/run-make-fulldeps/symbol-visibility/Makefile @@ -1,9 +1,6 @@ include ../tools.mk -# ignore-windows -# -# On MINGW the --version-script, --dynamic-list, and --retain-symbol args don't -# seem to work reliably. +# ignore-windows-msvc NM=nm -D CDYLIB_NAME=liba_cdylib.so @@ -19,6 +16,14 @@ EXE_NAME=an_executable COMBINED_CDYLIB_NAME=libcombined_rlib_dylib.dylib endif +ifdef IS_WINDOWS +NM=nm -g +CDYLIB_NAME=liba_cdylib.dll.a +RDYLIB_NAME=liba_rust_dylib.dll.a +EXE_NAME=an_executable.exe +COMBINED_CDYLIB_NAME=libcombined_rlib_dylib.dll.a +endif + # `grep` regex for symbols produced by either `legacy` or `v0` mangling RE_ANY_RUST_SYMBOL="_ZN.*h.*E\|_R[a-zA-Z0-9_]+" @@ -30,38 +35,38 @@ all: $(RUSTC) -Zshare-generics=no a_cdylib.rs --crate-name combined_rlib_dylib --crate-type=rlib,cdylib # Check that a cdylib exports its public #[no_mangle] functions - [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -c public_c_function_from_cdylib)" -eq "1" ] + [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v _imp__ | grep -c public_c_function_from_cdylib)" -eq "1" ] # Check that a cdylib exports the public #[no_mangle] functions of dependencies - [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -c public_c_function_from_rlib)" -eq "1" ] + [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v _imp__ | grep -c public_c_function_from_rlib)" -eq "1" ] # Check that a cdylib DOES NOT export any public Rust functions - [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -c $(RE_ANY_RUST_SYMBOL))" -eq "0" ] + [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v _imp__ | grep -c $(RE_ANY_RUST_SYMBOL))" -eq "0" ] # Check that a Rust dylib exports its monomorphic functions - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_c_function_from_rust_dylib)" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_rust_function_from_rust_dylib)" -eq "1" ] + [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v _imp__ | grep -c public_c_function_from_rust_dylib)" -eq "1" ] + [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v _imp__ | grep -c public_rust_function_from_rust_dylib)" -eq "1" ] # Check that a Rust dylib does not export generics if -Zshare-generics=no - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_generic_function_from_rust_dylib)" -eq "0" ] + [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v _imp__ | grep -c public_generic_function_from_rust_dylib)" -eq "0" ] # Check that a Rust dylib exports the monomorphic functions from its dependencies - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_c_function_from_rlib)" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_rust_function_from_rlib)" -eq "1" ] + [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v _imp__ | grep -c public_c_function_from_rlib)" -eq "1" ] + [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v _imp__ | grep -c public_rust_function_from_rlib)" -eq "1" ] # Check that a Rust dylib does not export generics if -Zshare-generics=no - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_generic_function_from_rlib)" -eq "0" ] + [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v _imp__ | grep -c public_generic_function_from_rlib)" -eq "0" ] # Check that an executable does not export any dynamic symbols - [ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -c public_c_function_from_rlib)" -eq "0" ] - [ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -c public_rust_function_from_exe)" -eq "0" ] + [ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -v _imp__ | grep -c public_c_function_from_rlib)" -eq "0" ] + [ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -v _imp__ | grep -c public_rust_function_from_exe)" -eq "0" ] # Check the combined case, where we generate a cdylib and an rlib in the same # compilation session: # Check that a cdylib exports its public #[no_mangle] functions - [ "$$($(NM) $(TMPDIR)/$(COMBINED_CDYLIB_NAME) | grep -c public_c_function_from_cdylib)" -eq "1" ] + [ "$$($(NM) $(TMPDIR)/$(COMBINED_CDYLIB_NAME) | grep -v _imp__ | grep -c public_c_function_from_cdylib)" -eq "1" ] # Check that a cdylib exports the public #[no_mangle] functions of dependencies - [ "$$($(NM) $(TMPDIR)/$(COMBINED_CDYLIB_NAME) | grep -c public_c_function_from_rlib)" -eq "1" ] + [ "$$($(NM) $(TMPDIR)/$(COMBINED_CDYLIB_NAME) | grep -v _imp__ | grep -c public_c_function_from_rlib)" -eq "1" ] # Check that a cdylib DOES NOT export any public Rust functions - [ "$$($(NM) $(TMPDIR)/$(COMBINED_CDYLIB_NAME) | grep -c $(RE_ANY_RUST_SYMBOL))" -eq "0" ] + [ "$$($(NM) $(TMPDIR)/$(COMBINED_CDYLIB_NAME) | grep -v _imp__ | grep -c $(RE_ANY_RUST_SYMBOL))" -eq "0" ] $(RUSTC) -Zshare-generics=yes an_rlib.rs @@ -70,22 +75,22 @@ all: $(RUSTC) -Zshare-generics=yes an_executable.rs # Check that a cdylib exports its public #[no_mangle] functions - [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -c public_c_function_from_cdylib)" -eq "1" ] + [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v _imp__ | grep -c public_c_function_from_cdylib)" -eq "1" ] # Check that a cdylib exports the public #[no_mangle] functions of dependencies - [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -c public_c_function_from_rlib)" -eq "1" ] + [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v _imp__ | grep -c public_c_function_from_rlib)" -eq "1" ] # Check that a cdylib DOES NOT export any public Rust functions - [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -c $(RE_ANY_RUST_SYMBOL))" -eq "0" ] + [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v _imp__ | grep -c $(RE_ANY_RUST_SYMBOL))" -eq "0" ] # Check that a Rust dylib exports its monomorphic functions, including generics this time - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_c_function_from_rust_dylib)" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_rust_function_from_rust_dylib)" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_generic_function_from_rust_dylib)" -eq "1" ] + [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v _imp__ | grep -c public_c_function_from_rust_dylib)" -eq "1" ] + [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v _imp__ | grep -c public_rust_function_from_rust_dylib)" -eq "1" ] + [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v _imp__ | grep -c public_generic_function_from_rust_dylib)" -eq "1" ] # Check that a Rust dylib exports the monomorphic functions from its dependencies - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_c_function_from_rlib)" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_rust_function_from_rlib)" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_generic_function_from_rlib)" -eq "1" ] + [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v _imp__ | grep -c public_c_function_from_rlib)" -eq "1" ] + [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v _imp__ | grep -c public_rust_function_from_rlib)" -eq "1" ] + [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v _imp__ | grep -c public_generic_function_from_rlib)" -eq "1" ] # Check that an executable does not export any dynamic symbols - [ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -c public_c_function_from_rlib)" -eq "0" ] - [ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -c public_rust_function_from_exe)" -eq "0" ] + [ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -v _imp__ | grep -c public_c_function_from_rlib)" -eq "0" ] + [ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -v _imp__ | grep -c public_rust_function_from_exe)" -eq "0" ] diff --git a/src/test/run-make-fulldeps/tools.mk b/src/test/run-make-fulldeps/tools.mk index 04bf78ed2105b..1effa46e101eb 100644 --- a/src/test/run-make-fulldeps/tools.mk +++ b/src/test/run-make-fulldeps/tools.mk @@ -150,7 +150,7 @@ ifdef IS_MSVC $(CC) $< -link -dll -out:`cygpath -w $@` else %.dll: lib%.o - $(CC) -o $@ $< -shared + $(CC) -o $@ $< -shared -Wl,--out-implib=$@.a endif $(TMPDIR)/lib%.o: %.c diff --git a/src/test/run-make-fulldeps/used/Makefile b/src/test/run-make-fulldeps/used/Makefile index 8d913e3993502..4d904472931ec 100644 --- a/src/test/run-make-fulldeps/used/Makefile +++ b/src/test/run-make-fulldeps/used/Makefile @@ -1,6 +1,6 @@ -include ../tools.mk -# ignore-windows +# ignore-windows-msvc all: $(RUSTC) -C opt-level=3 --emit=obj used.rs diff --git a/src/test/rustdoc-ui/intra-links-private.rs b/src/test/rustdoc-ui/intra-links-private.rs index b7906aba5b1a9..86cf9fed3dab4 100644 --- a/src/test/rustdoc-ui/intra-links-private.rs +++ b/src/test/rustdoc-ui/intra-links-private.rs @@ -1,7 +1,7 @@ // check-pass // revisions: public private // [private]compile-flags: --document-private-items -#![cfg_attr(private, deny(intra_doc_resolution_failure))] +#![cfg_attr(private, deny(intra_doc_link_resolution_failure))] /// docs [DontDocMe] //[public]~^ WARNING `[DontDocMe]` public documentation for `DocMe` links to a private item diff --git a/src/test/rustdoc/internal.rs b/src/test/rustdoc/internal.rs index 2cb7c472cc84b..a1e322fb9a307 100644 --- a/src/test/rustdoc/internal.rs +++ b/src/test/rustdoc/internal.rs @@ -1,11 +1,13 @@ // compile-flags: -Z force-unstable-if-unmarked -// @matches internal/index.html '//*[@class="docblock-short"]/span[@class="stab internal"]' \ -// 'Internal' +// Check that the unstable marker is not added for "rustc_private". + +// @!matches internal/index.html '//*[@class="docblock-short"]/span[@class="stab unstable"]' +// @!matches internal/index.html '//*[@class="docblock-short"]/span[@class="stab internal"]' // @matches - '//*[@class="docblock-short"]' 'Docs' -// @has internal/struct.S.html '//*[@class="stab internal"]' \ -// 'This is an internal compiler API. (rustc_private)' +// @!has internal/struct.S.html '//*[@class="stab unstable"]' +// @!has internal/struct.S.html '//*[@class="stab internal"]' /// Docs pub struct S; diff --git a/src/test/rustdoc/intra-doc-crate/additional_doc.rs b/src/test/rustdoc/intra-doc-crate/additional_doc.rs new file mode 100644 index 0000000000000..adfa7f5754eb9 --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/additional_doc.rs @@ -0,0 +1,10 @@ +// aux-build:additional_doc.rs +// build-aux-docs +#![deny(intra_doc_link_resolution_failure)] + +extern crate my_rand; + +// @has 'additional_doc/trait.Rng.html' '//a[@href="../additional_doc/trait.Rng.html"]' 'Rng' +// @has 'additional_doc/trait.Rng.html' '//a[@href="../my_rand/trait.RngCore.html"]' 'RngCore' +/// This is an [`Rng`]. +pub use my_rand::Rng; diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs new file mode 100644 index 0000000000000..8b8793e75ed59 --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs @@ -0,0 +1,6 @@ +#![crate_name = "my_rand"] +#![deny(intra_doc_link_resolution_failure)] + +pub trait RngCore {} +/// Rng extends [`RngCore`]. +pub trait Rng: RngCore {} diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs new file mode 100644 index 0000000000000..2ee5835a7df84 --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs @@ -0,0 +1,7 @@ +#![crate_name = "a"] +#![deny(intra_doc_link_resolution_failure)] + +pub struct Foo; + +/// Link to [Foo] +pub struct Bar; diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/macro_inner.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/macro_inner.rs new file mode 100644 index 0000000000000..abd41fec13016 --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/macro_inner.rs @@ -0,0 +1,10 @@ +#![crate_name = "macro_inner"] +#![deny(intra_doc_link_resolution_failure)] + +pub struct Foo; + +/// See also [`Foo`] +#[macro_export] +macro_rules! my_macro { + () => {} +} diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/module.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/module.rs new file mode 100644 index 0000000000000..5d63d7e37b64d --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/module.rs @@ -0,0 +1,7 @@ +#![crate_name = "module_inner"] +#![deny(intra_doc_link_resolution_failure)] +/// [SomeType] links to [bar] +pub struct SomeType; +pub trait SomeTrait {} +/// [bar] links to [SomeTrait] and also [SomeType] +pub mod bar {} diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/proc_macro.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/proc_macro.rs new file mode 100644 index 0000000000000..0d5a954075df2 --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/proc_macro.rs @@ -0,0 +1,20 @@ +// force-host +// no-prefer-dynamic +// compile-flags: --crate-type proc-macro +#![crate_type="proc-macro"] +#![crate_name="proc_macro_inner"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +/// Links to [`OtherDerive`] +#[proc_macro_derive(DeriveA)] +pub fn a_derive(input: TokenStream) -> TokenStream { + input +} + +#[proc_macro_derive(OtherDerive)] +pub fn other_derive(input: TokenStream) -> TokenStream { + input +} diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-inner.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-inner.rs new file mode 100644 index 0000000000000..3a22d13e673ac --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-inner.rs @@ -0,0 +1,12 @@ +#![crate_name = "a"] +#![deny(intra_doc_link_resolution_failure)] + +pub mod bar { + pub struct Bar; +} + +pub mod foo { + use crate::bar; + /// link to [bar::Bar] + pub struct Foo; +} diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-outer.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-outer.rs new file mode 100644 index 0000000000000..b8ca4e44e1f16 --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-outer.rs @@ -0,0 +1,13 @@ +#![crate_name = "bar"] +#![deny(intra_doc_link_resolution_failure)] + +pub trait Foo { + /// [`Bar`] [`Baz`] + fn foo(); +} + +pub trait Bar { +} + +pub trait Baz { +} diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/traits.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/traits.rs new file mode 100644 index 0000000000000..c16e39d56f3d0 --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/traits.rs @@ -0,0 +1,16 @@ +#![crate_name = "inner"] +/// this is a trait +pub trait SomeTrait { + /// this is a method for [a trait][SomeTrait] + fn foo(); +} + +pub mod bar { + use super::SomeTrait; + + pub struct BarStruct; + + impl SomeTrait for BarStruct { + fn foo() {} + } +} diff --git a/src/test/rustdoc/intra-doc-crate/basic.rs b/src/test/rustdoc/intra-doc-crate/basic.rs new file mode 100644 index 0000000000000..a245a0f84539c --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/basic.rs @@ -0,0 +1,9 @@ +// aux-build:intra-doc-basic.rs +// build-aux-docs +#![deny(intra_doc_link_resolution_failure)] + +// from https://github.com/rust-lang/rust/issues/65983 +extern crate a; + +// @has 'basic/struct.Bar.html' '//a[@href="../a/struct.Foo.html"]' 'Foo' +pub use a::Bar; diff --git a/src/test/rustdoc/intra-doc-crate/macro.rs b/src/test/rustdoc/intra-doc-crate/macro.rs new file mode 100644 index 0000000000000..72fd57b6b0c7f --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/macro.rs @@ -0,0 +1,12 @@ +// ignore-tidy-linelength +// aux-build:macro_inner.rs +// aux-build:proc_macro.rs +// build-aux-docs +#![deny(intra_doc_link_resolution_failure)] +extern crate macro_inner; +extern crate proc_macro_inner; + +// @has 'macro/macro.my_macro.html' '//a[@href="../macro_inner/struct.Foo.html"]' 'Foo' +pub use macro_inner::my_macro; +// @has 'macro/derive.DeriveA.html' '//a[@href="../proc_macro_inner/derive.OtherDerive.html"]' 'OtherDerive' +pub use proc_macro_inner::DeriveA; diff --git a/src/test/rustdoc/intra-doc-crate/module.rs b/src/test/rustdoc/intra-doc-crate/module.rs new file mode 100644 index 0000000000000..67fa7293f37fb --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/module.rs @@ -0,0 +1,8 @@ +// outer.rs +// aux-build: module.rs +// build-aux-docs +#![deny(intra_doc_link_resolution_failure)] +extern crate module_inner; +// @has 'module/bar/index.html' '//a[@href="../../module_inner/trait.SomeTrait.html"]' 'SomeTrait' +// @has 'module/bar/index.html' '//a[@href="../../module_inner/struct.SomeType.html"]' 'SomeType' +pub use module_inner::bar; diff --git a/src/test/rustdoc/intra-doc-crate/submodule-inner.rs b/src/test/rustdoc/intra-doc-crate/submodule-inner.rs new file mode 100644 index 0000000000000..b4b615bf9edad --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/submodule-inner.rs @@ -0,0 +1,8 @@ +// aux-build:submodule-inner.rs +// build-aux-docs +#![deny(intra_doc_link_resolution_failure)] + +extern crate a; + +// @has 'submodule_inner/struct.Foo.html' '//a[@href="../a/bar/struct.Bar.html"]' 'Bar' +pub use a::foo::Foo; diff --git a/src/test/rustdoc/intra-doc-crate/submodule-outer.rs b/src/test/rustdoc/intra-doc-crate/submodule-outer.rs new file mode 100644 index 0000000000000..6b30ef8b3dec8 --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/submodule-outer.rs @@ -0,0 +1,16 @@ +// aux-build:submodule-outer.rs +// edition:2018 +#![deny(intra_doc_link_resolution_failure)] + +extern crate bar as bar_; + +// from https://github.com/rust-lang/rust/issues/60883 +pub mod bar { + pub use ::bar_::Bar; +} + +// NOTE: we re-exported both `Foo` and `Bar` here, +// NOTE: so they are inlined and therefore we link to the current module. +// @has 'submodule_outer/trait.Foo.html' '//a[@href="../submodule_outer/bar/trait.Bar.html"]' 'Bar' +// @has 'submodule_outer/trait.Foo.html' '//a[@href="../submodule_outer/trait.Baz.html"]' 'Baz' +pub use ::bar_::{Foo, Baz}; diff --git a/src/test/rustdoc/intra-doc-crate/traits.rs b/src/test/rustdoc/intra-doc-crate/traits.rs new file mode 100644 index 0000000000000..617331236902d --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/traits.rs @@ -0,0 +1,17 @@ +// ignore-test +// ^ this is https://github.com/rust-lang/rust/issues/73829 +// aux-build:traits.rs +// build-aux-docs +// ignore-tidy-line-length +#![deny(intra_doc_link_resolution_failure)] + +extern crate inner; +use inner::SomeTrait; + +pub struct SomeStruct; + + // @has 'traits/struct.SomeStruct.html' '//a[@href="../inner/trait.SomeTrait.html"]' 'SomeTrait' +impl SomeTrait for SomeStruct { + // @has 'traits/struct.SomeStruct.html' '//a[@href="../inner/trait.SomeTrait.html"]' 'a trait' + fn foo() {} +} diff --git a/src/test/rustdoc/intra-link-prim-precedence.rs b/src/test/rustdoc/intra-link-prim-precedence.rs index ca83d5e2281a7..d7ebb73b3be7d 100644 --- a/src/test/rustdoc/intra-link-prim-precedence.rs +++ b/src/test/rustdoc/intra-link-prim-precedence.rs @@ -1,5 +1,5 @@ // ignore-tidy-linelength -#![deny(intra_doc_resolution_failure)] +#![deny(intra_doc_link_resolution_failure)] pub mod char {} diff --git a/src/test/ui/issues/issue-59020.rs b/src/test/ui/issues/issue-59020.rs index e7544934da0c8..a2b11764a2fc6 100644 --- a/src/test/ui/issues/issue-59020.rs +++ b/src/test/ui/issues/issue-59020.rs @@ -1,7 +1,6 @@ // edition:2018 // run-pass // ignore-emscripten no threads support -// ignore-sgx no thread sleep support use std::thread; use std::time::Duration; diff --git a/src/test/ui/issues/issue-9396.rs b/src/test/ui/issues/issue-9396.rs index 27b5185377d97..3e7e9a51cdd3a 100644 --- a/src/test/ui/issues/issue-9396.rs +++ b/src/test/ui/issues/issue-9396.rs @@ -2,7 +2,6 @@ #![allow(unused_must_use)] #![allow(deprecated)] // ignore-emscripten no threads support -// ignore-sgx no thread sleep support use std::sync::mpsc::{TryRecvError, channel}; use std::thread; diff --git a/src/test/ui/mpsc_stress.rs b/src/test/ui/mpsc_stress.rs index bce5fdcd119f7..a889542fec0be 100644 --- a/src/test/ui/mpsc_stress.rs +++ b/src/test/ui/mpsc_stress.rs @@ -1,7 +1,6 @@ // run-pass // compile-flags:--test // ignore-emscripten -// ignore-sgx no thread sleep support use std::sync::mpsc::channel; use std::sync::mpsc::TryRecvError; @@ -37,6 +36,8 @@ impl Barrier { fn wait(self) { self.shared.fetch_add(1, Ordering::SeqCst); while self.shared.load(Ordering::SeqCst) != self.count { + #[cfg(target_env = "sgx")] + thread::yield_now(); } } } diff --git a/src/test/ui/sleep.rs b/src/test/ui/sleep.rs index 757578b84750c..3b3a4a4f3250c 100644 --- a/src/test/ui/sleep.rs +++ b/src/test/ui/sleep.rs @@ -1,6 +1,5 @@ // run-pass // ignore-emscripten no threads support -// ignore-sgx no thread sleep support use std::thread::{self, sleep}; use std::time::Duration; diff --git a/src/test/ui/tcp-stress.rs b/src/test/ui/tcp-stress.rs index 1f1948fa8fa2c..08b47dc531857 100644 --- a/src/test/ui/tcp-stress.rs +++ b/src/test/ui/tcp-stress.rs @@ -4,7 +4,6 @@ // ignore-emscripten no threads or sockets support // ignore-netbsd system ulimit (Too many open files) // ignore-openbsd system ulimit (Too many open files) -// ignore-sgx no thread sleep support use std::io::prelude::*; use std::net::{TcpListener, TcpStream}; diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 2c64abb4be6bd..6ac89f2b1b82a 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -34,6 +34,7 @@ static HOSTS: &[&str] = &[ "powerpc-unknown-linux-gnu", "powerpc64-unknown-linux-gnu", "powerpc64le-unknown-linux-gnu", + "riscv64gc-unknown-linux-gnu", "s390x-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-pc-windows-gnu", diff --git a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs index 7128fee9bcf51..1d4772bb3d606 100644 --- a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs +++ b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs @@ -8,7 +8,7 @@ use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::source_map::Span; -use rustc_span::symbol::{Ident, SymbolStr}; +use rustc_span::symbol::{Ident, Symbol}; use std::cmp::Ordering; declare_clippy_lint! { @@ -75,7 +75,7 @@ pub struct NonExpressiveNames { impl_lint_pass!(NonExpressiveNames => [SIMILAR_NAMES, MANY_SINGLE_CHAR_NAMES, JUST_UNDERSCORES_AND_DIGITS]); struct ExistingName { - interned: SymbolStr, + interned: Symbol, span: Span, len: usize, exemptions: &'static [&'static str], @@ -218,18 +218,19 @@ impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> { let mut split_at = None; match existing_name.len.cmp(&count) { Ordering::Greater => { - if existing_name.len - count != 1 || levenstein_not_1(&interned_name, &existing_name.interned) { + if existing_name.len - count != 1 || levenstein_not_1(&interned_name, &existing_name.interned.as_str()) { continue; } }, Ordering::Less => { - if count - existing_name.len != 1 || levenstein_not_1(&existing_name.interned, &interned_name) { + if count - existing_name.len != 1 || levenstein_not_1(&existing_name.interned.as_str(), &interned_name) { continue; } }, Ordering::Equal => { let mut interned_chars = interned_name.chars(); - let mut existing_chars = existing_name.interned.chars(); + let interned_str = existing_name.interned.as_str(); + let mut existing_chars = interned_str.chars(); let first_i = interned_chars.next().expect("we know we have at least one char"); let first_e = existing_chars.next().expect("we know we have at least one char"); let eq_or_numeric = |(a, b): (char, char)| a == b || a.is_numeric() && b.is_numeric(); @@ -302,7 +303,7 @@ impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> { } self.0.names.push(ExistingName { exemptions: get_exemptions(&interned_name).unwrap_or(&[]), - interned: interned_name, + interned: ident.name, span: ident.span, len: count, }); diff --git a/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs b/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs index 735800e7e7416..154082a0fdb53 100644 --- a/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs +++ b/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs @@ -3,7 +3,7 @@ use rustc_ast::ast::{Item, ItemKind, UseTree, UseTreeKind}; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; -use rustc_span::symbol::{Ident, SymbolStr}; +use rustc_span::symbol::Ident; declare_clippy_lint! { /// **What it does:** Checks for imports that remove "unsafe" from an item's @@ -73,6 +73,6 @@ fn unsafe_to_safe_check(old_name: Ident, new_name: Ident, cx: &EarlyContext<'_>, } #[must_use] -fn contains_unsafe(name: &SymbolStr) -> bool { +fn contains_unsafe(name: &str) -> bool { name.contains("Unsafe") || name.contains("unsafe") } diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 571e7a59113ad..d6e28e93c9667 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -867,6 +867,7 @@ impl Config { &self.target == name || // triple util::matches_os(&self.target, name) || // target util::matches_env(&self.target, name) || // env + self.target.ends_with(name) || // target and env name == util::get_arch(&self.target) || // architecture name == util::get_pointer_width(&self.target) || // pointer width name == self.stage_id.split('-').next().unwrap() || // stage diff --git a/src/tools/rustc-std-workspace-std/lib.rs b/src/tools/rustc-std-workspace-std/lib.rs index f40d09cafbb47..1e955c61ac85f 100644 --- a/src/tools/rustc-std-workspace-std/lib.rs +++ b/src/tools/rustc-std-workspace-std/lib.rs @@ -1 +1,2 @@ +#![feature(restricted_std)] pub use std::*;