Auto merge of #56840 - pietroalbini:rollup, r=pietroalbini
Rollup of 14 pull requests Successful merges: - #56718 (Use libbacktrace pretty-printing) - #56725 (fix rust-lang/rust issue #50583) - #56731 (Add missing urls in ffi module docs) - #56738 (Fix private_no_mangle_fns message grammar) - #56746 (Add test of current behavior (infer free region within closure body)) - #56747 (target: remove Box returned by get_targets) - #56751 (Allow ptr::hash to accept fat pointers) - #56755 (Account for `impl Trait` when suggesting lifetime) - #56758 (Add short emoji status to toolstate updates) - #56760 (Deduplicate unsatisfied trait bounds) - #56769 (Add x86_64-unknown-uefi target) - #56792 (Bootstrap: Add testsuite for compiletest tool) - #56808 (Fixes broken links) - #56809 (Fix docs path to PermissionsExt) Failed merges: r? @ghost
This commit is contained in:
commit
0a1b2267e4
12
Cargo.lock
12
Cargo.lock
@ -81,7 +81,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.9"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -728,7 +728,7 @@ name = "error-chain"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -736,7 +736,7 @@ name = "error-chain"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -751,7 +751,7 @@ name = "failure"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -2060,7 +2060,7 @@ name = "rustc"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"arena 0.0.0",
|
||||
"backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -3380,7 +3380,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
|
||||
"checksum assert_cli 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98589b0e465a6c510d95fceebd365bb79bedece7f6e18a480897f2015f85ec51"
|
||||
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
|
||||
"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
|
||||
"checksum backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "18b65ea1161bfb2dd6da6fade5edd4dbd08fba85012123dd333d2fd1b90b2782"
|
||||
"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0"
|
||||
"checksum bit-set 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6f1efcc46c18245a69c38fcc5cc650f16d3a59d034f3106e9ed63748f695730a"
|
||||
"checksum bit-vec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4440d5cb623bb7390ae27fec0bb6c61111969860f8e3ae198bfa0663645e67cf"
|
||||
|
@ -416,6 +416,7 @@ impl<'a> Builder<'a> {
|
||||
test::Rustfmt,
|
||||
test::Miri,
|
||||
test::Clippy,
|
||||
test::CompiletestTest,
|
||||
test::RustdocJS,
|
||||
test::RustdocTheme,
|
||||
// Run bootstrap close to the end as it's unlikely to fail
|
||||
|
@ -429,6 +429,45 @@ impl Step for Miri {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct CompiletestTest {
|
||||
stage: u32,
|
||||
host: Interned<String>,
|
||||
}
|
||||
|
||||
impl Step for CompiletestTest {
|
||||
type Output = ();
|
||||
|
||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||
run.path("src/tools/compiletest")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
run.builder.ensure(CompiletestTest {
|
||||
stage: run.builder.top_stage,
|
||||
host: run.target,
|
||||
});
|
||||
}
|
||||
|
||||
/// Runs `cargo test` for compiletest.
|
||||
fn run(self, builder: &Builder) {
|
||||
let stage = self.stage;
|
||||
let host = self.host;
|
||||
let compiler = builder.compiler(stage, host);
|
||||
|
||||
let mut cargo = tool::prepare_tool_cargo(builder,
|
||||
compiler,
|
||||
Mode::ToolBootstrap,
|
||||
host,
|
||||
"test",
|
||||
"src/tools/compiletest",
|
||||
SourceType::InTree,
|
||||
&[]);
|
||||
|
||||
try_run(builder, &mut cargo);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Clippy {
|
||||
stage: u32,
|
||||
|
@ -52,8 +52,8 @@ RUN env \
|
||||
CXX=arm-linux-gnueabi-g++ CXXFLAGS="-march=armv6 -marm" \
|
||||
bash musl.sh arm && \
|
||||
env \
|
||||
CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv6 -marm" \
|
||||
CXX=arm-linux-gnueabihf-g++ CXXFLAGS="-march=armv6 -marm" \
|
||||
CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv6 -marm -mfpu=vfp" \
|
||||
CXX=arm-linux-gnueabihf-g++ CXXFLAGS="-march=armv6 -marm -mfpu=vfp" \
|
||||
bash musl.sh armhf && \
|
||||
env \
|
||||
CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv7-a" \
|
||||
|
@ -6,5 +6,5 @@ the team is supporting directly.
|
||||
|
||||
To see the list of built-in targets, you can run `rustc --print target-list`,
|
||||
or look at [the API
|
||||
docs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_back/target/#modules).
|
||||
docs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_target/spec/index.html#modules).
|
||||
Each module there defines a builder for a particular target.
|
@ -4,7 +4,7 @@
|
||||
architecture. The list of *targets* are the possible architectures that you can build for.
|
||||
|
||||
To see all the options that you can set with a target, see the docs
|
||||
[here](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_back/target/struct.Target.html).
|
||||
[here](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_target/spec/struct.Target.html).
|
||||
|
||||
To compile to a particular target, use the `--target` flag:
|
||||
|
||||
|
@ -8,7 +8,7 @@ The tracking issue for this feature is: [#48055]
|
||||
|
||||
This implements [RFC1909]. When turned on, you can have unsized arguments and locals:
|
||||
|
||||
[RFC1909]: https://github.com/rust-lang/rfcs/blob/master/text/1909-coercions.md
|
||||
[RFC1909]: https://github.com/rust-lang/rfcs/blob/master/text/1909-unsized-rvalues.md
|
||||
|
||||
```rust
|
||||
#![feature(unsized_locals)]
|
||||
|
@ -2544,7 +2544,7 @@ pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool {
|
||||
/// assert_eq!(actual, expected);
|
||||
/// ```
|
||||
#[unstable(feature = "ptr_hash", reason = "newly added", issue = "56286")]
|
||||
pub fn hash<T, S: hash::Hasher>(hashee: *const T, into: &mut S) {
|
||||
pub fn hash<T: ?Sized, S: hash::Hasher>(hashee: *const T, into: &mut S) {
|
||||
use hash::Hash;
|
||||
hashee.hash(into);
|
||||
}
|
||||
|
@ -1095,7 +1095,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
let sp = hir.span(id);
|
||||
// `sp` only covers `T`, change it so that it covers
|
||||
// `T:` when appropriate
|
||||
let sp = if has_bounds {
|
||||
let is_impl_trait = bound_kind.to_string().starts_with("impl ");
|
||||
let sp = if has_bounds && !is_impl_trait {
|
||||
sp.to(self.tcx
|
||||
.sess
|
||||
.source_map()
|
||||
@ -1103,7 +1104,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
} else {
|
||||
sp
|
||||
};
|
||||
(sp, has_bounds)
|
||||
(sp, has_bounds, is_impl_trait)
|
||||
})
|
||||
} else {
|
||||
None
|
||||
@ -1136,25 +1137,33 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
fn binding_suggestion<'tcx, S: fmt::Display>(
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
type_param_span: Option<(Span, bool)>,
|
||||
type_param_span: Option<(Span, bool, bool)>,
|
||||
bound_kind: GenericKind<'tcx>,
|
||||
sub: S,
|
||||
) {
|
||||
let consider = &format!(
|
||||
"consider adding an explicit lifetime bound `{}: {}`...",
|
||||
bound_kind, sub
|
||||
let consider = format!(
|
||||
"consider adding an explicit lifetime bound {}",
|
||||
if type_param_span.map(|(_, _, is_impl_trait)| is_impl_trait).unwrap_or(false) {
|
||||
format!(" `{}` to `{}`...", sub, bound_kind)
|
||||
} else {
|
||||
format!("`{}: {}`...", bound_kind, sub)
|
||||
},
|
||||
);
|
||||
if let Some((sp, has_lifetimes)) = type_param_span {
|
||||
let tail = if has_lifetimes { " + " } else { "" };
|
||||
let suggestion = format!("{}: {}{}", bound_kind, sub, tail);
|
||||
if let Some((sp, has_lifetimes, is_impl_trait)) = type_param_span {
|
||||
let suggestion = if is_impl_trait {
|
||||
format!("{} + {}", bound_kind, sub)
|
||||
} else {
|
||||
let tail = if has_lifetimes { " + " } else { "" };
|
||||
format!("{}: {}{}", bound_kind, sub, tail)
|
||||
};
|
||||
err.span_suggestion_short_with_applicability(
|
||||
sp,
|
||||
consider,
|
||||
&consider,
|
||||
suggestion,
|
||||
Applicability::MaybeIncorrect, // Issue #41966
|
||||
);
|
||||
} else {
|
||||
err.help(consider);
|
||||
err.help(&consider);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,50 +183,14 @@ pub struct EvalError<'tcx> {
|
||||
impl<'tcx> EvalError<'tcx> {
|
||||
pub fn print_backtrace(&mut self) {
|
||||
if let Some(ref mut backtrace) = self.backtrace {
|
||||
eprintln!("{}", print_backtrace(&mut *backtrace));
|
||||
print_backtrace(&mut *backtrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn print_backtrace(backtrace: &mut Backtrace) -> String {
|
||||
use std::fmt::Write;
|
||||
|
||||
fn print_backtrace(backtrace: &mut Backtrace) {
|
||||
backtrace.resolve();
|
||||
|
||||
let mut trace_text = "\n\nAn error occurred in miri:\n".to_string();
|
||||
write!(trace_text, "backtrace frames: {}\n", backtrace.frames().len()).unwrap();
|
||||
'frames: for (i, frame) in backtrace.frames().iter().enumerate() {
|
||||
if frame.symbols().is_empty() {
|
||||
write!(trace_text, " {}: no symbols\n", i).unwrap();
|
||||
}
|
||||
let mut first = true;
|
||||
for symbol in frame.symbols() {
|
||||
if first {
|
||||
write!(trace_text, " {}: ", i).unwrap();
|
||||
first = false;
|
||||
} else {
|
||||
let len = i.to_string().len();
|
||||
write!(trace_text, " {} ", " ".repeat(len)).unwrap();
|
||||
}
|
||||
if let Some(name) = symbol.name() {
|
||||
write!(trace_text, "{}\n", name).unwrap();
|
||||
} else {
|
||||
write!(trace_text, "<unknown>\n").unwrap();
|
||||
}
|
||||
write!(trace_text, " at ").unwrap();
|
||||
if let Some(file_path) = symbol.filename() {
|
||||
write!(trace_text, "{}", file_path.display()).unwrap();
|
||||
} else {
|
||||
write!(trace_text, "<unknown_file>").unwrap();
|
||||
}
|
||||
if let Some(line) = symbol.lineno() {
|
||||
write!(trace_text, ":{}\n", line).unwrap();
|
||||
} else {
|
||||
write!(trace_text, "\n").unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
trace_text
|
||||
eprintln!("\n\nAn error occurred in miri:\n{:?}", backtrace);
|
||||
}
|
||||
|
||||
impl<'tcx> From<EvalErrorKind<'tcx, u64>> for EvalError<'tcx> {
|
||||
@ -238,7 +202,7 @@ impl<'tcx> From<EvalErrorKind<'tcx, u64>> for EvalError<'tcx> {
|
||||
|
||||
if val == "immediate" {
|
||||
// Print it now
|
||||
eprintln!("{}", print_backtrace(&mut backtrace));
|
||||
print_backtrace(&mut backtrace);
|
||||
None
|
||||
} else {
|
||||
Some(Box::new(backtrace))
|
||||
|
@ -376,7 +376,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
||||
store.register_removed("resolve_trait_on_defaulted_unit",
|
||||
"converted into hard error, see https://github.com/rust-lang/rust/issues/48950");
|
||||
store.register_removed("private_no_mangle_fns",
|
||||
"no longer an warning, #[no_mangle] functions always exported");
|
||||
"no longer a warning, #[no_mangle] functions always exported");
|
||||
store.register_removed("private_no_mangle_statics",
|
||||
"no longer an warning, #[no_mangle] statics always exported");
|
||||
"no longer a warning, #[no_mangle] statics always exported");
|
||||
}
|
||||
|
@ -68,6 +68,7 @@ mod linux_musl_base;
|
||||
mod openbsd_base;
|
||||
mod netbsd_base;
|
||||
mod solaris_base;
|
||||
mod uefi_base;
|
||||
mod windows_base;
|
||||
mod windows_msvc_base;
|
||||
mod thumb_base;
|
||||
@ -254,12 +255,12 @@ macro_rules! supported_targets {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_targets() -> Box<dyn Iterator<Item=String>> {
|
||||
Box::new(TARGETS.iter().filter_map(|t| -> Option<String> {
|
||||
pub fn get_targets() -> impl Iterator<Item = String> {
|
||||
TARGETS.iter().filter_map(|t| -> Option<String> {
|
||||
load_specific(t)
|
||||
.and(Ok(t.to_string()))
|
||||
.ok()
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -419,6 +420,8 @@ supported_targets! {
|
||||
("aarch64-unknown-none", aarch64_unknown_none),
|
||||
|
||||
("x86_64-fortanix-unknown-sgx", x86_64_fortanix_unknown_sgx),
|
||||
|
||||
("x86_64-unknown-uefi", x86_64_unknown_uefi),
|
||||
}
|
||||
|
||||
/// Everything `rustc` knows about how to compile for a specific target.
|
||||
|
74
src/librustc_target/spec/uefi_base.rs
Normal file
74
src/librustc_target/spec/uefi_base.rs
Normal file
@ -0,0 +1,74 @@
|
||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// This defines a base target-configuration for native UEFI systems. The UEFI specification has
|
||||
// quite detailed sections on the ABI of all the supported target architectures. In almost all
|
||||
// cases it simply follows what Microsoft Windows does. Hence, whenever in doubt, see the MSDN
|
||||
// documentation.
|
||||
// UEFI uses COFF/PE32+ format for binaries. All binaries must be statically linked. No dynamic
|
||||
// linker is supported. As native to COFF, binaries are position-dependent, but will be relocated
|
||||
// by the loader if the pre-chosen memory location is already in use.
|
||||
// UEFI forbids running code on anything but the boot-CPU. Not interrupts are allowed other than
|
||||
// the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all
|
||||
// code runs in the same environment, no process separation is supported.
|
||||
|
||||
use spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions};
|
||||
use std::default::Default;
|
||||
|
||||
pub fn opts() -> TargetOptions {
|
||||
let mut pre_link_args = LinkArgs::new();
|
||||
|
||||
pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Link), vec![
|
||||
// Suppress the verbose logo and authorship debugging output, which would needlessly
|
||||
// clog any log files.
|
||||
"/NOLOGO".to_string(),
|
||||
|
||||
// UEFI is fully compatible to non-executable data pages. Tell the compiler that
|
||||
// non-code sections can be marked as non-executable, including stack pages.
|
||||
"/NXCOMPAT".to_string(),
|
||||
|
||||
// There is no runtime for UEFI targets, prevent them from being linked. UEFI targets
|
||||
// must be freestanding.
|
||||
"/nodefaultlib".to_string(),
|
||||
|
||||
// Non-standard subsystems have no default entry-point in PE+ files. We have to define
|
||||
// one. "efi_main" seems to be a common choice amongst other implementations and the
|
||||
// spec.
|
||||
"/entry:efi_main".to_string(),
|
||||
|
||||
// COFF images have a "Subsystem" field in their header, which defines what kind of
|
||||
// program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION,
|
||||
// EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION,
|
||||
// which is very likely the most common option. Individual projects can override this
|
||||
// with custom linker flags.
|
||||
// The subsystem-type only has minor effects on the application. It defines the memory
|
||||
// regions the application is loaded into (runtime-drivers need to be put into
|
||||
// reserved areas), as well as whether a return from the entry-point is treated as
|
||||
// exit (default for applications).
|
||||
"/subsystem:efi_application".to_string(),
|
||||
]);
|
||||
|
||||
TargetOptions {
|
||||
dynamic_linking: false,
|
||||
executables: true,
|
||||
disable_redzone: true,
|
||||
exe_suffix: ".efi".to_string(),
|
||||
allows_weak_linkage: false,
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
singlethread: true,
|
||||
emit_debug_gdb_scripts: false,
|
||||
|
||||
linker: Some("lld-link".to_string()),
|
||||
lld_flavor: LldFlavor::Link,
|
||||
pre_link_args,
|
||||
|
||||
.. Default::default()
|
||||
}
|
||||
}
|
58
src/librustc_target/spec/x86_64_unknown_uefi.rs
Normal file
58
src/librustc_target/spec/x86_64_unknown_uefi.rs
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// This defines the amd64 target for UEFI systems as described in the UEFI specification. See the
|
||||
// uefi-base module for generic UEFI options. On x86_64 systems (mostly called "x64" in the spec)
|
||||
// UEFI systems always run in long-mode, have the interrupt-controller pre-configured and force a
|
||||
// single-CPU execution.
|
||||
// The win64 ABI is used. It differs from the sysv64 ABI, so we must use a windows target with
|
||||
// LLVM. "x86_64-unknown-windows" is used to get the minimal subset of windows-specific features.
|
||||
|
||||
use spec::{LinkerFlavor, LldFlavor, Target, TargetResult};
|
||||
|
||||
pub fn target() -> TargetResult {
|
||||
let mut base = super::uefi_base::opts();
|
||||
base.cpu = "x86-64".to_string();
|
||||
base.max_atomic_width = Some(64);
|
||||
|
||||
// We disable MMX and SSE for now. UEFI does not prevent these from being used, but there have
|
||||
// been reports to GRUB that some firmware does not initialize the FP exception handlers
|
||||
// properly. Therefore, using FP coprocessors will end you up at random memory locations when
|
||||
// you throw FP exceptions.
|
||||
// To be safe, we disable them for now and force soft-float. This can be revisited when we
|
||||
// have more test coverage. Disabling FP served GRUB well so far, so it should be good for us
|
||||
// as well.
|
||||
base.features = "-mmx,-sse,+soft-float".to_string();
|
||||
|
||||
// UEFI systems run without a host OS, hence we cannot assume any code locality. We must tell
|
||||
// LLVM to expect code to reference any address in the address-space. The "large" code-model
|
||||
// places no locality-restrictions, so it fits well here.
|
||||
base.code_model = Some("large".to_string());
|
||||
|
||||
// UEFI mostly mirrors the calling-conventions used on windows. In case of x86-64 this means
|
||||
// small structs will be returned as int. This shouldn't matter much, since the restrictions
|
||||
// placed by the UEFI specifications forbid any ABI to return structures.
|
||||
base.abi_return_struct_as_int = true;
|
||||
|
||||
Ok(Target {
|
||||
llvm_target: "x86_64-unknown-windows".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_pointer_width: "64".to_string(),
|
||||
target_c_int_width: "32".to_string(),
|
||||
data_layout: "e-m:w-i64:64-f80:128-n8:16:32:64-S128".to_string(),
|
||||
target_os: "uefi".to_string(),
|
||||
target_env: "".to_string(),
|
||||
target_vendor: "unknown".to_string(),
|
||||
arch: "x86_64".to_string(),
|
||||
linker_flavor: LinkerFlavor::Lld(LldFlavor::Link),
|
||||
|
||||
options: base,
|
||||
})
|
||||
}
|
@ -424,10 +424,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
if !unsatisfied_predicates.is_empty() {
|
||||
let bound_list = unsatisfied_predicates.iter()
|
||||
let mut bound_list = unsatisfied_predicates.iter()
|
||||
.map(|p| format!("`{} : {}`", p.self_ty(), p))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
.collect::<Vec<_>>();
|
||||
bound_list.sort();
|
||||
bound_list.dedup(); // #35677
|
||||
let bound_list = bound_list.join("\n");
|
||||
err.note(&format!("the method `{}` exists but the following trait bounds \
|
||||
were not satisfied:\n{}",
|
||||
item_name,
|
||||
|
@ -72,32 +72,32 @@
|
||||
//!
|
||||
//! * **From Rust to C:** [`CString`] represents an owned, C-friendly
|
||||
//! string: it is nul-terminated, and has no internal nul characters.
|
||||
//! Rust code can create a `CString` out of a normal string (provided
|
||||
//! Rust code can create a [`CString`] out of a normal string (provided
|
||||
//! that the string doesn't have nul characters in the middle), and
|
||||
//! then use a variety of methods to obtain a raw `*mut u8` that can
|
||||
//! then use a variety of methods to obtain a raw `*mut `[`u8`] that can
|
||||
//! then be passed as an argument to functions which use the C
|
||||
//! conventions for strings.
|
||||
//!
|
||||
//! * **From C to Rust:** [`CStr`] represents a borrowed C string; it
|
||||
//! is what you would use to wrap a raw `*const u8` that you got from
|
||||
//! a C function. A `CStr` is guaranteed to be a nul-terminated array
|
||||
//! of bytes. Once you have a `CStr`, you can convert it to a Rust
|
||||
//! `&str` if it's valid UTF-8, or lossily convert it by adding
|
||||
//! is what you would use to wrap a raw `*const `[`u8`] that you got from
|
||||
//! a C function. A [`CStr`] is guaranteed to be a nul-terminated array
|
||||
//! of bytes. Once you have a [`CStr`], you can convert it to a Rust
|
||||
//! [`&str`][`str`] if it's valid UTF-8, or lossily convert it by adding
|
||||
//! replacement characters.
|
||||
//!
|
||||
//! [`OsString`] and [`OsStr`] are useful when you need to transfer
|
||||
//! strings to and from the operating system itself, or when capturing
|
||||
//! the output of external commands. Conversions between `OsString`,
|
||||
//! `OsStr` and Rust strings work similarly to those for [`CString`]
|
||||
//! the output of external commands. Conversions between [`OsString`],
|
||||
//! [`OsStr`] and Rust strings work similarly to those for [`CString`]
|
||||
//! and [`CStr`].
|
||||
//!
|
||||
//! * [`OsString`] represents an owned string in whatever
|
||||
//! representation the operating system prefers. In the Rust standard
|
||||
//! library, various APIs that transfer strings to/from the operating
|
||||
//! system use `OsString` instead of plain strings. For example,
|
||||
//! system use [`OsString`] instead of plain strings. For example,
|
||||
//! [`env::var_os()`] is used to query environment variables; it
|
||||
//! returns an `Option<OsString>`. If the environment variable exists
|
||||
//! you will get a `Some(os_string)`, which you can *then* try to
|
||||
//! returns an [`Option`]`<`[`OsString`]`>`. If the environment variable
|
||||
//! exists you will get a [`Some`]`(os_string)`, which you can *then* try to
|
||||
//! convert to a Rust string. This yields a [`Result<>`], so that
|
||||
//! your code can detect errors in case the environment variable did
|
||||
//! not in fact contain valid Unicode data.
|
||||
@ -105,7 +105,7 @@
|
||||
//! * [`OsStr`] represents a borrowed reference to a string in a
|
||||
//! format that can be passed to the operating system. It can be
|
||||
//! converted into an UTF-8 Rust string slice in a similar way to
|
||||
//! `OsString`.
|
||||
//! [`OsString`].
|
||||
//!
|
||||
//! # Conversions
|
||||
//!
|
||||
@ -131,7 +131,7 @@
|
||||
//! Additionally, on Windows [`OsString`] implements the
|
||||
//! `std::os::windows:ffi::`[`OsStringExt`][windows.OsStringExt]
|
||||
//! trait, which provides a [`from_wide`] method. The result of this
|
||||
//! method is an `OsString` which can be round-tripped to a Windows
|
||||
//! method is an [`OsString`] which can be round-tripped to a Windows
|
||||
//! string losslessly.
|
||||
//!
|
||||
//! [`String`]: ../string/struct.String.html
|
||||
@ -160,6 +160,8 @@
|
||||
//! [`collect`]: ../iter/trait.Iterator.html#method.collect
|
||||
//! [windows.OsStringExt]: ../os/windows/ffi/trait.OsStringExt.html
|
||||
//! [`from_wide`]: ../os/windows/ffi/trait.OsStringExt.html#tymethod.from_wide
|
||||
//! [`Option`]: ../option/enum.Option.html
|
||||
//! [`Some`]: ../option/enum.Option.html#variant.Some
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
|
@ -195,9 +195,10 @@ pub struct OpenOptions(fs_imp::OpenOptions);
|
||||
/// This module only currently provides one bit of information, [`readonly`],
|
||||
/// which is exposed on all currently supported platforms. Unix-specific
|
||||
/// functionality, such as mode bits, is available through the
|
||||
/// `os::unix::PermissionsExt` trait.
|
||||
/// [`PermissionsExt`] trait.
|
||||
///
|
||||
/// [`readonly`]: struct.Permissions.html#method.readonly
|
||||
/// [`PermissionsExt`]: ../os/unix/fs/trait.PermissionsExt.html
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct Permissions(fs_imp::FilePermissions);
|
||||
|
@ -14,8 +14,8 @@ LL | .collect(); //~ ERROR no method named `collect`
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: the method `collect` exists but the following trait bounds were not satisfied:
|
||||
`std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:16:39: 19:6 found_e:_]>> : std::iter::Iterator`
|
||||
`&mut std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:16:39: 19:6 found_e:_]>> : std::iter::Iterator`
|
||||
`std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:16:39: 19:6 found_e:_]>> : std::iter::Iterator`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
5
src/test/ui/issues/issue-35677.rs
Normal file
5
src/test/ui/issues/issue-35677.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use std::collections::HashMap;
|
||||
fn intersect_map<K, V>(this: &mut HashMap<K, V>, other: HashMap<K, V>) -> bool {
|
||||
this.drain()
|
||||
//~^ ERROR no method named
|
||||
}
|
18
src/test/ui/issues/issue-35677.stderr
Normal file
18
src/test/ui/issues/issue-35677.stderr
Normal file
@ -0,0 +1,18 @@
|
||||
error[E0601]: `main` function not found in crate `issue_35677`
|
||||
|
|
||||
= note: consider adding a `main` function to `$DIR/issue-35677.rs`
|
||||
|
||||
error[E0599]: no method named `drain` found for type `&mut std::collections::HashMap<K, V>` in the current scope
|
||||
--> $DIR/issue-35677.rs:3:10
|
||||
|
|
||||
LL | this.drain()
|
||||
| ^^^^^
|
||||
|
|
||||
= note: the method `drain` exists but the following trait bounds were not satisfied:
|
||||
`K : std::cmp::Eq`
|
||||
`K : std::hash::Hash`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors occurred: E0599, E0601.
|
||||
For more information about an error, try `rustc --explain E0599`.
|
@ -1,8 +1,8 @@
|
||||
warning: lint `private_no_mangle_fns` has been removed: `no longer an warning, #[no_mangle] functions always exported`
|
||||
warning: lint `private_no_mangle_fns` has been removed: `no longer a warning, #[no_mangle] functions always exported`
|
||||
|
|
||||
= note: requested on the command line with `-F private_no_mangle_fns`
|
||||
|
||||
warning: lint `private_no_mangle_statics` has been removed: `no longer an warning, #[no_mangle] statics always exported`
|
||||
warning: lint `private_no_mangle_statics` has been removed: `no longer a warning, #[no_mangle] statics always exported`
|
||||
|
|
||||
= note: requested on the command line with `-F private_no_mangle_statics`
|
||||
|
||||
|
@ -5,8 +5,8 @@ LL | once::<&str>("str").fuse().filter(|a: &str| true).count();
|
||||
| ^^^^^
|
||||
|
|
||||
= note: the method `count` exists but the following trait bounds were not satisfied:
|
||||
`std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator`
|
||||
`&mut std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator`
|
||||
`std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator`
|
||||
|
||||
error[E0631]: type mismatch in closure arguments
|
||||
--> $DIR/issue-36053-2.rs:17:32
|
||||
|
@ -0,0 +1,74 @@
|
||||
// This is a collection of examples where a function's formal
|
||||
// parameter has an explicit lifetime and a closure within that
|
||||
// function returns that formal parameter. The closure's return type,
|
||||
// to be correctly inferred, needs to include the lifetime introduced
|
||||
// by the function.
|
||||
//
|
||||
// This works today, which precludes changing things so that closures
|
||||
// follow the same lifetime-elision rules used elsehwere. See
|
||||
// rust-lang/rust#56537
|
||||
|
||||
// compile-pass
|
||||
// We are already testing NLL explicitly via the revision system below.
|
||||
// ignore-compare-mode-nll
|
||||
|
||||
// revisions: ll nll migrate
|
||||
//[ll] compile-flags:-Zborrowck=ast
|
||||
//[nll] compile-flags:-Zborrowck=mir -Z two-phase-borrows
|
||||
//[migrate] compile-flags:-Zborrowck=migrate -Z two-phase-borrows
|
||||
|
||||
fn willy_no_annot<'w>(p: &'w str, q: &str) -> &'w str {
|
||||
let free_dumb = |_x| { p }; // no type annotation at all
|
||||
let hello = format!("Hello");
|
||||
free_dumb(&hello)
|
||||
}
|
||||
|
||||
fn willy_ret_type_annot<'w>(p: &'w str, q: &str) -> &'w str {
|
||||
let free_dumb = |_x| -> &str { p }; // type annotation on the return type
|
||||
let hello = format!("Hello");
|
||||
free_dumb(&hello)
|
||||
}
|
||||
|
||||
fn willy_ret_region_annot<'w>(p: &'w str, q: &str) -> &'w str {
|
||||
let free_dumb = |_x| -> &'w str { p }; // type+region annotation on return type
|
||||
let hello = format!("Hello");
|
||||
free_dumb(&hello)
|
||||
}
|
||||
|
||||
fn willy_arg_type_ret_type_annot<'w>(p: &'w str, q: &str) -> &'w str {
|
||||
let free_dumb = |_x: &str| -> &str { p }; // type annotation on arg and return types
|
||||
let hello = format!("Hello");
|
||||
free_dumb(&hello)
|
||||
}
|
||||
|
||||
fn willy_arg_type_ret_region_annot<'w>(p: &'w str, q: &str) -> &'w str {
|
||||
let free_dumb = |_x: &str| -> &'w str { p }; // fully annotated
|
||||
let hello = format!("Hello");
|
||||
free_dumb(&hello)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let world = format!("World");
|
||||
let w1: &str = {
|
||||
let hello = format!("He11o");
|
||||
willy_no_annot(&world, &hello)
|
||||
};
|
||||
let w2: &str = {
|
||||
let hello = format!("He22o");
|
||||
willy_ret_type_annot(&world, &hello)
|
||||
};
|
||||
let w3: &str = {
|
||||
let hello = format!("He33o");
|
||||
willy_ret_region_annot(&world, &hello)
|
||||
};
|
||||
let w4: &str = {
|
||||
let hello = format!("He44o");
|
||||
willy_arg_type_ret_type_annot(&world, &hello)
|
||||
};
|
||||
let w5: &str = {
|
||||
let hello = format!("He55o");
|
||||
willy_arg_type_ret_region_annot(&world, &hello)
|
||||
};
|
||||
assert_eq!((w1, w2, w3, w4, w5),
|
||||
("World","World","World","World","World"));
|
||||
}
|
18
src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed
Normal file
18
src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed
Normal file
@ -0,0 +1,18 @@
|
||||
// run-rustfix
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
fn foo(d: impl Debug + 'static) {
|
||||
//~^ HELP consider adding an explicit lifetime bound `'static` to `impl Debug`
|
||||
bar(d);
|
||||
//~^ ERROR the parameter type `impl Debug` may not live long enough
|
||||
//~| NOTE ...so that the type `impl Debug` will meet its required lifetime bounds
|
||||
}
|
||||
|
||||
fn bar(d: impl Debug + 'static) {
|
||||
println!("{:?}", d)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo("hi");
|
||||
}
|
18
src/test/ui/suggestions/suggest-impl-trait-lifetime.rs
Normal file
18
src/test/ui/suggestions/suggest-impl-trait-lifetime.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// run-rustfix
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
fn foo(d: impl Debug) {
|
||||
//~^ HELP consider adding an explicit lifetime bound `'static` to `impl Debug`
|
||||
bar(d);
|
||||
//~^ ERROR the parameter type `impl Debug` may not live long enough
|
||||
//~| NOTE ...so that the type `impl Debug` will meet its required lifetime bounds
|
||||
}
|
||||
|
||||
fn bar(d: impl Debug + 'static) {
|
||||
println!("{:?}", d)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo("hi");
|
||||
}
|
19
src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr
Normal file
19
src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr
Normal file
@ -0,0 +1,19 @@
|
||||
error[E0310]: the parameter type `impl Debug` may not live long enough
|
||||
--> $DIR/suggest-impl-trait-lifetime.rs:7:5
|
||||
|
|
||||
LL | bar(d);
|
||||
| ^^^
|
||||
|
|
||||
note: ...so that the type `impl Debug` will meet its required lifetime bounds
|
||||
--> $DIR/suggest-impl-trait-lifetime.rs:7:5
|
||||
|
|
||||
LL | bar(d);
|
||||
| ^^^
|
||||
help: consider adding an explicit lifetime bound `'static` to `impl Debug`...
|
||||
|
|
||||
LL | fn foo(d: impl Debug + 'static) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0310`.
|
@ -34,6 +34,16 @@ MAINTAINERS = {
|
||||
'rust-by-example': '@steveklabnik @marioidival @projektir',
|
||||
}
|
||||
|
||||
EMOJI = {
|
||||
'miri': '🛰️',
|
||||
'clippy-driver': '📎',
|
||||
'rls': '💻',
|
||||
'rustfmt': '📝',
|
||||
'book': '📖',
|
||||
'nomicon': '👿',
|
||||
'reference': '📚',
|
||||
'rust-by-example': '👩🏫',
|
||||
}
|
||||
|
||||
def read_current_status(current_commit, path):
|
||||
'''Reads build status of `current_commit` from content of `history/*.tsv`
|
||||
@ -63,13 +73,12 @@ def update_latest(
|
||||
}
|
||||
|
||||
slug = 'rust-lang/rust'
|
||||
message = textwrap.dedent('''\
|
||||
📣 Toolstate changed by {}!
|
||||
|
||||
long_message = textwrap.dedent('''\
|
||||
Tested on commit {}@{}.
|
||||
Direct link to PR: <{}>
|
||||
|
||||
''').format(relevant_pr_number, slug, current_commit, relevant_pr_url)
|
||||
''').format(slug, current_commit, relevant_pr_url)
|
||||
emoji_status = []
|
||||
anything_changed = False
|
||||
for status in latest:
|
||||
tool = status['tool']
|
||||
@ -81,12 +90,18 @@ def update_latest(
|
||||
status[os] = new
|
||||
if new > old:
|
||||
changed = True
|
||||
message += '🎉 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \
|
||||
.format(tool, os, old, new, MAINTAINERS.get(tool))
|
||||
long_message += '🎉 {} on {}: {} → {}.\n' \
|
||||
.format(tool, os, old, new)
|
||||
emoji = "{}🎉".format(EMOJI.get(tool))
|
||||
if msg not in emoji_status:
|
||||
emoji_status += [msg]
|
||||
elif new < old:
|
||||
changed = True
|
||||
message += '💔 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \
|
||||
long_message += '💔 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \
|
||||
.format(tool, os, old, new, MAINTAINERS.get(tool))
|
||||
emoji = "{}💔".format(EMOJI.get(tool))
|
||||
if msg not in emoji_status:
|
||||
emoji_status += [msg]
|
||||
|
||||
if changed:
|
||||
status['commit'] = current_commit
|
||||
@ -96,6 +111,9 @@ def update_latest(
|
||||
if not anything_changed:
|
||||
return ''
|
||||
|
||||
short_message = "📣 Toolstate changed by {}! ({})"
|
||||
.format(relevant_pr_number, '/'.join(emoji_status))
|
||||
message = short_message + "\n\n" + long_message
|
||||
f.seek(0)
|
||||
f.truncate(0)
|
||||
json.dump(latest, f, indent=4, separators=(',', ': '))
|
||||
|
Loading…
x
Reference in New Issue
Block a user