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:
bors 2018-12-15 11:31:40 +00:00
commit 0a1b2267e4
27 changed files with 419 additions and 96 deletions

View File

@ -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"

View File

@ -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

View File

@ -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,

View File

@ -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" \

View File

@ -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.

View File

@ -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:

View File

@ -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)]

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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))

View File

@ -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");
}

View File

@ -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.

View 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()
}
}

View 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,
})
}

View File

@ -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,

View File

@ -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")]

View File

@ -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);

View File

@ -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

View 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
}

View 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`.

View File

@ -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`

View File

@ -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

View File

@ -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"));
}

View 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");
}

View 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");
}

View 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`.

View File

@ -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=(',', ': '))