From 470cdf54ac9acee20ab8da46ef7899bae9f58f29 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 15 Jan 2020 16:39:08 +0100 Subject: [PATCH 01/14] add bare metal ARM Cortex-A targets to rustc -> `rustc --target armv7-none-eabi` will work also build rust-std (rustup) components for them -> `rustup target add armv7-none-eabi` will work --- src/ci/docker/dist-various-1/Dockerfile | 4 ++ src/librustc_target/spec/armv7a_none_eabi.rs | 48 +++++++++++++++++++ .../spec/armv7a_none_eabihf.rs | 36 ++++++++++++++ src/librustc_target/spec/mod.rs | 3 ++ src/tools/build-manifest/src/main.rs | 2 + 5 files changed, 93 insertions(+) create mode 100644 src/librustc_target/spec/armv7a_none_eabi.rs create mode 100644 src/librustc_target/spec/armv7a_none_eabihf.rs diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile index 6bbf092878311..689e18c3b40ba 100644 --- a/src/ci/docker/dist-various-1/Dockerfile +++ b/src/ci/docker/dist-various-1/Dockerfile @@ -134,6 +134,8 @@ ENV TARGETS=$TARGETS,armebv7r-none-eabihf ENV TARGETS=$TARGETS,armv7r-none-eabi ENV TARGETS=$TARGETS,armv7r-none-eabihf ENV TARGETS=$TARGETS,thumbv7neon-unknown-linux-gnueabihf +ENV TARGETS=$TARGETS,armv7a-none-eabi +ENV TARGETS=$TARGETS,armv7a-none-eabihf # riscv targets currently do not need a C compiler, as compiler_builtins # doesn't currently have it enabled, and the riscv gcc compiler is not @@ -147,6 +149,8 @@ ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \ CC_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc \ AR_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-ar \ CXX_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-g++ \ + CC_armv7a_none_eabi=arm-none-eabi-gcc \ + CC_armv7a_none_eabihf=arm-none-eabi-gcc \ CC_riscv32i_unknown_none_elf=false \ CC_riscv32imc_unknown_none_elf=false \ CC_riscv32imac_unknown_none_elf=false \ diff --git a/src/librustc_target/spec/armv7a_none_eabi.rs b/src/librustc_target/spec/armv7a_none_eabi.rs new file mode 100644 index 0000000000000..2fbef154f814c --- /dev/null +++ b/src/librustc_target/spec/armv7a_none_eabi.rs @@ -0,0 +1,48 @@ +// Generic ARMv7-A target for bare-metal code - floating point disabled +// +// This is basically the `armv7-unknown-linux-gnueabi` target with some changes +// (listed below) to bring it closer to the bare-metal `thumb` & `aarch64` +// targets: +// +// - `TargetOptions.features`: added `+strict-align`. rationale: unaligned +// memory access is disabled on boot on these cores +// - linker changed to LLD. rationale: C is not strictly needed to build +// bare-metal binaries (the `gcc` linker has the advantage that it knows where C +// libraries and crt*.o are but it's not much of an advantage here); LLD is also +// faster +// - `target_os` set to `none`. rationale: matches `thumb` targets +// - `target_{env,vendor}` set to an empty string. rationale: matches `thumb` +// targets +// - `panic_strategy` set to `abort`. rationale: matches `thumb` targets +// - `relocation-model` set to `static`; also no PIE, no relro and no dynamic +// linking. rationale: matches `thumb` targets + +use super::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions}; + +pub fn target() -> Result { + let opts = TargetOptions { + linker: Some("rust-lld".to_owned()), + features: "+v7,+thumb2,+soft-float,-neon,+strict-align".to_string(), + executables: true, + relocation_model: "static".to_string(), + disable_redzone: true, + max_atomic_width: Some(64), + panic_strategy: PanicStrategy::Abort, + abi_blacklist: super::arm_base::abi_blacklist(), + emit_debug_gdb_scripts: false, + ..Default::default() + }; + Ok(Target { + llvm_target: "armv7a-none-eabi".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + target_os: "none".to_string(), + target_env: String::new(), + target_vendor: String::new(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + arch: "arm".to_string(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + options: opts, + }) +} diff --git a/src/librustc_target/spec/armv7a_none_eabihf.rs b/src/librustc_target/spec/armv7a_none_eabihf.rs new file mode 100644 index 0000000000000..f31e68c5bd12a --- /dev/null +++ b/src/librustc_target/spec/armv7a_none_eabihf.rs @@ -0,0 +1,36 @@ +// Generic ARMv7-A target for bare-metal code - floating point enabled (assumes +// FPU is present and emits FPU instructions) +// +// This is basically the `armv7-unknown-linux-gnueabihf` target with some +// changes (list in `armv7a_none_eabi.rs`) to bring it closer to the bare-metal +// `thumb` & `aarch64` targets. + +use super::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions}; + +pub fn target() -> Result { + let opts = TargetOptions { + linker: Some("rust-lld".to_owned()), + features: "+v7,+vfp3,-d32,+thumb2,-neon,+strict-align".to_string(), + executables: true, + relocation_model: "static".to_string(), + disable_redzone: true, + max_atomic_width: Some(64), + panic_strategy: PanicStrategy::Abort, + abi_blacklist: super::arm_base::abi_blacklist(), + emit_debug_gdb_scripts: false, + ..Default::default() + }; + Ok(Target { + llvm_target: "armv7a-none-eabihf".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + target_os: "none".to_string(), + target_env: String::new(), + target_vendor: String::new(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + arch: "arm".to_string(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + options: opts, + }) +} diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 528ffdf93a01a..67f45d3d230ef 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -472,6 +472,9 @@ supported_targets! { ("thumbv8m.main-none-eabi", thumbv8m_main_none_eabi), ("thumbv8m.main-none-eabihf", thumbv8m_main_none_eabihf), + ("armv7a-none-eabi", armv7a_none_eabi), + ("armv7a-none-eabihf", armv7a_none_eabihf), + ("msp430-none-elf", msp430_none_elf), ("aarch64-unknown-cloudabi", aarch64_unknown_cloudabi), diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 481163a1a9abe..8281d20e4c886 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -69,6 +69,8 @@ static TARGETS: &[&str] = &[ "thumbv7neon-linux-androideabi", "armv7-unknown-linux-gnueabi", "armv7-unknown-linux-gnueabihf", + "armv7a-none-eabi", + "armv7a-none-eabihf", "thumbv7neon-unknown-linux-gnueabihf", "armv7-unknown-linux-musleabi", "armv7-unknown-linux-musleabihf", From de388032555b697d1b0ef197241886ab90ac39b2 Mon Sep 17 00:00:00 2001 From: Tobias Kortkamp Date: Sun, 19 Jan 2020 07:04:24 +0100 Subject: [PATCH 02/14] Add -Wl,-znotext to default linker flags to link with lld 9 on FreeBSD 13.0-CURRENT i386 rust-nightly has been failing to link since 2019-12-10 with variations of ``` = note: ld: error: relocation R_386_PC32 cannot be used against symbol __rust_probestack; recompile with -fPIC >>> defined in /wrkdirs/usr/ports/lang/rust-nightly/work/rustc-nightly-src/build/i686-unknown-freebsd/stage1/lib/rustlib/i686-unknown-freebsd/lib/libcompiler_builtins-6570a75fe85f0e1a.rlib(compiler_builtins-6570a75fe85f0e1a.compiler_builtins.2i519eqi-cgu.15.rcgu.o) >>> referenced by std.4xivr03c-cgu.14 >>> std-9bd70afd58e204b7.std.4xivr03c-cgu.14.rcgu.o:(_$LT$alloc..boxed..Box$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$A$GT$$GT$::call_once::h1c78ed6e734a2bfc (.llvm.10122419023709863394)) in archive /wrkdirs/usr/ports/lang/rust-nightly/work/rustc-nightly-src/build/i686-unknown-freebsd/stage1/lib/rustlib/i686-unknown-freebsd/lib/libstd-9bd70afd58e204b7.rlib ld: error: relocation R_386_PC32 cannot be used against symbol __rust_probestack; recompile with -fPIC >>> defined in /wrkdirs/usr/ports/lang/rust-nightly/work/rustc-nightly-src/build/i686-unknown-freebsd/stage1/lib/rustlib/i686-unknown-freebsd/lib/libcompiler_builtins-6570a75fe85f0e1a.rlib(compiler_builtins-6570a75fe85f0e1a.compiler_builtins.2i519eqi-cgu.15.rcgu.o) >>> referenced by std.4xivr03c-cgu.14 >>> std-9bd70afd58e204b7.std.4xivr03c-cgu.14.rcgu.o:(std::io::util::copy::h9115f048f2203467) in archive /wrkdirs/usr/ports/lang/rust-nightly/work/rustc-nightly-src/build/i686-unknown-freebsd/stage1/lib/rustlib/i686-unknown-freebsd/lib/libstd-9bd70afd58e204b7.rlib clang-cpp: error: linker command failed with exit code 1 (use -v to see invocation) error: aborting due to previous error error: could not compile `rustc_macros`. ``` Full log: http://beefy17.nyi.freebsd.org/data/head-i386-default/p523508_s356869/logs/rust-nightly-1.42.0.20200118.log AFAICT it stopped building after bumping compiler_builtins to 0.1.22 in https://github.com/rust-lang/rust/pull/67110. --- src/librustc_target/spec/i686_unknown_freebsd.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustc_target/spec/i686_unknown_freebsd.rs b/src/librustc_target/spec/i686_unknown_freebsd.rs index 88c944a6cb7eb..60f2188514e1b 100644 --- a/src/librustc_target/spec/i686_unknown_freebsd.rs +++ b/src/librustc_target/spec/i686_unknown_freebsd.rs @@ -4,7 +4,9 @@ pub fn target() -> TargetResult { let mut base = super::freebsd_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); + let pre_link_args = base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap(); + pre_link_args.push("-m32".to_string()); + pre_link_args.push("-Wl,-znotext".to_string()); base.stack_probes = true; Ok(Target { From 2c0845c6ccfdee7fb255756918a22101376efa7e Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sun, 19 Jan 2020 22:08:15 +0100 Subject: [PATCH 03/14] Mark __msan_track_origins as an exported symbol for LTO --- src/librustc_codegen_ssa/back/symbol_export.rs | 8 +++++++- src/test/codegen/sanitizer-memory-track-orgins.rs | 6 +++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index bd44b4a38fd58..c5989748560ce 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc::middle::exported_symbols::{metadata_symbol_name, ExportedSymbol, SymbolExportLevel}; -use rustc::session::config; +use rustc::session::config::{self, Sanitizer}; use rustc::ty::query::Providers; use rustc::ty::subst::SubstsRef; use rustc::ty::Instance; @@ -206,6 +206,12 @@ fn exported_symbols_provider_local( })); } + if let Some(Sanitizer::Memory) = tcx.sess.opts.debugging_opts.sanitizer { + // Similar to profiling, preserve weak msan symbol during LTO. + let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new("__msan_track_origins")); + symbols.push((exported_symbol, SymbolExportLevel::C)); + } + if tcx.sess.crate_types.borrow().contains(&config::CrateType::Dylib) { let symbol_name = metadata_symbol_name(tcx); let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(&symbol_name)); diff --git a/src/test/codegen/sanitizer-memory-track-orgins.rs b/src/test/codegen/sanitizer-memory-track-orgins.rs index fd8be0bced796..1fd496b35dfcc 100644 --- a/src/test/codegen/sanitizer-memory-track-orgins.rs +++ b/src/test/codegen/sanitizer-memory-track-orgins.rs @@ -4,17 +4,21 @@ // needs-sanitizer-support // only-linux // only-x86_64 -// revisions:MSAN-0 MSAN-1 MSAN-2 +// revisions:MSAN-0 MSAN-1 MSAN-2 MSAN-1-LTO MSAN-2-LTO // //[MSAN-0] compile-flags: -Zsanitizer=memory //[MSAN-1] compile-flags: -Zsanitizer=memory -Zsanitizer-memory-track-origins=1 //[MSAN-2] compile-flags: -Zsanitizer=memory -Zsanitizer-memory-track-origins +//[MSAN-1-LTO] compile-flags: -Zsanitizer=memory -Zsanitizer-memory-track-origins=1 -C lto=fat +//[MSAN-2-LTO] compile-flags: -Zsanitizer=memory -Zsanitizer-memory-track-origins -C lto=fat #![crate_type="lib"] // MSAN-0-NOT: @__msan_track_origins // MSAN-1: @__msan_track_origins = weak_odr local_unnamed_addr constant i32 1 // MSAN-2: @__msan_track_origins = weak_odr local_unnamed_addr constant i32 2 +// MSAN-1-LTO: @__msan_track_origins = weak_odr local_unnamed_addr constant i32 1 +// MSAN-2-LTO: @__msan_track_origins = weak_odr local_unnamed_addr constant i32 2 // // MSAN-0-LABEL: define void @copy( // MSAN-1-LABEL: define void @copy( From d8c661a88644ad710e309d3a8f0f27c5f74d705f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Tue, 21 Jan 2020 00:00:00 +0000 Subject: [PATCH 04/14] Mark __msan_keep_going as an exported symbol for LTO --- .../back/symbol_export.rs | 8 ++- src/test/codegen/sanitizer-recover.rs | 56 ++++++++++++------- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index c5989748560ce..d680e14bbbd5b 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -208,8 +208,12 @@ fn exported_symbols_provider_local( if let Some(Sanitizer::Memory) = tcx.sess.opts.debugging_opts.sanitizer { // Similar to profiling, preserve weak msan symbol during LTO. - let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new("__msan_track_origins")); - symbols.push((exported_symbol, SymbolExportLevel::C)); + const MSAN_WEAK_SYMBOLS: [&str; 2] = ["__msan_track_origins", "__msan_keep_going"]; + + symbols.extend(MSAN_WEAK_SYMBOLS.iter().map(|sym| { + let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(sym)); + (exported_symbol, SymbolExportLevel::C) + })); } if tcx.sess.crate_types.borrow().contains(&config::CrateType::Dylib) { diff --git a/src/test/codegen/sanitizer-recover.rs b/src/test/codegen/sanitizer-recover.rs index a292332667b54..9a583725b0bf0 100644 --- a/src/test/codegen/sanitizer-recover.rs +++ b/src/test/codegen/sanitizer-recover.rs @@ -4,31 +4,47 @@ // needs-sanitizer-support // only-linux // only-x86_64 -// revisions:ASAN ASAN-RECOVER MSAN MSAN-RECOVER +// revisions:ASAN ASAN-RECOVER MSAN MSAN-RECOVER MSAN-RECOVER-LTO +// no-prefer-dynamic // -//[ASAN] compile-flags: -Zsanitizer=address -//[ASAN-RECOVER] compile-flags: -Zsanitizer=address -Zsanitizer-recover=address -//[MSAN] compile-flags: -Zsanitizer=memory -//[MSAN-RECOVER] compile-flags: -Zsanitizer=memory -Zsanitizer-recover=memory - -#![crate_type="lib"] +//[ASAN] compile-flags: -Zsanitizer=address +//[ASAN-RECOVER] compile-flags: -Zsanitizer=address -Zsanitizer-recover=address +//[MSAN] compile-flags: -Zsanitizer=memory +//[MSAN-RECOVER] compile-flags: -Zsanitizer=memory -Zsanitizer-recover=memory +//[MSAN-RECOVER-LTO] compile-flags: -Zsanitizer=memory -Zsanitizer-recover=memory -C lto=fat +// +// MSAN-NOT: @__msan_keep_going +// MSAN-RECOVER: @__msan_keep_going = weak_odr {{.*}} constant i32 1 +// MSAN-RECOVER-LTO: @__msan_keep_going = weak_odr {{.*}} constant i32 1 -// ASAN-LABEL: define i32 @penguin( +// ASAN-LABEL: define i32 @penguin( +// ASAN: call void @__asan_report_load4(i64 %0) +// ASAN: unreachable +// ASAN: } +// // ASAN-RECOVER-LABEL: define i32 @penguin( -// MSAN-LABEL: define i32 @penguin( +// ASAN-RECOVER: call void @__asan_report_load4_noabort( +// ASAN-RECOVER-NOT: unreachable +// ASAN: } +// +// MSAN-LABEL: define i32 @penguin( +// MSAN: call void @__msan_warning_noreturn() +// MSAN: unreachable +// MSAN: } +// // MSAN-RECOVER-LABEL: define i32 @penguin( +// MSAN-RECOVER: call void @__msan_warning() +// MSAN-RECOVER-NOT: unreachable +// MSAN-RECOVER: } +// +// MSAN-RECOVER-LTO-LABEL: define i32 @penguin( +// MSAN-RECOVER-LTO: call void @__msan_warning() +// MSAN-RECOVER-LTO-NOT: unreachable +// MSAN-RECOVER-LTO: } +// #[no_mangle] pub fn penguin(p: &mut i32) -> i32 { - // ASAN: call void @__asan_report_load4(i64 %0) - // ASAN: unreachable - // - // ASAN-RECOVER: call void @__asan_report_load4_noabort( - // ASAN-RECOVER-NOT: unreachable - // - // MSAN: call void @__msan_warning_noreturn() - // MSAN: unreachable - // - // MSAN-RECOVER: call void @__msan_warning() - // MSAN-RECOVER-NOT: unreachable *p } + +fn main() {} From dd0507c054ea27ae836025761908d339a478e0ab Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 20 Jan 2020 15:22:12 +0000 Subject: [PATCH 05/14] Make `TooGeneric` error in WF checking a proper error `TooGeneric` is encountered during WF checking when we cannot determine that a constant involving a generic parameter will always be evaluated successfully (rather than resulting in an error). In these cases, the burden of proof should be with the caller, so that we can avoid post-monomorphisation tim errors (which was the previous previous behaviour). This commit ensures that this situation produces a proper compiler error, rather than silently ignoring it or ICEing. --- src/librustc/traits/error_reporting/mod.rs | 34 +++++++++++++------ .../array-size-in-generic-struct-param.rs | 7 ++-- .../array-size-in-generic-struct-param.stderr | 20 ++++++++++- 3 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs index 646cb80bffd94..f3dc79f0ff6b2 100644 --- a/src/librustc/traits/error_reporting/mod.rs +++ b/src/librustc/traits/error_reporting/mod.rs @@ -914,17 +914,29 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { report_object_safety_error(self.tcx, span, did, violations) } - // already reported in the query - ConstEvalFailure(err) => { - if let ErrorHandled::TooGeneric = err { - // Silence this error, as it can be produced during intermediate steps - // when a constant is not yet able to be evaluated (but will be later). - return; - } - self.tcx.sess.delay_span_bug( - span, - &format!("constant in type had an ignored error: {:?}", err), - ); + ConstEvalFailure(ErrorHandled::TooGeneric) => { + // In this instance, we have a const expression containing an unevaluated + // generic parameter. We have no idea whether this expression is valid or + // not (e.g. it might result in an error), but we don't want to just assume + // that it's okay, because that might result in post-monomorphisation time + // errors. The onus is really on the caller to provide values that it can + // prove are well-formed. + let mut err = self + .tcx + .sess + .struct_span_err(span, "constant expression depends on a generic parameter"); + // FIXME(const_generics): we should suggest to the user how they can resolve this + // issue. However, this is currently not actually possible + // (see https://github.com/rust-lang/rust/issues/66962#issuecomment-575907083). + err.note("this may fail depending on what value the parameter takes"); + err + } + + // Already reported in the query. + ConstEvalFailure(ErrorHandled::Reported) => { + self.tcx + .sess + .delay_span_bug(span, &format!("constant in type had an ignored error")); return; } diff --git a/src/test/ui/const-generics/array-size-in-generic-struct-param.rs b/src/test/ui/const-generics/array-size-in-generic-struct-param.rs index f3be7b56db589..d996bf56fcc10 100644 --- a/src/test/ui/const-generics/array-size-in-generic-struct-param.rs +++ b/src/test/ui/const-generics/array-size-in-generic-struct-param.rs @@ -1,10 +1,9 @@ -// run-pass - #![feature(const_generics)] //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash #[allow(dead_code)] -struct ArithArrayLen([u32; 0 + N]); // ok +struct ArithArrayLen([u32; 0 + N]); +//~^ ERROR constant expression depends on a generic parameter #[derive(PartialEq, Eq)] struct Config { @@ -12,7 +11,7 @@ struct Config { } struct B { - arr: [u8; CFG.arr_size], // ok + arr: [u8; CFG.arr_size], //~ ERROR constant expression depends on a generic parameter } const C: Config = Config { arr_size: 5 }; diff --git a/src/test/ui/const-generics/array-size-in-generic-struct-param.stderr b/src/test/ui/const-generics/array-size-in-generic-struct-param.stderr index 274f97697029e..6ae70c493b1dd 100644 --- a/src/test/ui/const-generics/array-size-in-generic-struct-param.stderr +++ b/src/test/ui/const-generics/array-size-in-generic-struct-param.stderr @@ -1,8 +1,26 @@ warning: the feature `const_generics` is incomplete and may cause the compiler to crash - --> $DIR/array-size-in-generic-struct-param.rs:3:12 + --> $DIR/array-size-in-generic-struct-param.rs:1:12 | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ | = note: `#[warn(incomplete_features)]` on by default +error: constant expression depends on a generic parameter + --> $DIR/array-size-in-generic-struct-param.rs:5:38 + | +LL | struct ArithArrayLen([u32; 0 + N]); + | ^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: constant expression depends on a generic parameter + --> $DIR/array-size-in-generic-struct-param.rs:14:5 + | +LL | arr: [u8; CFG.arr_size], + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to 2 previous errors + From 8abbd0beae79de5186158a759b08cb73d175b5ad Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 21 Jan 2020 17:18:37 +0100 Subject: [PATCH 06/14] for now, do not build rust-std for the armv7a-none-eabihf target it needs some upstream changes in the build script of the compiler-builtins crate --- src/ci/docker/dist-various-1/Dockerfile | 3 ++- src/tools/build-manifest/src/main.rs | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile index 9da18d600ba2f..2a68a25be21b3 100644 --- a/src/ci/docker/dist-various-1/Dockerfile +++ b/src/ci/docker/dist-various-1/Dockerfile @@ -161,7 +161,6 @@ ENV TARGETS=$TARGETS,armv7r-none-eabi ENV TARGETS=$TARGETS,armv7r-none-eabihf ENV TARGETS=$TARGETS,thumbv7neon-unknown-linux-gnueabihf ENV TARGETS=$TARGETS,armv7a-none-eabi -ENV TARGETS=$TARGETS,armv7a-none-eabihf # riscv targets currently do not need a C compiler, as compiler_builtins # doesn't currently have it enabled, and the riscv gcc compiler is not @@ -177,6 +176,8 @@ ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \ CXX_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-g++ \ CC_armv7a_none_eabi=arm-none-eabi-gcc \ CC_armv7a_none_eabihf=arm-none-eabi-gcc \ + CFLAGS_armv7a_none_eabi=-march=armv7-a \ + CFLAGS_armv7a_none_eabihf=-march=armv7-a+vfpv3 \ CC_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-gcc \ AR_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-ar \ CXX_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-g++ \ diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 8281d20e4c886..c8d6580f7a1a5 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -70,7 +70,6 @@ static TARGETS: &[&str] = &[ "armv7-unknown-linux-gnueabi", "armv7-unknown-linux-gnueabihf", "armv7a-none-eabi", - "armv7a-none-eabihf", "thumbv7neon-unknown-linux-gnueabihf", "armv7-unknown-linux-musleabi", "armv7-unknown-linux-musleabihf", From 5dee7dddf24a022184a743b714b5062e83516a87 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Tue, 21 Jan 2020 21:49:23 +0100 Subject: [PATCH 07/14] Handle methods in try diagnostic The diagnostic for diagnostic for methods and trait provided methods would only show the empty string: error[E0277]: the `?` operator can only be used in that returns `Result` or `Option` (or another type that implements `std::ops::Try`) Handle the missing cases so it reads ``a method'' / ``an async method'' / ``a trait method'' respectively. Signed-off-by: Philipp Gesang --- .../traits/error_reporting/on_unimplemented.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/librustc/traits/error_reporting/on_unimplemented.rs b/src/librustc/traits/error_reporting/on_unimplemented.rs index 9f3fc91548b21..8f55540cae38a 100644 --- a/src/librustc/traits/error_reporting/on_unimplemented.rs +++ b/src/librustc/traits/error_reporting/on_unimplemented.rs @@ -67,6 +67,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "a function" }) }) + } else if let hir::Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Method(_, hir::TraitMethod::Provided(body_id)), + .. + }) = &node + { + self.describe_generator(*body_id).or_else(|| Some("a trait method")) + } else if let hir::Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::Method(sig, body_id), + .. + }) = &node + { + self.describe_generator(*body_id).or_else(|| { + Some(if let hir::FnHeader { asyncness: hir::IsAsync::Async, .. } = sig.header { + "an async method" + } else { + "a method" + }) + }) } else if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(_is_move, _, body_id, _, gen_movability), .. From 02e66baac6882ef30e607d2bca98929f01758957 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Tue, 21 Jan 2020 21:51:13 +0100 Subject: [PATCH 08/14] Test try diagnostics for impl and trait methods Signed-off-by: Philipp Gesang --- src/test/ui/try-on-option-diagnostics.rs | 29 ++++++++++++++++++++ src/test/ui/try-on-option-diagnostics.stderr | 28 ++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/test/ui/try-on-option-diagnostics.rs b/src/test/ui/try-on-option-diagnostics.rs index 65d5e29ec2f13..63d17414c313b 100644 --- a/src/test/ui/try-on-option-diagnostics.rs +++ b/src/test/ui/try-on-option-diagnostics.rs @@ -16,3 +16,32 @@ fn a_closure() -> u32 { }; a_closure() } + +fn a_method() -> u32 { + struct S; + + impl S { + fn a_method() { + let x: Option = None; + x?; //~ ERROR the `?` operator + } + } + + S::a_method(); + 22 +} + +fn a_trait_method() -> u32 { + struct S; + trait T { + fn a_trait_method() { + let x: Option = None; + x?; //~ ERROR the `?` operator + } + } + + impl T for S { } + + S::a_trait_method(); + 22 +} diff --git a/src/test/ui/try-on-option-diagnostics.stderr b/src/test/ui/try-on-option-diagnostics.stderr index ce3aca39fb8fb..c9dc3f1b87969 100644 --- a/src/test/ui/try-on-option-diagnostics.stderr +++ b/src/test/ui/try-on-option-diagnostics.stderr @@ -27,6 +27,32 @@ LL | | }; = help: the trait `std::ops::Try` is not implemented for `{integer}` = note: required by `std::ops::Try::from_error` -error: aborting due to 2 previous errors +error[E0277]: the `?` operator can only be used in a method that returns `Result` or `Option` (or another type that implements `std::ops::Try`) + --> $DIR/try-on-option-diagnostics.rs:26:13 + | +LL | / fn a_method() { +LL | | let x: Option = None; +LL | | x?; + | | ^^ cannot use the `?` operator in a method that returns `()` +LL | | } + | |_________- this function should return `Result` or `Option` to accept `?` + | + = help: the trait `std::ops::Try` is not implemented for `()` + = note: required by `std::ops::Try::from_error` + +error[E0277]: the `?` operator can only be used in a trait method that returns `Result` or `Option` (or another type that implements `std::ops::Try`) + --> $DIR/try-on-option-diagnostics.rs:39:13 + | +LL | / fn a_trait_method() { +LL | | let x: Option = None; +LL | | x?; + | | ^^ cannot use the `?` operator in a trait method that returns `()` +LL | | } + | |_________- this function should return `Result` or `Option` to accept `?` + | + = help: the trait `std::ops::Try` is not implemented for `()` + = note: required by `std::ops::Try::from_error` + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. From db3b40c2a1fe6129a7bbc12df6260b7197731153 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Tue, 21 Jan 2020 21:46:38 +0100 Subject: [PATCH 09/14] Cleanup: rewrite conditional as match As suggested by @Centril. Signed-off-by: Philipp Gesang --- .../error_reporting/on_unimplemented.rs | 66 +++++++++---------- 1 file changed, 31 insertions(+), 35 deletions(-) diff --git a/src/librustc/traits/error_reporting/on_unimplemented.rs b/src/librustc/traits/error_reporting/on_unimplemented.rs index 8f55540cae38a..2ba12baaf6d6e 100644 --- a/src/librustc/traits/error_reporting/on_unimplemented.rs +++ b/src/librustc/traits/error_reporting/on_unimplemented.rs @@ -59,49 +59,45 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { fn describe_enclosure(&self, hir_id: hir::HirId) -> Option<&'static str> { let hir = &self.tcx.hir(); let node = hir.find(hir_id)?; - if let hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. }) = &node { - self.describe_generator(*body_id).or_else(|| { - Some(if let hir::FnHeader { asyncness: hir::IsAsync::Async, .. } = sig.header { - "an async function" - } else { - "a function" + match &node { + hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. }) => { + self.describe_generator(*body_id).or_else(|| { + Some(if let hir::FnHeader { asyncness: hir::IsAsync::Async, .. } = sig.header { + "an async function" + } else { + "a function" + }) }) - }) - } else if let hir::Node::TraitItem(hir::TraitItem { - kind: hir::TraitItemKind::Method(_, hir::TraitMethod::Provided(body_id)), - .. - }) = &node - { - self.describe_generator(*body_id).or_else(|| Some("a trait method")) - } else if let hir::Node::ImplItem(hir::ImplItem { - kind: hir::ImplItemKind::Method(sig, body_id), - .. - }) = &node - { - self.describe_generator(*body_id).or_else(|| { + } + hir::Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Method(_, hir::TraitMethod::Provided(body_id)), + .. + }) => self.describe_generator(*body_id).or_else(|| Some("a trait method")), + hir::Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::Method(sig, body_id), + .. + }) => self.describe_generator(*body_id).or_else(|| { Some(if let hir::FnHeader { asyncness: hir::IsAsync::Async, .. } = sig.header { "an async method" } else { "a method" }) - }) - } else if let hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Closure(_is_move, _, body_id, _, gen_movability), - .. - }) = &node - { - self.describe_generator(*body_id).or_else(|| { + }), + hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Closure(_is_move, _, body_id, _, gen_movability), + .. + }) => self.describe_generator(*body_id).or_else(|| { Some(if gen_movability.is_some() { "an async closure" } else { "a closure" }) - }) - } else if let hir::Node::Expr(hir::Expr { .. }) = &node { - let parent_hid = hir.get_parent_node(hir_id); - if parent_hid != hir_id { - return self.describe_enclosure(parent_hid); - } else { - None + }), + hir::Node::Expr(hir::Expr { .. }) => { + let parent_hid = hir.get_parent_node(hir_id); + if parent_hid != hir_id { + return self.describe_enclosure(parent_hid); + } else { + None + } } - } else { - None + _ => None, } } From d1bb7e16e0d0ad4e568df14eceedc5b0dd484214 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 21 Jan 2020 09:50:22 -0500 Subject: [PATCH 10/14] Privatize private fields of OutputFilenames --- src/librustc_interface/util.rs | 33 ++++++++++++++------------------- src/librustc_session/config.rs | 14 ++++++++++++-- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 21f9fa4816591..3e65da9c47b7e 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -550,13 +550,13 @@ pub fn build_output_filenames( .or_else(|| attr::find_crate_name(attrs).map(|n| n.to_string())) .unwrap_or_else(|| input.filestem().to_owned()); - OutputFilenames { - out_directory: dirpath, - out_filestem: stem, - single_output_file: None, - extra: sess.opts.cg.extra_filename.clone(), - outputs: sess.opts.output_types.clone(), - } + OutputFilenames::new( + dirpath, + stem, + None, + sess.opts.cg.extra_filename.clone(), + sess.opts.output_types.clone(), + ) } Some(ref out_file) => { @@ -578,18 +578,13 @@ pub fn build_output_filenames( sess.warn("ignoring --out-dir flag due to -o flag"); } - OutputFilenames { - out_directory: out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(), - out_filestem: out_file - .file_stem() - .unwrap_or_default() - .to_str() - .unwrap() - .to_string(), - single_output_file: ofile, - extra: sess.opts.cg.extra_filename.clone(), - outputs: sess.opts.output_types.clone(), - } + OutputFilenames::new( + out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(), + out_file.file_stem().unwrap_or_default().to_str().unwrap().to_string(), + ofile, + sess.opts.cg.extra_filename.clone(), + sess.opts.output_types.clone(), + ) } } } diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index b6b22e298ca62..08960cd44984b 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -447,9 +447,9 @@ impl Input { #[derive(Clone, Hash)] pub struct OutputFilenames { pub out_directory: PathBuf, - pub out_filestem: String, + out_filestem: String, pub single_output_file: Option, - pub extra: String, + extra: String, pub outputs: OutputTypes, } @@ -458,6 +458,16 @@ impl_stable_hash_via_hash!(OutputFilenames); pub const RUST_CGU_EXT: &str = "rcgu"; impl OutputFilenames { + pub fn new( + out_directory: PathBuf, + out_filestem: String, + single_output_file: Option, + extra: String, + outputs: OutputTypes, + ) -> Self { + OutputFilenames { out_directory, out_filestem, single_output_file, extra, outputs } + } + pub fn path(&self, flavor: OutputType) -> PathBuf { self.outputs .get(&flavor) From 8c6067c24e181aa388619ca0f39100e5c9a1f509 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 21 Jan 2020 09:54:58 -0500 Subject: [PATCH 11/14] Store filestem in a pre-formatted form --- src/librustc_session/config.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index 08960cd44984b..81e8e47445859 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -447,9 +447,8 @@ impl Input { #[derive(Clone, Hash)] pub struct OutputFilenames { pub out_directory: PathBuf, - out_filestem: String, + filestem: String, pub single_output_file: Option, - extra: String, pub outputs: OutputTypes, } @@ -465,7 +464,12 @@ impl OutputFilenames { extra: String, outputs: OutputTypes, ) -> Self { - OutputFilenames { out_directory, out_filestem, single_output_file, extra, outputs } + OutputFilenames { + out_directory, + single_output_file, + outputs, + filestem: format!("{}{}", out_filestem, extra), + } } pub fn path(&self, flavor: OutputType) -> PathBuf { @@ -487,7 +491,7 @@ impl OutputFilenames { /// Like temp_path, but also supports things where there is no corresponding /// OutputType, like noopt-bitcode or lto-bitcode. pub fn temp_path_ext(&self, ext: &str, codegen_unit_name: Option<&str>) -> PathBuf { - let base = self.out_directory.join(&self.filestem()); + let base = self.out_directory.join(&self.filestem); let mut extension = String::new(); @@ -505,16 +509,11 @@ impl OutputFilenames { extension.push_str(ext); } - let path = base.with_extension(&extension[..]); - path + base.with_extension(extension) } pub fn with_extension(&self, extension: &str) -> PathBuf { - self.out_directory.join(&self.filestem()).with_extension(extension) - } - - pub fn filestem(&self) -> String { - format!("{}{}", self.out_filestem, self.extra) + self.out_directory.join(&self.filestem).with_extension(extension) } } From dc97181a0966cd1686a70ce06849a19c196f72eb Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 21 Jan 2020 09:57:50 -0500 Subject: [PATCH 12/14] Do not base path to append extension We already have ownership of the base path, so no need to clone it (within Path::with_extension). --- src/librustc_session/config.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index 81e8e47445859..c7fcd04c45a0a 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -491,8 +491,6 @@ impl OutputFilenames { /// Like temp_path, but also supports things where there is no corresponding /// OutputType, like noopt-bitcode or lto-bitcode. pub fn temp_path_ext(&self, ext: &str, codegen_unit_name: Option<&str>) -> PathBuf { - let base = self.out_directory.join(&self.filestem); - let mut extension = String::new(); if let Some(codegen_unit_name) = codegen_unit_name { @@ -509,11 +507,13 @@ impl OutputFilenames { extension.push_str(ext); } - base.with_extension(extension) + self.with_extension(&extension) } pub fn with_extension(&self, extension: &str) -> PathBuf { - self.out_directory.join(&self.filestem).with_extension(extension) + let mut path = self.out_directory.join(&self.filestem); + path.set_extension(extension); + path } } From eb2da27af27c010bf5501bbe85341ccd457dc3d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Wed, 22 Jan 2020 01:02:32 +0100 Subject: [PATCH 13/14] bootstrap: update clippy subcmd decription Clarify where the clippy used in `./x.py clippy` is coming from. It uses whatever clippy binary was installed via rustup, cargo-install or otherwise and does NOT use the binary generated by `./x.py build src/tools/clippy`. --- src/bootstrap/flags.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 1fbdd50a51133..2101ef27f9d42 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -104,7 +104,7 @@ Usage: x.py [options] [...] Subcommands: build Compile either the compiler or libraries check Compile either the compiler or libraries, using cargo check - clippy Run clippy + clippy Run clippy (uses rustup/cargo-installed clippy binary) fix Run cargo fix fmt Run rustfmt test Build and run some test suites From 7962ccb216e993b52f67986f7944fba5fc38482c Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 22 Jan 2020 01:38:05 +0100 Subject: [PATCH 14/14] pprust: use as_deref --- src/libsyntax/print/pprust.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index bc67980c454c0..6b21224b9b64c 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1643,7 +1643,7 @@ impl<'a> State<'a> { self.print_expr_as_cond(i); self.s.space(); self.print_block(then); - self.print_else(e.as_ref().map(|e| &**e)) + self.print_else(e.as_deref()) } // Final `else` block. ast::ExprKind::Block(ref b, _) => { @@ -1947,7 +1947,7 @@ impl<'a> State<'a> { self.print_let(pat, scrutinee); } ast::ExprKind::If(ref test, ref blk, ref elseopt) => { - self.print_if(test, blk, elseopt.as_ref().map(|e| &**e)); + self.print_if(test, blk, elseopt.as_deref()) } ast::ExprKind::While(ref test, ref blk, opt_label) => { if let Some(label) = opt_label {