Auto merge of #68474 - tmandry:rollup-6gmbet6, r=tmandry
Rollup of 10 pull requests Successful merges: - #67195 ([experiment] Add `-Z no-link` flag) - #68253 (add bare metal ARM Cortex-A targets to rustc) - #68361 (Unbreak linking with lld 9 on FreeBSD 13.0-CURRENT i386) - #68388 (Make `TooGeneric` error in WF checking a proper error) - #68409 (Micro-optimize OutputFilenames) - #68410 (Export weak symbols used by MemorySanitizer) - #68425 (Fix try-op diagnostic in E0277 for methods) - #68440 (bootstrap: update clippy subcmd decription) - #68441 (pprust: use as_deref) - #68462 (librustc_mir: don't allocate vectors where slices will do.) Failed merges: r? @ghost
This commit is contained in:
commit
e23dd6687f
@ -3428,6 +3428,7 @@ dependencies = [
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"serialize",
|
||||
"smallvec 1.0.0",
|
||||
"syntax",
|
||||
]
|
||||
|
@ -104,7 +104,7 @@ Usage: x.py <subcommand> [options] [<paths>...]
|
||||
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
|
||||
|
@ -160,6 +160,7 @@ 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
|
||||
|
||||
# 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
|
||||
@ -173,6 +174,10 @@ 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 \
|
||||
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++ \
|
||||
|
@ -27,7 +27,7 @@ pub use rustc_session::utils::NativeLibraryKind;
|
||||
|
||||
/// Where a crate came from on the local filesystem. One of these three options
|
||||
/// must be non-None.
|
||||
#[derive(PartialEq, Clone, Debug, HashStable)]
|
||||
#[derive(PartialEq, Clone, Debug, HashStable, RustcEncodable, RustcDecodable)]
|
||||
pub struct CrateSource {
|
||||
pub dylib: Option<(PathBuf, PathKind)>,
|
||||
pub rlib: Option<(PathBuf, PathKind)>,
|
||||
@ -75,7 +75,7 @@ impl DepKind {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
#[derive(PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub enum LibSource {
|
||||
Some(PathBuf),
|
||||
MetadataOnly,
|
||||
@ -160,6 +160,7 @@ pub enum ExternCrateSource {
|
||||
Path,
|
||||
}
|
||||
|
||||
#[derive(RustcEncodable, RustcDecodable)]
|
||||
pub struct EncodedMetadata {
|
||||
pub raw_data: Vec<u8>,
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ pub type DependencyList = Vec<Linkage>;
|
||||
/// This is local to the tcx, and is generally relevant to one session.
|
||||
pub type Dependencies = Vec<(config::CrateType, DependencyList)>;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug, HashStable)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug, HashStable, RustcEncodable, RustcDecodable)]
|
||||
pub enum Linkage {
|
||||
NotLinked,
|
||||
IncludedFromDylib,
|
||||
|
@ -919,17 +919,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;
|
||||
}
|
||||
|
||||
|
@ -59,31 +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::Expr(hir::Expr {
|
||||
kind: hir::ExprKind::Closure(_is_move, _, body_id, _, gen_movability),
|
||||
..
|
||||
}) = &node
|
||||
{
|
||||
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
|
||||
}
|
||||
} else {
|
||||
None
|
||||
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"
|
||||
})
|
||||
}),
|
||||
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" })
|
||||
}),
|
||||
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
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ rustc_incremental = { path = "../librustc_incremental" }
|
||||
rustc_index = { path = "../librustc_index" }
|
||||
rustc_llvm = { path = "../librustc_llvm" }
|
||||
rustc_session = { path = "../librustc_session" }
|
||||
rustc_serialize = { path = "../libserialize", package = "serialize" }
|
||||
rustc_target = { path = "../librustc_target" }
|
||||
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
|
||||
syntax = { path = "../libsyntax" }
|
||||
|
@ -33,6 +33,7 @@ use rustc_codegen_ssa::CompiledModule;
|
||||
use rustc_errors::{FatalError, Handler};
|
||||
use std::any::Any;
|
||||
use std::ffi::CStr;
|
||||
use std::fs;
|
||||
use std::sync::Arc;
|
||||
use syntax::expand::allocator::AllocatorKind;
|
||||
|
||||
@ -44,6 +45,7 @@ use rustc::ty::{self, TyCtxt};
|
||||
use rustc::util::common::ErrorReported;
|
||||
use rustc_codegen_ssa::ModuleCodegen;
|
||||
use rustc_codegen_utils::codegen_backend::CodegenBackend;
|
||||
use rustc_serialize::json;
|
||||
|
||||
mod back {
|
||||
pub mod archive;
|
||||
@ -298,6 +300,18 @@ impl CodegenBackend for LlvmCodegenBackend {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if sess.opts.debugging_opts.no_link {
|
||||
// FIXME: use a binary format to encode the `.rlink` file
|
||||
let rlink_data = json::encode(&codegen_results).map_err(|err| {
|
||||
sess.fatal(&format!("failed to encode rlink: {}", err));
|
||||
})?;
|
||||
let rlink_file = outputs.with_extension("rlink");
|
||||
fs::write(&rlink_file, rlink_data).map_err(|err| {
|
||||
sess.fatal(&format!("failed to write file {}: {}", rlink_file.display(), err));
|
||||
})?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Run the linker on any artifacts that resulted from the LLVM run.
|
||||
// This should produce either a finished executable or library.
|
||||
sess.time("link_crate", || {
|
||||
|
@ -20,6 +20,7 @@ use rustc_target::spec::{LinkerFlavor, LldFlavor};
|
||||
|
||||
/// For all the linkers we support, and information they might
|
||||
/// need out of the shared crate context before we get rid of it.
|
||||
#[derive(RustcEncodable, RustcDecodable)]
|
||||
pub struct LinkerInfo {
|
||||
exports: FxHashMap<CrateType, Vec<String>>,
|
||||
}
|
||||
|
@ -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,16 @@ 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.
|
||||
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) {
|
||||
let symbol_name = metadata_symbol_name(tcx);
|
||||
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(&symbol_name));
|
||||
|
@ -87,7 +87,7 @@ impl<M> ModuleCodegen<M> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, RustcEncodable, RustcDecodable)]
|
||||
pub struct CompiledModule {
|
||||
pub name: String,
|
||||
pub kind: ModuleKind,
|
||||
@ -101,7 +101,7 @@ pub struct CachedModuleCodegen {
|
||||
pub source: WorkProduct,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
|
||||
pub enum ModuleKind {
|
||||
Regular,
|
||||
Metadata,
|
||||
@ -117,7 +117,14 @@ bitflags::bitflags! {
|
||||
}
|
||||
|
||||
/// Misc info we load from metadata to persist beyond the tcx.
|
||||
#[derive(Debug)]
|
||||
///
|
||||
/// Note: though `CrateNum` is only meaningful within the same tcx, information within `CrateInfo`
|
||||
/// is self-contained. `CrateNum` can be viewed as a unique identifier within a `CrateInfo`, where
|
||||
/// `used_crate_source` contains all `CrateSource` of the dependents, and maintains a mapping from
|
||||
/// identifiers (`CrateNum`) to `CrateSource`. The other fields map `CrateNum` to the crate's own
|
||||
/// additional properties, so that effectively we can retrieve each dependent crate's `CrateSource`
|
||||
/// and the corresponding properties without referencing information outside of a `CrateInfo`.
|
||||
#[derive(Debug, RustcEncodable, RustcDecodable)]
|
||||
pub struct CrateInfo {
|
||||
pub panic_runtime: Option<CrateNum>,
|
||||
pub compiler_builtins: Option<CrateNum>,
|
||||
@ -135,6 +142,7 @@ pub struct CrateInfo {
|
||||
pub dependency_formats: Lrc<Dependencies>,
|
||||
}
|
||||
|
||||
#[derive(RustcEncodable, RustcDecodable)]
|
||||
pub struct CodegenResults {
|
||||
pub crate_name: Symbol,
|
||||
pub modules: Vec<CompiledModule>,
|
||||
|
@ -1,7 +1,8 @@
|
||||
use rustc_data_structures::AtomicRef;
|
||||
use rustc_index::vec::Idx;
|
||||
use rustc_serialize::{Decoder, Encoder};
|
||||
use std::fmt;
|
||||
use std::u32;
|
||||
use std::{u32, u64};
|
||||
|
||||
rustc_index::newtype_index! {
|
||||
pub struct CrateId {
|
||||
@ -86,8 +87,18 @@ impl fmt::Display for CrateNum {
|
||||
}
|
||||
}
|
||||
|
||||
impl rustc_serialize::UseSpecializedEncodable for CrateNum {}
|
||||
impl rustc_serialize::UseSpecializedDecodable for CrateNum {}
|
||||
/// As a local identifier, a `CrateNum` is only meaningful within its context, e.g. within a tcx.
|
||||
/// Therefore, make sure to include the context when encode a `CrateNum`.
|
||||
impl rustc_serialize::UseSpecializedEncodable for CrateNum {
|
||||
fn default_encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
|
||||
e.emit_u32(self.as_u32())
|
||||
}
|
||||
}
|
||||
impl rustc_serialize::UseSpecializedDecodable for CrateNum {
|
||||
fn default_decode<D: Decoder>(d: &mut D) -> Result<CrateNum, D::Error> {
|
||||
Ok(CrateNum::from_u32(d.read_u32()?))
|
||||
}
|
||||
}
|
||||
|
||||
rustc_index::newtype_index! {
|
||||
/// A DefIndex is an index into the hir-map for a crate, identifying a
|
||||
@ -135,8 +146,21 @@ impl DefId {
|
||||
}
|
||||
}
|
||||
|
||||
impl rustc_serialize::UseSpecializedEncodable for DefId {}
|
||||
impl rustc_serialize::UseSpecializedDecodable for DefId {}
|
||||
impl rustc_serialize::UseSpecializedEncodable for DefId {
|
||||
fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
let krate = u64::from(self.krate.as_u32());
|
||||
let index = u64::from(self.index.as_u32());
|
||||
s.emit_u64((krate << 32) | index)
|
||||
}
|
||||
}
|
||||
impl rustc_serialize::UseSpecializedDecodable for DefId {
|
||||
fn default_decode<D: Decoder>(d: &mut D) -> Result<DefId, D::Error> {
|
||||
let def_id = d.read_u64()?;
|
||||
let krate = CrateNum::from_u32((def_id >> 32) as u32);
|
||||
let index = DefIndex::from_u32((def_id & 0xffffffff) as u32);
|
||||
Ok(DefId { krate, index })
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default_def_id_debug(def_id: DefId, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("DefId").field("krate", &def_id.krate).field("index", &def_id.index).finish()
|
||||
|
@ -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(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor<'tcx> {
|
||||
place,
|
||||
Place {
|
||||
local: self_arg(),
|
||||
projection: self.tcx().intern_place_elems(&vec![ProjectionElem::Deref]),
|
||||
projection: self.tcx().intern_place_elems(&[ProjectionElem::Deref]),
|
||||
},
|
||||
self.tcx,
|
||||
);
|
||||
@ -153,7 +153,7 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> {
|
||||
place,
|
||||
Place {
|
||||
local: self_arg(),
|
||||
projection: self.tcx().intern_place_elems(&vec![ProjectionElem::Field(
|
||||
projection: self.tcx().intern_place_elems(&[ProjectionElem::Field(
|
||||
Field::new(0),
|
||||
self.ref_gen_ty,
|
||||
)]),
|
||||
|
@ -51,7 +51,7 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> {
|
||||
let new_place = match rvalue {
|
||||
Rvalue::Ref(_, _, place) => {
|
||||
if let &[ref proj_l @ .., proj_r] = place.projection.as_ref() {
|
||||
place.projection = self.tcx().intern_place_elems(&vec![proj_r.clone()]);
|
||||
place.projection = self.tcx().intern_place_elems(&[proj_r.clone()]);
|
||||
|
||||
Place {
|
||||
// Replace with dummy
|
||||
|
@ -447,9 +447,8 @@ impl Input {
|
||||
#[derive(Clone, Hash)]
|
||||
pub struct OutputFilenames {
|
||||
pub out_directory: PathBuf,
|
||||
pub out_filestem: String,
|
||||
filestem: String,
|
||||
pub single_output_file: Option<PathBuf>,
|
||||
pub extra: String,
|
||||
pub outputs: OutputTypes,
|
||||
}
|
||||
|
||||
@ -458,6 +457,21 @@ 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<PathBuf>,
|
||||
extra: String,
|
||||
outputs: OutputTypes,
|
||||
) -> Self {
|
||||
OutputFilenames {
|
||||
out_directory,
|
||||
single_output_file,
|
||||
outputs,
|
||||
filestem: format!("{}{}", out_filestem, extra),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn path(&self, flavor: OutputType) -> PathBuf {
|
||||
self.outputs
|
||||
.get(&flavor)
|
||||
@ -477,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 {
|
||||
@ -495,16 +507,13 @@ impl OutputFilenames {
|
||||
extension.push_str(ext);
|
||||
}
|
||||
|
||||
let path = base.with_extension(&extension[..]);
|
||||
path
|
||||
self.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)
|
||||
let mut path = self.out_directory.join(&self.filestem);
|
||||
path.set_extension(extension);
|
||||
path
|
||||
}
|
||||
}
|
||||
|
||||
@ -619,7 +628,7 @@ pub enum EntryFnType {
|
||||
|
||||
impl_stable_hash_via_hash!(EntryFnType);
|
||||
|
||||
#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug)]
|
||||
#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub enum CrateType {
|
||||
Executable,
|
||||
Dylib,
|
||||
|
@ -950,4 +950,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
|
||||
(such as entering an empty infinite loop) by inserting llvm.sideeffect"),
|
||||
deduplicate_diagnostics: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
|
||||
"deduplicate identical diagnostics"),
|
||||
no_link: bool = (false, parse_bool, [TRACKED],
|
||||
"compile without linking"),
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ pub struct SearchPath {
|
||||
pub files: Vec<PathBuf>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Copy, Debug, Hash, Eq)]
|
||||
#[derive(PartialEq, Clone, Copy, Debug, Hash, Eq, RustcEncodable, RustcDecodable)]
|
||||
pub enum PathKind {
|
||||
Native,
|
||||
Crate,
|
||||
|
48
src/librustc_target/spec/armv7a_none_eabi.rs
Normal file
48
src/librustc_target/spec/armv7a_none_eabi.rs
Normal file
@ -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<Target, String> {
|
||||
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,
|
||||
})
|
||||
}
|
36
src/librustc_target/spec/armv7a_none_eabihf.rs
Normal file
36
src/librustc_target/spec/armv7a_none_eabihf.rs
Normal file
@ -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<Target, String> {
|
||||
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,
|
||||
})
|
||||
}
|
@ -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 {
|
||||
|
@ -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),
|
||||
|
@ -1645,7 +1645,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, _) => {
|
||||
@ -1949,7 +1949,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 {
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
//[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
|
||||
|
||||
#![crate_type="lib"]
|
||||
|
||||
// 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() {}
|
||||
|
@ -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<const N: usize>([u32; 0 + N]); // ok
|
||||
struct ArithArrayLen<const N: usize>([u32; 0 + N]);
|
||||
//~^ ERROR constant expression depends on a generic parameter
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
struct Config {
|
||||
@ -12,7 +11,7 @@ struct Config {
|
||||
}
|
||||
|
||||
struct B<const CFG: Config> {
|
||||
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 };
|
||||
|
@ -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<const N: usize>([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
|
||||
|
||||
|
@ -16,3 +16,32 @@ fn a_closure() -> u32 {
|
||||
};
|
||||
a_closure()
|
||||
}
|
||||
|
||||
fn a_method() -> u32 {
|
||||
struct S;
|
||||
|
||||
impl S {
|
||||
fn a_method() {
|
||||
let x: Option<u32> = 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<u32> = None;
|
||||
x?; //~ ERROR the `?` operator
|
||||
}
|
||||
}
|
||||
|
||||
impl T for S { }
|
||||
|
||||
S::a_trait_method();
|
||||
22
|
||||
}
|
||||
|
@ -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<u32> = 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<u32> = 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`.
|
||||
|
@ -69,6 +69,7 @@ static TARGETS: &[&str] = &[
|
||||
"thumbv7neon-linux-androideabi",
|
||||
"armv7-unknown-linux-gnueabi",
|
||||
"armv7-unknown-linux-gnueabihf",
|
||||
"armv7a-none-eabi",
|
||||
"thumbv7neon-unknown-linux-gnueabihf",
|
||||
"armv7-unknown-linux-musleabi",
|
||||
"armv7-unknown-linux-musleabihf",
|
||||
|
Loading…
x
Reference in New Issue
Block a user