From 4721b6518ce9c8e3a452af07c6dd178fbb83ab16 Mon Sep 17 00:00:00 2001 From: Arlie Davis Date: Mon, 14 Dec 2020 15:45:19 -0800 Subject: [PATCH 01/12] Split a func into cold/hot parts, reducing binary size I noticed that the Size::bits function is called in many places, and is inlined into them. On x86_64-pc-windows-msvc, this function is inlined 527 times, and compiled separately (non-inlined) 3 times. Each of those inlined calls contains code that panics. This commit moves the `panic!` call into a separate function and marks that function with `#[cold]`. This reduces binary size by 24 KB. By itself, that's not a substantial reduction. However, changes like this often reduce pressure on instruction-caches, since it reduces the amount of code that is inlined into hot code paths. Or more precisely, it removes cold code from hot cache lines. It also removes all conditionals from Size::bits(), which is called in many places. --- compiler/rustc_target/src/abi/mod.rs | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index a43080b09e9a1..31ceb0a389076 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -238,22 +238,38 @@ pub enum 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] @@ -268,9 +284,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] From 92d3537abb36a1c8c269fc96b9a962be40745a99 Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Sat, 12 Dec 2020 21:38:23 -0600 Subject: [PATCH 02/12] Add wasi-exec-model cg option for emitting wasi reactors --- compiler/rustc_codegen_ssa/src/back/link.rs | 1 + compiler/rustc_codegen_ssa/src/back/linker.rs | 11 ++++++++++ compiler/rustc_interface/src/tests.rs | 3 ++- compiler/rustc_session/src/config.rs | 2 ++ compiler/rustc_session/src/options.rs | 20 ++++++++++++++++++- compiler/rustc_session/src/session.rs | 8 ++++++++ compiler/rustc_target/src/spec/crt_objects.rs | 20 ++++++++++--------- compiler/rustc_target/src/spec/mod.rs | 6 +++++- src/bootstrap/compile.rs | 18 +++++++++-------- 9 files changed, 69 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 70cf876a08a51..80b92d3a72cdf 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1193,6 +1193,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_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 2273266a3ff82..62f620e0639a4 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_session/src/config.rs b/compiler/rustc_session/src/config.rs index 54abb65dc3883..31fc13d23727f 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2086,6 +2086,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; @@ -2141,6 +2142,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 74578f2dc179f..bc1d862b16071 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -278,6 +278,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)] @@ -708,6 +709,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 + } } ) } @@ -1147,9 +1157,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 4e269f3172c20..93c619c405452 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/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 8d749493d0a42..f0ef15e1a3944 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -407,6 +407,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 { @@ -418,6 +420,7 @@ impl LinkOutputKind { LinkOutputKind::StaticPicExe => "static-pic-exe", LinkOutputKind::DynamicDylib => "dynamic-dylib", LinkOutputKind::StaticDylib => "static-dylib", + LinkOutputKind::WasiReactorExe => "wasi-reactor-exe", } } @@ -429,6 +432,7 @@ impl LinkOutputKind { "static-pic-exe" => LinkOutputKind::StaticPicExe, "dynamic-dylib" => LinkOutputKind::DynamicDylib, "static-dylib" => LinkOutputKind::StaticDylib, + "wasi-reactor-exe" => LinkOutputKind::WasiReactorExe, _ => return None, }) } @@ -1377,7 +1381,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/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index cdad1cb4d499d..c142c43c98da4 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -187,14 +187,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); From de90afc72e2393efad0fb9cdfd765703a044fe02 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 22 Dec 2020 22:15:40 -0500 Subject: [PATCH 03/12] Explain method-call move errors in loops PR #73708 added a more detailed explanation of move errors that occur due to a call to a method that takes `self`. This PR extends that logic to work when a move error occurs due to a method call in the previous iteration of a loop. --- .../diagnostics/conflict_errors.rs | 142 +++++++++--------- src/test/ui/moves/move-fn-self-receiver.rs | 5 + .../ui/moves/move-fn-self-receiver.stderr | 11 +- .../suggestions/borrow-for-loop-head.stderr | 8 +- 4 files changed, 90 insertions(+), 76 deletions(-) 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..c2a14840fb85e 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 consumes the receiver `self` by taking ownership of it, 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/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..8c509363d02d1 100644 --- a/src/test/ui/moves/move-fn-self-receiver.stderr +++ b/src/test/ui/moves/move-fn-self-receiver.stderr @@ -152,7 +152,16 @@ note: this function consumes the receiver `self` by taking ownership of it, whic 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/suggestions/borrow-for-loop-head.stderr b/src/test/ui/suggestions/borrow-for-loop-head.stderr index de342a969f4eb..64ce6c1e16d4b 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 consumes the receiver `self` by taking ownership of it, 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 From 20979aad7733d8ddc89a1922560c4770d3a6e814 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 8 Jan 2021 14:57:28 -0500 Subject: [PATCH 04/12] Change wording of note --- .../src/borrow_check/diagnostics/conflict_errors.rs | 2 +- src/test/ui/codemap_tests/tab_3.stderr | 2 +- src/test/ui/issues/issue-34721.stderr | 2 +- src/test/ui/issues/issue-61108.stderr | 2 +- src/test/ui/issues/issue-64559.stderr | 2 +- src/test/ui/moves/move-fn-self-receiver.stderr | 12 ++++++------ .../moves/moves-based-on-type-access-to-field.stderr | 2 +- src/test/ui/moves/moves-based-on-type-exprs.stderr | 4 ++-- src/test/ui/suggestions/borrow-for-loop-head.stderr | 2 +- src/test/ui/unsized-locals/borrow-after-move.stderr | 2 +- src/test/ui/unsized-locals/double-move.stderr | 2 +- .../ui/use/use-after-move-self-based-on-type.stderr | 2 +- src/test/ui/use/use-after-move-self.stderr | 2 +- src/test/ui/walk-struct-literal-with.stderr | 2 +- 14 files changed, 20 insertions(+), 20 deletions(-) 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 c2a14840fb85e..db02ee67910b2 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs @@ -218,7 +218,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { 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) + &format!("this function takes ownership of the receiver `self`, which moves {}", place_name) ); } } 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.stderr b/src/test/ui/moves/move-fn-self-receiver.stderr index 8c509363d02d1..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,7 +146,7 @@ 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 { 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 64ce6c1e16d4b..28c319b659765 100644 --- a/src/test/ui/suggestions/borrow-for-loop-head.stderr +++ b/src/test/ui/suggestions/borrow-for-loop-head.stderr @@ -18,7 +18,7 @@ LL | for j in a { | `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 consumes the receiver `self` by taking ownership of it, which moves `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; 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{ From eef95871a4a43b7e366c168fc03d316519029c62 Mon Sep 17 00:00:00 2001 From: Eric Seppanen Date: Sat, 9 Jan 2021 22:40:48 -0800 Subject: [PATCH 05/12] fix broken link in PartialEq doc PartialEq doc was attempting to link to [`Eq`] but instead we got a link to `eq`. Disambiguate with "trait@Eq". --- library/core/src/cmp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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`): /// From f9b5859173c926c53fd40a371c6f39e226de56f6 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 10 Jan 2021 14:36:30 +0300 Subject: [PATCH 06/12] resolve: Simplify built-in macro table --- compiler/rustc_builtin_macros/src/lib.rs | 14 ++++---------- compiler/rustc_expand/src/base.rs | 2 +- compiler/rustc_interface/src/passes.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 4 ++-- compiler/rustc_resolve/src/macros.rs | 12 +++++++----- 5 files changed, 15 insertions(+), 19 deletions(-) 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_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_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index bc6c70c26ae0e..eb5206ee9fbfd 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}; @@ -870,7 +870,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 60a1fc8863132..6d99097b7d2b5 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)); } } @@ -1096,7 +1098,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, From 578da998afd116be69fe4e518a6279dcb18321d7 Mon Sep 17 00:00:00 2001 From: LingMan Date: Sun, 10 Jan 2021 14:38:14 +0100 Subject: [PATCH 07/12] Merge different function exits --- compiler/rustc_middle/src/hir/map/mod.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) 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 { From 2750e362092b690494f408d5cde9436c3ccc5ae3 Mon Sep 17 00:00:00 2001 From: Camelid Date: Sun, 10 Jan 2021 12:45:58 -0800 Subject: [PATCH 08/12] rustdoc: Resolve `&str` as `str` People almost always are referring to `&str`, not `str`, so this will save a manual link resolve in many cases. Note that we already accept `&` (resolves to `reference`) in intra-doc links, so this shouldn't cause breakage. --- src/librustdoc/passes/collect_intra_doc_links.rs | 2 +- src/test/rustdoc/intra-doc/non-path-primitives.rs | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 11ee59b2401c8..0eb5c63cef5e6 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -2086,7 +2086,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 ad4f6ddd9de69..28256a442d7fe 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' From e2d3a25161465ecb2a88a1c06708604a56f875c3 Mon Sep 17 00:00:00 2001 From: Camelid Date: Sun, 10 Jan 2021 21:24:15 -0800 Subject: [PATCH 09/12] Fix small typo transmutting -> transmuting --- compiler/rustc_passes/src/intrinsicck.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) { From 94bf59ea34a1592ca8797e03ac4511e344139cdf Mon Sep 17 00:00:00 2001 From: Gus Caplan Date: Sat, 12 Dec 2020 22:31:35 -0600 Subject: [PATCH 10/12] Use correct ABI for wasm32 by default Introduces `RUSTC_USE_WASM32_BINDGEN_COMPAT_ABI` env var to use the compat ABI if need. --- compiler/rustc_target/src/abi/call/mod.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 5de9a8dfa7ac1..73c1296a68643 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -605,7 +605,12 @@ 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" + if cx.target_spec().os != "emscripten" + && std::env::var("RUSTC_USE_WASM32_BINDGEN_COMPAT_ABI") + .map(|x| &x != "0") + .unwrap_or(false) => + { wasm32_bindgen_compat::compute_abi_info(self) } "wasm32" | "asmjs" => wasm32::compute_abi_info(cx, self), From 8f64cec02234a8971d547e7c610015fabc87162e Mon Sep 17 00:00:00 2001 From: Gus Caplan Date: Mon, 14 Dec 2020 10:33:35 -0600 Subject: [PATCH 11/12] new target --- compiler/rustc_target/src/abi/call/mod.rs | 7 +------ compiler/rustc_target/src/spec/mod.rs | 1 + compiler/rustc_target/src/spec/wasm32_unknown_bindgen.rs | 9 +++++++++ src/doc/rustc/src/platform-support.md | 1 + 4 files changed, 12 insertions(+), 6 deletions(-) create mode 100644 compiler/rustc_target/src/spec/wasm32_unknown_bindgen.rs diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 73c1296a68643..89a1f2a55343e 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -605,12 +605,7 @@ 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" - && std::env::var("RUSTC_USE_WASM32_BINDGEN_COMPAT_ABI") - .map(|x| &x != "0") - .unwrap_or(false) => - { + "wasm32" if cx.target_spec().os == "bindgen" => { wasm32_bindgen_compat::compute_abi_info(self) } "wasm32" | "asmjs" => wasm32::compute_abi_info(cx, self), diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index abc96eb3322ec..32d64bac05cbe 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -613,6 +613,7 @@ supported_targets! { ("thumbv7a-uwp-windows-msvc", thumbv7a_uwp_windows_msvc), ("asmjs-unknown-emscripten", asmjs_unknown_emscripten), + ("wasm32-unknown-bindgen", wasm32_unknown_bindgen), ("wasm32-unknown-emscripten", wasm32_unknown_emscripten), ("wasm32-unknown-unknown", wasm32_unknown_unknown), ("wasm32-wasi", wasm32_wasi), diff --git a/compiler/rustc_target/src/spec/wasm32_unknown_bindgen.rs b/compiler/rustc_target/src/spec/wasm32_unknown_bindgen.rs new file mode 100644 index 0000000000000..67163fcb4175c --- /dev/null +++ b/compiler/rustc_target/src/spec/wasm32_unknown_bindgen.rs @@ -0,0 +1,9 @@ +//! This target is a variant of `wasm32-unknown-unknown` which uses the bindgen +//! ABI instead of the normal ABI. +use super::{wasm32_unknown_unknown, Target}; + +pub fn target() -> Target { + let mut target = wasm32_unknown_unknown::target(); + target.options.os = "bindgen".to_string(); + target +} diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index ce8caae375e98..bbfffecfe88fd 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -126,6 +126,7 @@ target | std | host | notes `thumbv8m.base-none-eabi` | * | | ARMv8-M Baseline `thumbv8m.main-none-eabi` | * | | ARMv8-M Mainline `thumbv8m.main-none-eabihf` | * | | ARMv8-M Mainline, hardfloat +`wasm32-unknown-bindgen` | ✓ | | WebAssembly via wasm-bindgen `wasm32-unknown-emscripten` | ✓ | | WebAssembly via Emscripten `wasm32-unknown-unknown` | ✓ | | WebAssembly `wasm32-wasi` | ✓ | | WebAssembly with WASI From 5ba3be1d60618fcd7fb819fdee4590ec048f190f Mon Sep 17 00:00:00 2001 From: Gus Caplan Date: Mon, 11 Jan 2021 15:31:52 -0600 Subject: [PATCH 12/12] squash! fix wasi --- compiler/rustc_target/src/abi/call/mod.rs | 9 +++++---- compiler/rustc_target/src/spec/mod.rs | 1 - compiler/rustc_target/src/spec/wasm32_unknown_bindgen.rs | 9 --------- src/doc/rustc/src/platform-support.md | 1 - 4 files changed, 5 insertions(+), 15 deletions(-) delete mode 100644 compiler/rustc_target/src/spec/wasm32_unknown_bindgen.rs diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 89a1f2a55343e..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 == "bindgen" => { - 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/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 32d64bac05cbe..abc96eb3322ec 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -613,7 +613,6 @@ supported_targets! { ("thumbv7a-uwp-windows-msvc", thumbv7a_uwp_windows_msvc), ("asmjs-unknown-emscripten", asmjs_unknown_emscripten), - ("wasm32-unknown-bindgen", wasm32_unknown_bindgen), ("wasm32-unknown-emscripten", wasm32_unknown_emscripten), ("wasm32-unknown-unknown", wasm32_unknown_unknown), ("wasm32-wasi", wasm32_wasi), diff --git a/compiler/rustc_target/src/spec/wasm32_unknown_bindgen.rs b/compiler/rustc_target/src/spec/wasm32_unknown_bindgen.rs deleted file mode 100644 index 67163fcb4175c..0000000000000 --- a/compiler/rustc_target/src/spec/wasm32_unknown_bindgen.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! This target is a variant of `wasm32-unknown-unknown` which uses the bindgen -//! ABI instead of the normal ABI. -use super::{wasm32_unknown_unknown, Target}; - -pub fn target() -> Target { - let mut target = wasm32_unknown_unknown::target(); - target.options.os = "bindgen".to_string(); - target -} diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index bbfffecfe88fd..ce8caae375e98 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -126,7 +126,6 @@ target | std | host | notes `thumbv8m.base-none-eabi` | * | | ARMv8-M Baseline `thumbv8m.main-none-eabi` | * | | ARMv8-M Mainline `thumbv8m.main-none-eabihf` | * | | ARMv8-M Mainline, hardfloat -`wasm32-unknown-bindgen` | ✓ | | WebAssembly via wasm-bindgen `wasm32-unknown-emscripten` | ✓ | | WebAssembly via Emscripten `wasm32-unknown-unknown` | ✓ | | WebAssembly `wasm32-wasi` | ✓ | | WebAssembly with WASI