diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index ed76d51231d0b..635890644d067 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -14,10 +14,9 @@ extern crate proc_macro; use crate::deriving::*; -use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtension, SyntaxExtensionKind}; +use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind}; use rustc_expand::proc_macro::BangProcMacro; -use rustc_span::edition::Edition; -use rustc_span::symbol::{sym, Ident}; +use rustc_span::symbol::sym; mod asm; mod assert; @@ -44,13 +43,8 @@ pub mod proc_macro_harness; pub mod standard_library_imports; pub mod test_harness; -pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand, edition: Edition) { - let mut register = |name, kind| { - resolver.register_builtin_macro( - Ident::with_dummy_span(name), - SyntaxExtension::default(kind, edition), - ) - }; +pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { + let mut register = |name, kind| resolver.register_builtin_macro(name, kind); macro register_bang($($name:ident: $f:expr,)*) { $(register(sym::$name, SyntaxExtensionKind::LegacyBang(Box::new($f as MacroExpanderFn)));)* } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 55fddb38e10be..728795cf50b85 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1276,6 +1276,7 @@ fn exec_linker( fn link_output_kind(sess: &Session, crate_type: CrateType) -> LinkOutputKind { let kind = match (crate_type, sess.crt_static(Some(crate_type)), sess.relocation_model()) { + (CrateType::Executable, _, _) if sess.is_wasi_reactor() => LinkOutputKind::WasiReactorExe, (CrateType::Executable, false, RelocModel::Pic) => LinkOutputKind::DynamicPicExe, (CrateType::Executable, false, _) => LinkOutputKind::DynamicNoPicExe, (CrateType::Executable, true, RelocModel::Pic) => LinkOutputKind::StaticPicExe, diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 3df956c465e5e..bb35e7ec89439 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -314,6 +314,10 @@ impl<'a> Linker for GccLinker<'a> { self.cmd.arg("-static"); self.build_dylib(out_filename); } + LinkOutputKind::WasiReactorExe => { + self.linker_arg("--entry"); + self.linker_arg("_initialize"); + } } // VxWorks compiler driver introduced `--static-crt` flag specifically for rustc, // it switches linking for libc and similar system libraries to static without using @@ -662,6 +666,9 @@ impl<'a> Linker for MsvcLinker<'a> { arg.push(out_filename.with_extension("dll.lib")); self.cmd.arg(arg); } + LinkOutputKind::WasiReactorExe => { + panic!("can't link as reactor on non-wasi target"); + } } } @@ -1085,6 +1092,10 @@ impl<'a> Linker for WasmLd<'a> { LinkOutputKind::DynamicDylib | LinkOutputKind::StaticDylib => { self.cmd.arg("--no-entry"); } + LinkOutputKind::WasiReactorExe => { + self.cmd.arg("--entry"); + self.cmd.arg("_initialize"); + } } } diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index c1953c4d37300..2f43940a9dcbb 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -868,7 +868,7 @@ pub trait ResolverExpand { fn resolve_dollar_crates(&mut self); fn visit_ast_fragment_with_placeholders(&mut self, expn_id: ExpnId, fragment: &AstFragment); - fn register_builtin_macro(&mut self, ident: Ident, ext: SyntaxExtension); + fn register_builtin_macro(&mut self, name: Symbol, ext: SyntaxExtensionKind); fn expansion_for_ast_pass( &mut self, diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 461ee08592275..b67704119bccc 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -236,7 +236,7 @@ fn configure_and_expand_inner<'a>( pre_expansion_lint(sess, lint_store, &krate); let mut resolver = Resolver::new(sess, &krate, crate_name, metadata_loader, &resolver_arenas); - rustc_builtin_macros::register_builtin_macros(&mut resolver, sess.edition()); + rustc_builtin_macros::register_builtin_macros(&mut resolver); krate = sess.time("crate_injection", || { let alt_std_name = sess.opts.alt_std_name.as_ref().map(|s| Symbol::intern(s)); diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 3e94f1637734a..55d521a9b5ff5 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -7,7 +7,7 @@ use rustc_session::config::{build_configuration, build_session_options, to_crate use rustc_session::config::{rustc_optgroups, ErrorOutputType, ExternLocation, Options, Passes}; use rustc_session::config::{CFGuard, ExternEntry, LinkerPluginLto, LtoCli, SwitchWithOptPath}; use rustc_session::config::{ - Externs, OutputType, OutputTypes, SanitizerSet, SymbolManglingVersion, + Externs, OutputType, OutputTypes, SanitizerSet, SymbolManglingVersion, WasiExecModel, }; use rustc_session::lint::Level; use rustc_session::search_paths::SearchPath; @@ -597,6 +597,7 @@ fn test_debugging_options_tracking_hash() { tracked!(unleash_the_miri_inside_of_you, true); tracked!(use_ctors_section, Some(true)); tracked!(verify_llvm_ir, true); + tracked!(wasi_exec_model, Some(WasiExecModel::Reactor)); } #[test] diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index c2e99224d8b36..eb6aded9cb3bd 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -710,15 +710,10 @@ impl<'hir> Map<'hir> { let mut scope = id; loop { scope = self.get_enclosing_scope(scope).unwrap_or(CRATE_HIR_ID); - if scope == CRATE_HIR_ID { - return CRATE_HIR_ID; - } - match self.get(scope) { - Node::Block(_) => {} - _ => break, + if scope == CRATE_HIR_ID || !matches!(self.get(scope), Node::Block(_)) { + return scope; } } - scope } pub fn get_parent_did(&self, id: HirId) -> LocalDefId { diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs index 0bb09e26f03e8..db02ee67910b2 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs @@ -151,95 +151,88 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let move_msg = if move_spans.for_closure() { " into closure" } else { "" }; + let loop_message = if location == move_out.source || move_site.traversed_back_edge { + ", in previous iteration of loop" + } else { + "" + }; + if location == move_out.source { - err.span_label( - span, - format!( - "value {}moved{} here, in previous iteration of loop", - partially_str, move_msg - ), - ); is_loop_move = true; - } else if move_site.traversed_back_edge { - err.span_label( - move_span, - format!( - "value {}moved{} here, in previous iteration of loop", - partially_str, move_msg - ), - ); - } else { - if let UseSpans::FnSelfUse { var_span, fn_call_span, fn_span, kind } = - move_spans - { - let place_name = self - .describe_place(moved_place.as_ref()) - .map(|n| format!("`{}`", n)) - .unwrap_or_else(|| "value".to_owned()); - match kind { - FnSelfUseKind::FnOnceCall => { + } + + if let UseSpans::FnSelfUse { var_span, fn_call_span, fn_span, kind } = move_spans { + let place_name = self + .describe_place(moved_place.as_ref()) + .map(|n| format!("`{}`", n)) + .unwrap_or_else(|| "value".to_owned()); + match kind { + FnSelfUseKind::FnOnceCall => { + err.span_label( + fn_call_span, + &format!( + "{} {}moved due to this call{}", + place_name, partially_str, loop_message + ), + ); + err.span_note( + var_span, + "this value implements `FnOnce`, which causes it to be moved when called", + ); + } + FnSelfUseKind::Operator { self_arg } => { + err.span_label( + fn_call_span, + &format!( + "{} {}moved due to usage in operator{}", + place_name, partially_str, loop_message + ), + ); + if self.fn_self_span_reported.insert(fn_span) { + err.span_note( + self_arg.span, + "calling this operator moves the left-hand side", + ); + } + } + FnSelfUseKind::Normal { self_arg, implicit_into_iter } => { + if implicit_into_iter { err.span_label( fn_call_span, &format!( - "{} {}moved due to this call", - place_name, partially_str + "{} {}moved due to this implicit call to `.into_iter()`{}", + place_name, partially_str, loop_message ), ); - err.span_note( - var_span, - "this value implements `FnOnce`, which causes it to be moved when called", - ); - } - FnSelfUseKind::Operator { self_arg } => { + } else { err.span_label( fn_call_span, &format!( - "{} {}moved due to usage in operator", - place_name, partially_str + "{} {}moved due to this method call{}", + place_name, partially_str, loop_message ), ); - if self.fn_self_span_reported.insert(fn_span) { - err.span_note( - self_arg.span, - "calling this operator moves the left-hand side", - ); - } } - FnSelfUseKind::Normal { self_arg, implicit_into_iter } => { - if implicit_into_iter { - err.span_label( - fn_call_span, - &format!( - "{} {}moved due to this implicit call to `.into_iter()`", - place_name, partially_str - ), - ); - } else { - err.span_label( - fn_call_span, - &format!( - "{} {}moved due to this method call", - place_name, partially_str - ), - ); - } - // Avoid pointing to the same function in multiple different - // error messages - if self.fn_self_span_reported.insert(self_arg.span) { - err.span_note( - self_arg.span, - &format!("this function consumes the receiver `self` by taking ownership of it, which moves {}", place_name) - ); - } + // Avoid pointing to the same function in multiple different + // error messages + if self.fn_self_span_reported.insert(self_arg.span) { + err.span_note( + self_arg.span, + &format!("this function takes ownership of the receiver `self`, which moves {}", place_name) + ); } - // Deref::deref takes &self, which cannot cause a move - FnSelfUseKind::DerefCoercion { .. } => unreachable!(), } - } else { - err.span_label( - move_span, - format!("value {}moved{} here", partially_str, move_msg), - ); + // Deref::deref takes &self, which cannot cause a move + FnSelfUseKind::DerefCoercion { .. } => unreachable!(), + } + } else { + err.span_label( + move_span, + format!("value {}moved{} here{}", partially_str, move_msg, loop_message), + ); + // If the move error occurs due to a loop, don't show + // another message for the same span + if loop_message.is_empty() { move_spans.var_span_label( &mut err, format!( @@ -250,6 +243,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); } } + if let UseSpans::PatUse(span) = move_spans { err.span_suggestion_verbose( span.shrink_to_lo(), diff --git a/compiler/rustc_passes/src/intrinsicck.rs b/compiler/rustc_passes/src/intrinsicck.rs index 711e8e87c6c6e..ee90e9c54f69d 100644 --- a/compiler/rustc_passes/src/intrinsicck.rs +++ b/compiler/rustc_passes/src/intrinsicck.rs @@ -78,7 +78,7 @@ impl ExprVisitor<'tcx> { return; } - // Special-case transmutting from `typeof(function)` and + // Special-case transmuting from `typeof(function)` and // `Option` to present a clearer error. let from = unpack_option_like(self.tcx, from); if let (&ty::FnDef(..), SizeSkeleton::Known(size_to)) = (from.kind(), sk_to) { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 86bb1c77911ef..fb364053e241e 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -33,7 +33,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::ptr_key::PtrKey; use rustc_data_structures::sync::Lrc; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; -use rustc_expand::base::SyntaxExtension; +use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_hir::def::Namespace::*; use rustc_hir::def::{self, CtorOf, DefKind, NonMacroAttrKind, PartialRes}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX}; @@ -874,7 +874,7 @@ pub struct ExternPreludeEntry<'a> { /// Used for better errors for E0773 enum BuiltinMacroState { - NotYetSeen(SyntaxExtension), + NotYetSeen(SyntaxExtensionKind), AlreadySeen(Span), } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index a5eb369ee9058..5c74094ecd3ee 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -14,7 +14,8 @@ use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::ptr_key::PtrKey; use rustc_data_structures::sync::Lrc; use rustc_errors::struct_span_err; -use rustc_expand::base::{Indeterminate, InvocationRes, ResolverExpand, SyntaxExtension}; +use rustc_expand::base::{Indeterminate, InvocationRes, ResolverExpand}; +use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::compile_declarative_macro; use rustc_expand::expand::{AstFragment, Invocation, InvocationKind}; use rustc_feature::is_builtin_attr_name; @@ -176,10 +177,11 @@ impl<'a> ResolverExpand for Resolver<'a> { parent_scope.module.unexpanded_invocations.borrow_mut().remove(&expansion); } - fn register_builtin_macro(&mut self, ident: Ident, ext: SyntaxExtension) { - if self.builtin_macros.insert(ident.name, BuiltinMacroState::NotYetSeen(ext)).is_some() { + fn register_builtin_macro(&mut self, name: Symbol, ext: SyntaxExtensionKind) { + if self.builtin_macros.insert(name, BuiltinMacroState::NotYetSeen(ext)).is_some() { self.session - .span_err(ident.span, &format!("built-in macro `{}` was already defined", ident)); + .diagnostic() + .bug(&format!("built-in macro `{}` was already registered", name)); } } @@ -1097,7 +1099,7 @@ impl<'a> Resolver<'a> { // while still taking everything else from the source code. // If we already loaded this builtin macro, give a better error message than 'no such builtin macro'. match mem::replace(builtin_macro, BuiltinMacroState::AlreadySeen(item.span)) { - BuiltinMacroState::NotYetSeen(ext) => result.kind = ext.kind, + BuiltinMacroState::NotYetSeen(ext) => result.kind = ext, BuiltinMacroState::AlreadySeen(span) => { struct_span_err!( self.session, diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 6074aac4032c4..0cafdec1495bb 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2172,6 +2172,7 @@ crate mod dep_tracking { SymbolManglingVersion, TrimmedDefPaths, }; use crate::lint; + use crate::options::WasiExecModel; use crate::utils::NativeLibKind; use rustc_feature::UnstableFeatures; use rustc_span::edition::Edition; @@ -2227,6 +2228,7 @@ crate mod dep_tracking { impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); + impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 81f79f4b0e0fb..30af65e49a075 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -279,6 +279,7 @@ macro_rules! options { pub const parse_tls_model: &str = "one of supported TLS models (`rustc --print tls-models`)"; pub const parse_target_feature: &str = parse_string; + pub const parse_wasi_exec_model: &str = "either `command` or `reactor`"; } #[allow(dead_code)] @@ -722,6 +723,15 @@ macro_rules! options { None => false, } } + + fn parse_wasi_exec_model(slot: &mut Option, v: Option<&str>) -> bool { + match v { + Some("command") => *slot = Some(WasiExecModel::Command), + Some("reactor") => *slot = Some(WasiExecModel::Reactor), + _ => return false, + } + true + } } ) } @@ -1166,9 +1176,17 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "in general, enable more debug printouts (default: no)"), verify_llvm_ir: bool = (false, parse_bool, [TRACKED], "verify LLVM IR (default: no)"), + wasi_exec_model: Option = (None, parse_wasi_exec_model, [TRACKED], + "whether to build a wasi command or reactor"), // This list is in alphabetical order. // // If you add a new option, please update: - // - src/librustc_interface/tests.rs + // - compiler/rustc_interface/src/tests.rs +} + +#[derive(Clone, Hash)] +pub enum WasiExecModel { + Command, + Reactor, } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 509e583eca21d..1f9a1af0f6872 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -796,6 +796,14 @@ impl Session { self.opts.debugging_opts.tls_model.unwrap_or(self.target.tls_model) } + pub fn is_wasi_reactor(&self) -> bool { + self.target.options.os == "wasi" + && matches!( + self.opts.debugging_opts.wasi_exec_model, + Some(config::WasiExecModel::Reactor) + ) + } + pub fn must_not_eliminate_frame_pointers(&self) -> bool { // "mcount" function relies on stack pointer. // See . diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 5de9a8dfa7ac1..a9e595d11e759 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -605,10 +605,11 @@ impl<'a, Ty> FnAbi<'a, Ty> { "nvptx64" => nvptx64::compute_abi_info(self), "hexagon" => hexagon::compute_abi_info(self), "riscv32" | "riscv64" => riscv::compute_abi_info(cx, self), - "wasm32" if cx.target_spec().os != "emscripten" => { - wasm32_bindgen_compat::compute_abi_info(self) - } - "wasm32" | "asmjs" => wasm32::compute_abi_info(cx, self), + "wasm32" => match cx.target_spec().os.as_str() { + "emscripten" | "wasi" => wasm32::compute_abi_info(cx, self), + _ => wasm32_bindgen_compat::compute_abi_info(self), + }, + "asmjs" => wasm32::compute_abi_info(cx, self), a => return Err(format!("unrecognized arch \"{}\" in target specification", a)), } diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 61bfd58533a91..93868bed9b98e 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -271,22 +271,38 @@ impl ToJson for Endian { #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Encodable, Decodable)] #[derive(HashStable_Generic)] pub struct Size { + // The top 3 bits are ALWAYS zero. raw: u64, } impl Size { pub const ZERO: Size = Size { raw: 0 }; - #[inline] + /// Rounds `bits` up to the next-higher byte boundary, if `bits` is + /// is not aligned. pub fn from_bits(bits: impl TryInto) -> Size { let bits = bits.try_into().ok().unwrap(); + + #[cold] + fn overflow(bits: u64) -> ! { + panic!("Size::from_bits({}) has overflowed", bits); + } + + // This is the largest value of `bits` that does not cause overflow + // during rounding, and guarantees that the resulting number of bytes + // cannot cause overflow when multiplied by 8. + if bits > 0xffff_ffff_ffff_fff8 { + overflow(bits); + } + // Avoid potential overflow from `bits + 7`. - Size::from_bytes(bits / 8 + ((bits % 8) + 7) / 8) + Size { raw: bits / 8 + ((bits % 8) + 7) / 8 } } #[inline] pub fn from_bytes(bytes: impl TryInto) -> Size { - Size { raw: bytes.try_into().ok().unwrap() } + let bytes: u64 = bytes.try_into().ok().unwrap(); + Size { raw: bytes } } #[inline] @@ -301,9 +317,7 @@ impl Size { #[inline] pub fn bits(self) -> u64 { - self.bytes().checked_mul(8).unwrap_or_else(|| { - panic!("Size::bits: {} bytes in bits doesn't fit in u64", self.bytes()) - }) + self.raw << 3 } #[inline] diff --git a/compiler/rustc_target/src/spec/crt_objects.rs b/compiler/rustc_target/src/spec/crt_objects.rs index 76c0bf419e8c4..32da16a2d8ca8 100644 --- a/compiler/rustc_target/src/spec/crt_objects.rs +++ b/compiler/rustc_target/src/spec/crt_objects.rs @@ -5,15 +5,16 @@ //! The `crtx` ones are generally distributed with libc and the `begin/end` ones with gcc. //! See for some more details. //! -//! | Pre-link CRT objects | glibc | musl | bionic | mingw | wasi | -//! |----------------------|------------------------|------------------------|------------------|-------------------|------| -//! | dynamic-nopic-exe | crt1, crti, crtbegin | crt1, crti, crtbegin | crtbegin_dynamic | crt2, crtbegin | crt1 | -//! | dynamic-pic-exe | Scrt1, crti, crtbeginS | Scrt1, crti, crtbeginS | crtbegin_dynamic | crt2, crtbegin | crt1 | -//! | static-nopic-exe | crt1, crti, crtbeginT | crt1, crti, crtbegin | crtbegin_static | crt2, crtbegin | crt1 | -//! | static-pic-exe | rcrt1, crti, crtbeginS | rcrt1, crti, crtbeginS | crtbegin_dynamic | crt2, crtbegin | crt1 | -//! | dynamic-dylib | crti, crtbeginS | crti, crtbeginS | crtbegin_so | dllcrt2, crtbegin | - | -//! | static-dylib (gcc) | crti, crtbeginT | crti, crtbeginS | crtbegin_so | dllcrt2, crtbegin | - | -//! | static-dylib (clang) | crti, crtbeginT | N/A | crtbegin_static | dllcrt2, crtbegin | - | +//! | Pre-link CRT objects | glibc | musl | bionic | mingw | wasi | +//! |----------------------|------------------------|------------------------|------------------|-------------------|--------------| +//! | dynamic-nopic-exe | crt1, crti, crtbegin | crt1, crti, crtbegin | crtbegin_dynamic | crt2, crtbegin | crt1 | +//! | dynamic-pic-exe | Scrt1, crti, crtbeginS | Scrt1, crti, crtbeginS | crtbegin_dynamic | crt2, crtbegin | crt1 | +//! | static-nopic-exe | crt1, crti, crtbeginT | crt1, crti, crtbegin | crtbegin_static | crt2, crtbegin | crt1 | +//! | static-pic-exe | rcrt1, crti, crtbeginS | rcrt1, crti, crtbeginS | crtbegin_dynamic | crt2, crtbegin | crt1 | +//! | dynamic-dylib | crti, crtbeginS | crti, crtbeginS | crtbegin_so | dllcrt2, crtbegin | - | +//! | static-dylib (gcc) | crti, crtbeginT | crti, crtbeginS | crtbegin_so | dllcrt2, crtbegin | - | +//! | static-dylib (clang) | crti, crtbeginT | N/A | crtbegin_static | dllcrt2, crtbegin | - | +//! | wasi-reactor-exe | N/A | N/A | N/A | N/A | crt1-reactor | //! //! | Post-link CRT objects | glibc | musl | bionic | mingw | wasi | //! |-----------------------|---------------|---------------|----------------|--------|------| @@ -105,6 +106,7 @@ pub(super) fn pre_wasi_fallback() -> CrtObjects { (LinkOutputKind::DynamicPicExe, &["crt1.o"]), (LinkOutputKind::StaticNoPicExe, &["crt1.o"]), (LinkOutputKind::StaticPicExe, &["crt1.o"]), + (LinkOutputKind::WasiReactorExe, &["crt1-reactor.o"]), ]) } diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index abc96eb3322ec..d283c2548864f 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -408,6 +408,8 @@ pub enum LinkOutputKind { DynamicDylib, /// Dynamic library with bundled libc ("statically linked"). StaticDylib, + /// WASI module with a lifetime past the _initialize entry point + WasiReactorExe, } impl LinkOutputKind { @@ -419,6 +421,7 @@ impl LinkOutputKind { LinkOutputKind::StaticPicExe => "static-pic-exe", LinkOutputKind::DynamicDylib => "dynamic-dylib", LinkOutputKind::StaticDylib => "static-dylib", + LinkOutputKind::WasiReactorExe => "wasi-reactor-exe", } } @@ -430,6 +433,7 @@ impl LinkOutputKind { "static-pic-exe" => LinkOutputKind::StaticPicExe, "dynamic-dylib" => LinkOutputKind::DynamicDylib, "static-dylib" => LinkOutputKind::StaticDylib, + "wasi-reactor-exe" => LinkOutputKind::WasiReactorExe, _ => return None, }) } @@ -1378,7 +1382,7 @@ impl Target { let kind = LinkOutputKind::from_str(&k).ok_or_else(|| { format!("{}: '{}' is not a valid value for CRT object kind. \ Use '(dynamic,static)-(nopic,pic)-exe' or \ - '(dynamic,static)-dylib'", name, k) + '(dynamic,static)-dylib' or 'wasi-reactor-exe'", name, k) })?; let v = v.as_array().ok_or_else(|| diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 0c459a820c6ea..38c6bfb0ef361 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -29,7 +29,7 @@ use self::Ordering::*; /// /// This trait allows for partial equality, for types that do not have a full /// equivalence relation. For example, in floating point numbers `NaN != NaN`, -/// so floating point types implement `PartialEq` but not [`Eq`]. +/// so floating point types implement `PartialEq` but not [`trait@Eq`]. /// /// Formally, the equality must be (for all `a`, `b` and `c`): /// diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 9477a7cb35477..39700c087a20d 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -188,14 +188,16 @@ fn copy_self_contained_objects( } } else if target.ends_with("-wasi") { let srcdir = builder.wasi_root(target).unwrap().join("lib/wasm32-wasi"); - copy_and_stamp( - builder, - &libdir_self_contained, - &srcdir, - "crt1.o", - &mut target_deps, - DependencyType::TargetSelfContained, - ); + for &obj in &["crt1.o", "crt1-reactor.o"] { + copy_and_stamp( + builder, + &libdir_self_contained, + &srcdir, + obj, + &mut target_deps, + DependencyType::TargetSelfContained, + ); + } } else if target.contains("windows-gnu") { for obj in ["crt2.o", "dllcrt2.o"].iter() { let src = compiler_file(builder, builder.cc(target), target, obj); diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 9cba1b7b0f1cb..708d7710058d5 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -2085,7 +2085,7 @@ fn resolve_primitive(path_str: &str, ns: Namespace) -> Option { "f64" => F64, "char" => Char, "bool" | "true" | "false" => Bool, - "str" => Str, + "str" | "&str" => Str, // See #80181 for why these don't have symbols associated. "slice" => Slice, "array" => Array, diff --git a/src/test/rustdoc/intra-doc/non-path-primitives.rs b/src/test/rustdoc/intra-doc/non-path-primitives.rs index a409744e409b0..2c7e7b5c48c59 100644 --- a/src/test/rustdoc/intra-doc/non-path-primitives.rs +++ b/src/test/rustdoc/intra-doc/non-path-primitives.rs @@ -8,6 +8,15 @@ // @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.array.html#method.map"]' 'array::map' //! [array::map] +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.str.html"]' 'owned str' +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.str.html"]' 'str ref' +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.str.html#method.is_empty"]' 'str::is_empty' +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.str.html#method.len"]' '&str::len' +//! [owned str][str] +//! [str ref][&str] +//! [str::is_empty] +//! [&str::len] + // @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.is_null"]' 'pointer::is_null' // @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.is_null"]' '*const::is_null' // @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.is_null"]' '*mut::is_null' diff --git a/src/test/ui/codemap_tests/tab_3.stderr b/src/test/ui/codemap_tests/tab_3.stderr index 958d54bbb151f..e067dbbf85bdd 100644 --- a/src/test/ui/codemap_tests/tab_3.stderr +++ b/src/test/ui/codemap_tests/tab_3.stderr @@ -9,7 +9,7 @@ LL | { LL | println!("{:?}", some_vec); | ^^^^^^^^ value borrowed here after move | -note: this function consumes the receiver `self` by taking ownership of it, which moves `some_vec` +note: this function takes ownership of the receiver `self`, which moves `some_vec` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL | LL | fn into_iter(self) -> Self::IntoIter; diff --git a/src/test/ui/issues/issue-34721.stderr b/src/test/ui/issues/issue-34721.stderr index b4cc1a0aa7eb2..b14faff8f7b8d 100644 --- a/src/test/ui/issues/issue-34721.stderr +++ b/src/test/ui/issues/issue-34721.stderr @@ -13,7 +13,7 @@ LL | }; LL | x.zero() | ^ value used here after move | -note: this function consumes the receiver `self` by taking ownership of it, which moves `x` +note: this function takes ownership of the receiver `self`, which moves `x` --> $DIR/issue-34721.rs:4:13 | LL | fn zero(self) -> Self; diff --git a/src/test/ui/issues/issue-61108.stderr b/src/test/ui/issues/issue-61108.stderr index d6c289cbd668d..fb242f738c87e 100644 --- a/src/test/ui/issues/issue-61108.stderr +++ b/src/test/ui/issues/issue-61108.stderr @@ -12,7 +12,7 @@ LL | for l in bad_letters { LL | bad_letters.push('s'); | ^^^^^^^^^^^ value borrowed here after move | -note: this function consumes the receiver `self` by taking ownership of it, which moves `bad_letters` +note: this function takes ownership of the receiver `self`, which moves `bad_letters` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL | LL | fn into_iter(self) -> Self::IntoIter; diff --git a/src/test/ui/issues/issue-64559.stderr b/src/test/ui/issues/issue-64559.stderr index 5b97e21b88835..e0da3fd5195cb 100644 --- a/src/test/ui/issues/issue-64559.stderr +++ b/src/test/ui/issues/issue-64559.stderr @@ -13,7 +13,7 @@ LL | let _closure = || orig; | | | value used here after move | -note: this function consumes the receiver `self` by taking ownership of it, which moves `orig` +note: this function takes ownership of the receiver `self`, which moves `orig` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL | LL | fn into_iter(self) -> Self::IntoIter; diff --git a/src/test/ui/moves/move-fn-self-receiver.rs b/src/test/ui/moves/move-fn-self-receiver.rs index 6107f53fa1960..946642ef6f3ad 100644 --- a/src/test/ui/moves/move-fn-self-receiver.rs +++ b/src/test/ui/moves/move-fn-self-receiver.rs @@ -69,6 +69,11 @@ fn move_out(val: Container) { let container = Container(vec![]); for _val in container.custom_into_iter() {} container; //~ ERROR use of moved + + let foo2 = Foo; + loop { + foo2.use_self(); //~ ERROR use of moved + } } fn main() {} diff --git a/src/test/ui/moves/move-fn-self-receiver.stderr b/src/test/ui/moves/move-fn-self-receiver.stderr index dd263c1e90677..eca6bb9296ddc 100644 --- a/src/test/ui/moves/move-fn-self-receiver.stderr +++ b/src/test/ui/moves/move-fn-self-receiver.stderr @@ -6,7 +6,7 @@ LL | val.0.into_iter().next(); LL | val.0; | ^^^^^ value used here after move | -note: this function consumes the receiver `self` by taking ownership of it, which moves `val.0` +note: this function takes ownership of the receiver `self`, which moves `val.0` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL | LL | fn into_iter(self) -> Self::IntoIter; @@ -23,7 +23,7 @@ LL | foo.use_self(); LL | foo; | ^^^ value used here after move | -note: this function consumes the receiver `self` by taking ownership of it, which moves `foo` +note: this function takes ownership of the receiver `self`, which moves `foo` --> $DIR/move-fn-self-receiver.rs:13:17 | LL | fn use_self(self) {} @@ -49,7 +49,7 @@ LL | boxed_foo.use_box_self(); LL | boxed_foo; | ^^^^^^^^^ value used here after move | -note: this function consumes the receiver `self` by taking ownership of it, which moves `boxed_foo` +note: this function takes ownership of the receiver `self`, which moves `boxed_foo` --> $DIR/move-fn-self-receiver.rs:14:21 | LL | fn use_box_self(self: Box) {} @@ -65,7 +65,7 @@ LL | pin_box_foo.use_pin_box_self(); LL | pin_box_foo; | ^^^^^^^^^^^ value used here after move | -note: this function consumes the receiver `self` by taking ownership of it, which moves `pin_box_foo` +note: this function takes ownership of the receiver `self`, which moves `pin_box_foo` --> $DIR/move-fn-self-receiver.rs:15:25 | LL | fn use_pin_box_self(self: Pin>) {} @@ -91,7 +91,7 @@ LL | rc_foo.use_rc_self(); LL | rc_foo; | ^^^^^^ value used here after move | -note: this function consumes the receiver `self` by taking ownership of it, which moves `rc_foo` +note: this function takes ownership of the receiver `self`, which moves `rc_foo` --> $DIR/move-fn-self-receiver.rs:16:20 | LL | fn use_rc_self(self: Rc) {} @@ -146,13 +146,22 @@ LL | for _val in container.custom_into_iter() {} LL | container; | ^^^^^^^^^ value used here after move | -note: this function consumes the receiver `self` by taking ownership of it, which moves `container` +note: this function takes ownership of the receiver `self`, which moves `container` --> $DIR/move-fn-self-receiver.rs:23:25 | LL | fn custom_into_iter(self) -> impl Iterator { | ^^^^ -error: aborting due to 11 previous errors +error[E0382]: use of moved value: `foo2` + --> $DIR/move-fn-self-receiver.rs:75:9 + | +LL | let foo2 = Foo; + | ---- move occurs because `foo2` has type `Foo`, which does not implement the `Copy` trait +LL | loop { +LL | foo2.use_self(); + | ^^^^ ---------- `foo2` moved due to this method call, in previous iteration of loop + +error: aborting due to 12 previous errors Some errors have detailed explanations: E0382, E0505. For more information about an error, try `rustc --explain E0382`. diff --git a/src/test/ui/moves/moves-based-on-type-access-to-field.stderr b/src/test/ui/moves/moves-based-on-type-access-to-field.stderr index 11e9456958084..3cc8ca29144ca 100644 --- a/src/test/ui/moves/moves-based-on-type-access-to-field.stderr +++ b/src/test/ui/moves/moves-based-on-type-access-to-field.stderr @@ -8,7 +8,7 @@ LL | consume(x.into_iter().next().unwrap()); LL | touch(&x[0]); | ^ value borrowed here after move | -note: this function consumes the receiver `self` by taking ownership of it, which moves `x` +note: this function takes ownership of the receiver `self`, which moves `x` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL | LL | fn into_iter(self) -> Self::IntoIter; diff --git a/src/test/ui/moves/moves-based-on-type-exprs.stderr b/src/test/ui/moves/moves-based-on-type-exprs.stderr index 46940cf493659..9bcec36740d62 100644 --- a/src/test/ui/moves/moves-based-on-type-exprs.stderr +++ b/src/test/ui/moves/moves-based-on-type-exprs.stderr @@ -108,7 +108,7 @@ LL | let _y = x.into_iter().next().unwrap(); LL | touch(&x); | ^^ value borrowed here after move | -note: this function consumes the receiver `self` by taking ownership of it, which moves `x` +note: this function takes ownership of the receiver `self`, which moves `x` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL | LL | fn into_iter(self) -> Self::IntoIter; @@ -124,7 +124,7 @@ LL | let _y = [x.into_iter().next().unwrap(); 1]; LL | touch(&x); | ^^ value borrowed here after move | -note: this function consumes the receiver `self` by taking ownership of it, which moves `x` +note: this function takes ownership of the receiver `self`, which moves `x` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL | LL | fn into_iter(self) -> Self::IntoIter; diff --git a/src/test/ui/suggestions/borrow-for-loop-head.stderr b/src/test/ui/suggestions/borrow-for-loop-head.stderr index de342a969f4eb..28c319b659765 100644 --- a/src/test/ui/suggestions/borrow-for-loop-head.stderr +++ b/src/test/ui/suggestions/borrow-for-loop-head.stderr @@ -15,8 +15,14 @@ LL | for i in &a { LL | for j in a { | ^ | | - | value moved here, in previous iteration of loop + | `a` moved due to this implicit call to `.into_iter()`, in previous iteration of loop | help: consider borrowing to avoid moving into the for loop: `&a` + | +note: this function takes ownership of the receiver `self`, which moves `a` + --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL + | +LL | fn into_iter(self) -> Self::IntoIter; + | ^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/unsized-locals/borrow-after-move.stderr b/src/test/ui/unsized-locals/borrow-after-move.stderr index 5934276cc1dda..4f2bc06d4ab8e 100644 --- a/src/test/ui/unsized-locals/borrow-after-move.stderr +++ b/src/test/ui/unsized-locals/borrow-after-move.stderr @@ -51,7 +51,7 @@ LL | y.foo(); LL | println!("{}", &y); | ^^ value borrowed here after move | -note: this function consumes the receiver `self` by taking ownership of it, which moves `y` +note: this function takes ownership of the receiver `self`, which moves `y` --> $DIR/borrow-after-move.rs:5:12 | LL | fn foo(self) -> String; diff --git a/src/test/ui/unsized-locals/double-move.stderr b/src/test/ui/unsized-locals/double-move.stderr index b897dbbc9a3aa..4bb2ad88faf3b 100644 --- a/src/test/ui/unsized-locals/double-move.stderr +++ b/src/test/ui/unsized-locals/double-move.stderr @@ -47,7 +47,7 @@ LL | y.foo(); LL | y.foo(); | ^ value used here after move | -note: this function consumes the receiver `self` by taking ownership of it, which moves `y` +note: this function takes ownership of the receiver `self`, which moves `y` --> $DIR/double-move.rs:5:12 | LL | fn foo(self) -> String; diff --git a/src/test/ui/use/use-after-move-self-based-on-type.stderr b/src/test/ui/use/use-after-move-self-based-on-type.stderr index b9440f4de07a9..7fdc4ab251fe8 100644 --- a/src/test/ui/use/use-after-move-self-based-on-type.stderr +++ b/src/test/ui/use/use-after-move-self-based-on-type.stderr @@ -8,7 +8,7 @@ LL | self.bar(); LL | return self.x; | ^^^^^^ value used here after move | -note: this function consumes the receiver `self` by taking ownership of it, which moves `self` +note: this function takes ownership of the receiver `self`, which moves `self` --> $DIR/use-after-move-self-based-on-type.rs:15:16 | LL | pub fn bar(self) {} diff --git a/src/test/ui/use/use-after-move-self.stderr b/src/test/ui/use/use-after-move-self.stderr index 3da53b024db44..073deee63b98c 100644 --- a/src/test/ui/use/use-after-move-self.stderr +++ b/src/test/ui/use/use-after-move-self.stderr @@ -8,7 +8,7 @@ LL | self.bar(); LL | return *self.x; | ^^^^^^^ value used here after move | -note: this function consumes the receiver `self` by taking ownership of it, which moves `self` +note: this function takes ownership of the receiver `self`, which moves `self` --> $DIR/use-after-move-self.rs:13:16 | LL | pub fn bar(self) {} diff --git a/src/test/ui/walk-struct-literal-with.stderr b/src/test/ui/walk-struct-literal-with.stderr index ece63a2b81947..cda08b0f4e09c 100644 --- a/src/test/ui/walk-struct-literal-with.stderr +++ b/src/test/ui/walk-struct-literal-with.stderr @@ -8,7 +8,7 @@ LL | let end = Mine{other_val:1, ..start.make_string_bar()}; LL | println!("{}", start.test); | ^^^^^^^^^^ value borrowed here after move | -note: this function consumes the receiver `self` by taking ownership of it, which moves `start` +note: this function takes ownership of the receiver `self`, which moves `start` --> $DIR/walk-struct-literal-with.rs:7:28 | LL | fn make_string_bar(mut self) -> Mine{