New upstream version 1.56.0+dfsg1

This commit is contained in:
Ximin Luo 2021-10-22 15:37:38 +01:00
parent 94222f6423
commit dc3f568640
87 changed files with 1173 additions and 213 deletions

4
Cargo.lock generated
View File

@ -1966,6 +1966,10 @@ dependencies = [
"walkdir",
]
[[package]]
name = "lld-wrapper"
version = "0.1.0"
[[package]]
name = "lock_api"
version = "0.4.1"

View File

@ -35,6 +35,7 @@ members = [
"src/tools/expand-yaml-anchors",
"src/tools/jsondocck",
"src/tools/html-checker",
"src/tools/lld-wrapper",
]
exclude = [

View File

@ -1,3 +1,185 @@
Version 1.56.0 (2021-10-21)
========================
Language
--------
- [The 2021 Edition is now stable.][rust#88100]
See [the edition guide][rust-2021-edition-guide] for more details.
- [The pattern in `binding @ pattern` can now also introduce new bindings.][rust#85305]
- [Union field access is permitted in `const fn`.][rust#85769]
[rust-2021-edition-guide]: https://doc.rust-lang.org/nightly/edition-guide/rust-2021/index.html
Compiler
--------
- [Upgrade to LLVM 13.][rust#87570]
- [Support memory, address, and thread sanitizers on aarch64-unknown-freebsd.][rust#88023]
- [Allow specifying a deployment target version for all iOS targets][rust#87699]
- [Warnings can be forced on with `--force-warn`.][rust#87472]
This feature is primarily intended for usage by `cargo fix`, rather than end users.
- [Promote `aarch64-apple-ios-sim` to Tier 2\*.][rust#87760]
- [Add `powerpc-unknown-freebsd` at Tier 3\*.][rust#87370]
- [Add `riscv32imc-esp-espidf` at Tier 3\*.][rust#87666]
\* Refer to Rust's [platform support page][platform-support-doc] for more
information on Rust's tiered platform support.
Libraries
---------
- [Allow writing of incomplete UTF-8 sequences via stdout/stderr on Windows.][rust#83342]
The Windows console still requires valid Unicode, but this change allows
splitting a UTF-8 character across multiple write calls. This allows, for
instance, programs that just read and write data buffers (e.g. copying a file
to stdout) without regard for Unicode or character boundaries.
- [Prefer `AtomicU{64,128}` over Mutex for Instant backsliding protection.][rust#83093]
For this use case, atomics scale much better under contention.
- [Implement `Extend<(A, B)>` for `(Extend<A>, Extend<B>)`][rust#85835]
- [impl Default, Copy, Clone for std::io::Sink and std::io::Empty][rust#86744]
- [`impl From<[(K, V); N]>` for all collections.][rust#84111]
- [Remove `P: Unpin` bound on impl Future for Pin.][rust#81363]
- [Treat invalid environment variable names as non-existent.][rust#86183]
Previously, the environment functions would panic if given a variable name
with an internal null character or equal sign (`=`). Now, these functions will
just treat such names as non-existent variables, since the OS cannot represent
the existence of a variable with such a name.
Stabilised APIs
---------------
- [`std::os::unix::fs::chroot`]
- [`UnsafeCell::raw_get`]
- [`BufWriter::into_parts`]
- [`core::panic::{UnwindSafe, RefUnwindSafe, AssertUnwindSafe}`]
These APIs were previously stable in `std`, but are now also available in `core`.
- [`Vec::shrink_to`]
- [`String::shrink_to`]
- [`OsString::shrink_to`]
- [`PathBuf::shrink_to`]
- [`BinaryHeap::shrink_to`]
- [`VecDeque::shrink_to`]
- [`HashMap::shrink_to`]
- [`HashSet::shrink_to`]
These APIs are now usable in const contexts:
- [`std::mem::transmute`]
- [`[T]::first`][`slice::first`]
- [`[T]::split_first`][`slice::split_first`]
- [`[T]::last`][`slice::last`]
- [`[T]::split_last`][`slice::split_last`]
Cargo
-----
- [Cargo supports specifying a minimum supported Rust version in Cargo.toml.][`rust-version`]
This has no effect at present on dependency version selection.
We encourage crates to specify their minimum supported Rust version, and we encourage CI systems
that support Rust code to include a crate's specified minimum version in the text matrix for that
crate by default.
Compatibility notes
-------------------
- [Update to new argument parsing rules on Windows.][rust#87580]
This adjusts Rust's standard library to match the behavior of the standard
libraries for C/C++. The rules have changed slightly over time, and this PR
brings us to the latest set of rules (changed in 2008).
- [Disallow the aapcs calling convention on aarch64][rust#88399]
This was already not supported by LLVM; this change surfaces this lack of
support with a better error message.
- [Make `SEMICOLON_IN_EXPRESSIONS_FROM_MACROS` warn by default][rust#87385]
- [Warn when an escaped newline skips multiple lines.][rust#87671]
- [Calls to `libc::getpid` / `std::process::id` from `Command::pre_exec`
may return different values on glibc <= 2.24.][rust#81825]
Rust now invokes the `clone3` system call directly, when available, to use new functionality
available via that system call. Older versions of glibc cache the result of `getpid`, and only
update that cache when calling glibc's clone/fork functions, so a direct system call bypasses
that cache update. glibc 2.25 and newer no longer cache `getpid` for exactly this reason.
Internal changes
----------------
These changes provide no direct user facing benefits, but represent significant
improvements to the internals and overall performance of rustc
and related tools.
- [LLVM is compiled with PGO in published x86_64-unknown-linux-gnu artifacts.][rust#88069]
This improves the performance of most Rust builds.
- [Unify representation of macros in internal data structures.][rust#88019]
This change fixes a host of bugs with the handling of macros by the compiler,
as well as rustdoc.
[`std::os::unix::fs::chroot`]: https://doc.rust-lang.org/stable/std/os/unix/fs/fn.chroot.html
[`Iterator::intersperse`]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.intersperse
[`Iterator::intersperse_with`]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.intersperse
[`UnsafeCell::raw_get`]: https://doc.rust-lang.org/stable/std/cell/struct.UnsafeCell.html#method.raw_get
[`BufWriter::into_parts`]: https://doc.rust-lang.org/stable/std/io/struct.BufWriter.html#method.into_parts
[`core::panic::{UnwindSafe, RefUnwindSafe, AssertUnwindSafe}`]: https://github.com/rust-lang/rust/pull/84662
[`Vec::shrink_to`]: https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.shrink_to
[`String::shrink_to`]: https://doc.rust-lang.org/stable/std/string/struct.String.html#method.shrink_to
[`OsString::shrink_to`]: https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.shrink_to
[`PathBuf::shrink_to`]: https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.shrink_to
[`BinaryHeap::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/struct.BinaryHeap.html#method.shrink_to
[`VecDeque::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/struct.VecDeque.html#method.shrink_to
[`HashMap::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/hash_map/struct.HashMap.html#method.shrink_to
[`HashSet::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/hash_set/struct.HashSet.html#method.shrink_to
[`std::mem::transmute`]: https://doc.rust-lang.org/stable/std/mem/fn.transmute.html
[`slice::first`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.first
[`slice::split_first`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_first
[`slice::last`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.last
[`slice::split_last`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_last
[`rust-version`]: https://doc.rust-lang.org/nightly/cargo/reference/manifest.html#the-rust-version-field
[rust#87671]: https://github.com/rust-lang/rust/pull/87671
[rust#86183]: https://github.com/rust-lang/rust/pull/86183
[rust#87385]: https://github.com/rust-lang/rust/pull/87385
[rust#88100]: https://github.com/rust-lang/rust/pull/88100
[rust#86860]: https://github.com/rust-lang/rust/pull/86860
[rust#84039]: https://github.com/rust-lang/rust/pull/84039
[rust#86492]: https://github.com/rust-lang/rust/pull/86492
[rust#88363]: https://github.com/rust-lang/rust/pull/88363
[rust#85305]: https://github.com/rust-lang/rust/pull/85305
[rust#87832]: https://github.com/rust-lang/rust/pull/87832
[rust#88069]: https://github.com/rust-lang/rust/pull/88069
[rust#87472]: https://github.com/rust-lang/rust/pull/87472
[rust#87699]: https://github.com/rust-lang/rust/pull/87699
[rust#87570]: https://github.com/rust-lang/rust/pull/87570
[rust#88023]: https://github.com/rust-lang/rust/pull/88023
[rust#87760]: https://github.com/rust-lang/rust/pull/87760
[rust#87370]: https://github.com/rust-lang/rust/pull/87370
[rust#87580]: https://github.com/rust-lang/rust/pull/87580
[rust#83342]: https://github.com/rust-lang/rust/pull/83342
[rust#83093]: https://github.com/rust-lang/rust/pull/83093
[rust#88177]: https://github.com/rust-lang/rust/pull/88177
[rust#88548]: https://github.com/rust-lang/rust/pull/88548
[rust#88551]: https://github.com/rust-lang/rust/pull/88551
[rust#88299]: https://github.com/rust-lang/rust/pull/88299
[rust#88220]: https://github.com/rust-lang/rust/pull/88220
[rust#85835]: https://github.com/rust-lang/rust/pull/85835
[rust#86879]: https://github.com/rust-lang/rust/pull/86879
[rust#86744]: https://github.com/rust-lang/rust/pull/86744
[rust#84662]: https://github.com/rust-lang/rust/pull/84662
[rust#86593]: https://github.com/rust-lang/rust/pull/86593
[rust#81050]: https://github.com/rust-lang/rust/pull/81050
[rust#81363]: https://github.com/rust-lang/rust/pull/81363
[rust#84111]: https://github.com/rust-lang/rust/pull/84111
[rust#85769]: https://github.com/rust-lang/rust/pull/85769#issuecomment-854363720
[rust#88490]: https://github.com/rust-lang/rust/pull/88490
[rust#88269]: https://github.com/rust-lang/rust/pull/88269
[rust#84176]: https://github.com/rust-lang/rust/pull/84176
[rust#88399]: https://github.com/rust-lang/rust/pull/88399
[rust#88227]: https://github.com/rust-lang/rust/pull/88227
[rust#88200]: https://github.com/rust-lang/rust/pull/88200
[rust#82776]: https://github.com/rust-lang/rust/pull/82776
[rust#88077]: https://github.com/rust-lang/rust/pull/88077
[rust#87728]: https://github.com/rust-lang/rust/pull/87728
[rust#87050]: https://github.com/rust-lang/rust/pull/87050
[rust#87619]: https://github.com/rust-lang/rust/pull/87619
[rust#81825]: https://github.com/rust-lang/rust/pull/81825#issuecomment-808406918
[rust#88019]: https://github.com/rust-lang/rust/pull/88019
[rust#87666]: https://github.com/rust-lang/rust/pull/87666
Version 1.55.0 (2021-09-09)
============================
@ -4985,7 +5167,7 @@ Libraries
- [Upgrade to Unicode 10.0.0][42999]
- [Reimplemented `{f32, f64}::{min, max}` in Rust instead of using CMath.][42430]
- [Skip the main thread's manual stack guard on Linux][43072]
- [Iterator::nth for `ops::{Range, RangeFrom}` is now done in O(1) time][43077]
- [Iterator::nth for `ops::{Range, RangeFrom}` is now done in *O*(1) time][43077]
- [`#[repr(align(N))]` attribute max number is now 2^31 - 1.][43097] This was
previously 2^15.
- [`{OsStr, Path}::Display` now avoids allocations where possible][42613]
@ -8288,7 +8470,7 @@ Libraries
algorithm][s].
* [`std::io::copy` allows `?Sized` arguments][cc].
* The `Windows`, `Chunks`, and `ChunksMut` iterators over slices all
[override `count`, `nth` and `last` with an O(1)
[override `count`, `nth` and `last` with an *O*(1)
implementation][it].
* [`Default` is implemented for arrays up to `[T; 32]`][d].
* [`IntoRawFd` has been added to the Unix-specific prelude,
@ -8810,7 +8992,7 @@ Libraries
* The `Default` implementation for `Arc` [no longer requires `Sync +
Send`][arc].
* [The `Iterator` methods `count`, `nth`, and `last` have been
overridden for slices to have O(1) performance instead of O(n)][si].
overridden for slices to have *O*(1) performance instead of *O*(*n*)][si].
* Incorrect handling of paths on Windows has been improved in both the
compiler and the standard library.
* [`AtomicPtr` gained a `Default` implementation][ap].

View File

@ -1,11 +1,11 @@
use rustc_ast as ast;
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
use rustc_ast::{AssocTyConstraint, AssocTyConstraintKind, NodeId};
use rustc_ast::{PatKind, RangeEnd};
use rustc_ast::{PatKind, RangeEnd, VariantData};
use rustc_errors::struct_span_err;
use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP};
use rustc_feature::{Features, GateIssue};
use rustc_session::parse::feature_err_issue;
use rustc_session::parse::{feature_err, feature_err_issue};
use rustc_session::Session;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::sym;
@ -218,6 +218,46 @@ impl<'a> PostExpansionVisitor<'a> {
}
}
fn maybe_report_invalid_custom_discriminants(&self, variants: &[ast::Variant]) {
let has_fields = variants.iter().any(|variant| match variant.data {
VariantData::Tuple(..) | VariantData::Struct(..) => true,
VariantData::Unit(..) => false,
});
let discriminant_spans = variants
.iter()
.filter(|variant| match variant.data {
VariantData::Tuple(..) | VariantData::Struct(..) => false,
VariantData::Unit(..) => true,
})
.filter_map(|variant| variant.disr_expr.as_ref().map(|c| c.value.span))
.collect::<Vec<_>>();
if !discriminant_spans.is_empty() && has_fields {
let mut err = feature_err(
&self.sess.parse_sess,
sym::arbitrary_enum_discriminant,
discriminant_spans.clone(),
"custom discriminant values are not allowed in enums with tuple or struct variants",
);
for sp in discriminant_spans {
err.span_label(sp, "disallowed custom discriminant");
}
for variant in variants.iter() {
match &variant.data {
VariantData::Struct(..) => {
err.span_label(variant.span, "struct variant defined here");
}
VariantData::Tuple(..) => {
err.span_label(variant.span, "tuple variant defined here");
}
VariantData::Unit(..) => {}
}
}
err.emit();
}
}
fn check_gat(&self, generics: &ast::Generics, span: Span) {
if !generics.params.is_empty() {
gate_feature_post!(
@ -362,6 +402,26 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
}
}
ast::ItemKind::Enum(ast::EnumDef { ref variants, .. }, ..) => {
for variant in variants {
match (&variant.data, &variant.disr_expr) {
(ast::VariantData::Unit(..), _) => {}
(_, Some(disr_expr)) => gate_feature_post!(
&self,
arbitrary_enum_discriminant,
disr_expr.value.span,
"discriminants on non-unit variants are experimental"
),
_ => {}
}
}
let has_feature = self.features.arbitrary_enum_discriminant;
if !has_feature && !i.span.allows_unstable(sym::arbitrary_enum_discriminant) {
self.maybe_report_invalid_custom_discriminants(&variants);
}
}
ast::ItemKind::Impl(box ast::ImplKind {
polarity, defaultness, ref of_trait, ..
}) => {

View File

@ -1,10 +1,10 @@
use rustc_errors::{Applicability, DiagnosticBuilder};
use crate::panic::use_panic_2021;
use rustc_ast::ptr::P;
use rustc_ast::token;
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
use rustc_ast::{self as ast, *};
use rustc_ast_pretty::pprust;
use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_expand::base::*;
use rustc_parse::parser::Parser;
use rustc_span::symbol::{sym, Ident, Symbol};
@ -28,7 +28,7 @@ pub fn expand_assert<'cx>(
let sp = cx.with_call_site_ctxt(span);
let panic_call = if let Some(tokens) = custom_message {
let path = if span.rust_2021() {
let path = if use_panic_2021(span) {
// On edition 2021, we always call `$crate::panic::panic_2021!()`.
Path {
span: sp,

View File

@ -2,6 +2,7 @@ use rustc_ast::ptr::P;
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
use rustc_ast::*;
use rustc_expand::base::*;
use rustc_span::edition::Edition;
use rustc_span::symbol::sym;
use rustc_span::Span;
@ -19,7 +20,7 @@ pub fn expand_panic<'cx>(
sp: Span,
tts: TokenStream,
) -> Box<dyn MacResult + 'cx> {
let panic = if sp.rust_2021() { sym::panic_2021 } else { sym::panic_2015 };
let panic = if use_panic_2021(sp) { sym::panic_2021 } else { sym::panic_2015 };
let sp = cx.with_call_site_ctxt(sp);
@ -46,3 +47,19 @@ pub fn expand_panic<'cx>(
),
)
}
pub fn use_panic_2021(mut span: Span) -> bool {
// To determine the editon, we check the first span up the expansion
// stack that does not have #[allow_internal_unstable(edition_panic)].
// (To avoid using the edition of e.g. the assert!() or debug_assert!() definition.)
loop {
let expn = span.ctxt().outer_expn_data();
if let Some(features) = expn.allow_internal_unstable {
if features.iter().any(|&f| f == sym::edition_panic) {
span = expn.call_site;
continue;
}
}
break expn.edition >= Edition::Edition2021;
}
}

View File

@ -68,7 +68,7 @@ pub(crate) fn get_vtable<'tcx>(
ty: Ty<'tcx>,
trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
) -> Value {
let alloc_id = fx.tcx.vtable_allocation(ty, trait_ref);
let alloc_id = fx.tcx.vtable_allocation((ty, trait_ref));
let data_id =
data_id_for_alloc_id(&mut fx.constants_cx, &mut *fx.module, alloc_id, Mutability::Not);
let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);

View File

@ -72,7 +72,7 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
return val;
}
let vtable_alloc_id = tcx.vtable_allocation(ty, trait_ref);
let vtable_alloc_id = tcx.vtable_allocation((ty, trait_ref));
let vtable_allocation = tcx.global_alloc(vtable_alloc_id).unwrap_memory();
let vtable_const = cx.const_data_from_alloc(vtable_allocation);
let align = cx.data_layout().pointer_align.abi;

View File

@ -3,6 +3,8 @@ An `enum` with a discriminant must specify a `#[repr(inttype)]`.
Erroneous code example:
```compile_fail,E0732
#![feature(arbitrary_enum_discriminant)]
enum Enum { // error!
Unit = 1,
Tuple() = 2,
@ -18,6 +20,8 @@ is a well-defined way to extract a variant's discriminant from a value;
for instance:
```
#![feature(arbitrary_enum_discriminant)]
#[repr(u8)]
enum Enum {
Unit = 3,

View File

@ -289,13 +289,11 @@ declare_features! (
(accepted, member_constraints, "1.54.0", Some(61997), None),
/// Allows bindings in the subpattern of a binding pattern.
/// For example, you can write `x @ Some(y)`.
(accepted, bindings_after_at, "1.54.0", Some(65490), None),
(accepted, bindings_after_at, "1.56.0", Some(65490), None),
/// Allows calling `transmute` in const fn
(accepted, const_fn_transmute, "1.56.0", Some(53605), None),
/// Allows accessing fields of unions inside `const` functions.
(accepted, const_fn_union, "1.56.0", Some(51909), None),
/// Allows explicit discriminants on non-unit enum variants.
(accepted, arbitrary_enum_discriminant, "1.56.0", Some(60553), None),
// -------------------------------------------------------------------------
// feature-group-end: accepted features

View File

@ -468,6 +468,9 @@ declare_features! (
/// Allows #[repr(transparent)] on unions (RFC 2645).
(active, transparent_unions, "1.37.0", Some(60405), None),
/// Allows explicit discriminants on non-unit enum variants.
(active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None),
/// Allows `async || body` closures.
(active, async_closure, "1.37.0", Some(62290), None),

View File

@ -1006,6 +1006,13 @@ rustc_queries! {
key.1, key.0 }
}
query vtable_allocation(key: (Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>)) -> mir::interpret::AllocId {
desc { |tcx| "vtable const allocation for <{} as {}>",
key.0,
key.1.map(|trait_ref| format!("{}", trait_ref)).unwrap_or("_".to_owned())
}
}
query codegen_fulfill_obligation(
key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)
) -> Result<ImplSource<'tcx, ()>, ErrorReported> {

View File

@ -10,7 +10,7 @@ use crate::middle;
use crate::middle::cstore::EncodedMetadata;
use crate::middle::resolve_lifetime::{self, LifetimeScopeForPath, ObjectLifetimeDefault};
use crate::middle::stability;
use crate::mir::interpret::{self, AllocId, Allocation, ConstValue, Scalar};
use crate::mir::interpret::{self, Allocation, ConstValue, Scalar};
use crate::mir::{Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted};
use crate::thir::Thir;
use crate::traits;
@ -1062,9 +1062,6 @@ pub struct GlobalCtxt<'tcx> {
layout_interner: ShardedHashMap<&'tcx Layout, ()>,
output_filenames: Arc<OutputFilenames>,
pub(super) vtables_cache:
Lock<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), AllocId>>,
}
impl<'tcx> TyCtxt<'tcx> {
@ -1212,7 +1209,6 @@ impl<'tcx> TyCtxt<'tcx> {
const_stability_interner: Default::default(),
alloc_map: Lock::new(interpret::AllocMap::new()),
output_filenames: Arc::new(output_filenames),
vtables_cache: Default::default(),
}
}

View File

@ -2046,6 +2046,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
trait_impls_of: trait_def::trait_impls_of_provider,
type_uninhabited_from: inhabitedness::type_uninhabited_from,
const_param_default: consts::const_param_default,
vtable_allocation: vtable::vtable_allocation_provider,
..*providers
};
}

View File

@ -2177,6 +2177,7 @@ forward_display_to_print! {
// because `for<'tcx>` isn't possible yet.
ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>,
ty::Binder<'tcx, ty::TraitRef<'tcx>>,
ty::Binder<'tcx, ty::ExistentialTraitRef<'tcx>>,
ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
ty::Binder<'tcx, ty::FnSig<'tcx>>,
ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,

View File

@ -43,85 +43,72 @@ pub const COMMON_VTABLE_ENTRIES_DROPINPLACE: usize = 0;
pub const COMMON_VTABLE_ENTRIES_SIZE: usize = 1;
pub const COMMON_VTABLE_ENTRIES_ALIGN: usize = 2;
impl<'tcx> TyCtxt<'tcx> {
/// Retrieves an allocation that represents the contents of a vtable.
/// There's a cache within `TyCtxt` so it will be deduplicated.
pub fn vtable_allocation(
self,
ty: Ty<'tcx>,
poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
) -> AllocId {
let tcx = self;
let vtables_cache = tcx.vtables_cache.lock();
if let Some(alloc_id) = vtables_cache.get(&(ty, poly_trait_ref)).cloned() {
return alloc_id;
}
drop(vtables_cache);
/// Retrieves an allocation that represents the contents of a vtable.
/// Since this is a query, allocations are cached and not duplicated.
pub(super) fn vtable_allocation_provider<'tcx>(
tcx: TyCtxt<'tcx>,
key: (Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>),
) -> AllocId {
let (ty, poly_trait_ref) = key;
let vtable_entries = if let Some(poly_trait_ref) = poly_trait_ref {
let trait_ref = poly_trait_ref.with_self_ty(tcx, ty);
let trait_ref = tcx.erase_regions(trait_ref);
let vtable_entries = if let Some(poly_trait_ref) = poly_trait_ref {
let trait_ref = poly_trait_ref.with_self_ty(tcx, ty);
let trait_ref = tcx.erase_regions(trait_ref);
tcx.vtable_entries(trait_ref)
} else {
COMMON_VTABLE_ENTRIES
tcx.vtable_entries(trait_ref)
} else {
COMMON_VTABLE_ENTRIES
};
let layout = tcx
.layout_of(ty::ParamEnv::reveal_all().and(ty))
.expect("failed to build vtable representation");
assert!(!layout.is_unsized(), "can't create a vtable for an unsized type");
let size = layout.size.bytes();
let align = layout.align.abi.bytes();
let ptr_size = tcx.data_layout.pointer_size;
let ptr_align = tcx.data_layout.pointer_align.abi;
let vtable_size = ptr_size * u64::try_from(vtable_entries.len()).unwrap();
let mut vtable = Allocation::uninit(vtable_size, ptr_align, /* panic_on_fail */ true).unwrap();
// No need to do any alignment checks on the memory accesses below, because we know the
// allocation is correctly aligned as we created it above. Also we're only offsetting by
// multiples of `ptr_align`, which means that it will stay aligned to `ptr_align`.
for (idx, entry) in vtable_entries.iter().enumerate() {
let idx: u64 = u64::try_from(idx).unwrap();
let scalar = match entry {
VtblEntry::MetadataDropInPlace => {
let instance = ty::Instance::resolve_drop_in_place(tcx, ty);
let fn_alloc_id = tcx.create_fn_alloc(instance);
let fn_ptr = Pointer::from(fn_alloc_id);
ScalarMaybeUninit::from_pointer(fn_ptr, &tcx)
}
VtblEntry::MetadataSize => Scalar::from_uint(size, ptr_size).into(),
VtblEntry::MetadataAlign => Scalar::from_uint(align, ptr_size).into(),
VtblEntry::Vacant => continue,
VtblEntry::Method(instance) => {
// Prepare the fn ptr we write into the vtable.
let instance = instance.polymorphize(tcx);
let fn_alloc_id = tcx.create_fn_alloc(instance);
let fn_ptr = Pointer::from(fn_alloc_id);
ScalarMaybeUninit::from_pointer(fn_ptr, &tcx)
}
VtblEntry::TraitVPtr(trait_ref) => {
let super_trait_ref = trait_ref
.map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref));
let supertrait_alloc_id = tcx.vtable_allocation((ty, Some(super_trait_ref)));
let vptr = Pointer::from(supertrait_alloc_id);
ScalarMaybeUninit::from_pointer(vptr, &tcx)
}
};
let layout = tcx
.layout_of(ty::ParamEnv::reveal_all().and(ty))
vtable
.write_scalar(&tcx, alloc_range(ptr_size * idx, ptr_size), scalar)
.expect("failed to build vtable representation");
assert!(!layout.is_unsized(), "can't create a vtable for an unsized type");
let size = layout.size.bytes();
let align = layout.align.abi.bytes();
let ptr_size = tcx.data_layout.pointer_size;
let ptr_align = tcx.data_layout.pointer_align.abi;
let vtable_size = ptr_size * u64::try_from(vtable_entries.len()).unwrap();
let mut vtable =
Allocation::uninit(vtable_size, ptr_align, /* panic_on_fail */ true).unwrap();
// No need to do any alignment checks on the memory accesses below, because we know the
// allocation is correctly aligned as we created it above. Also we're only offsetting by
// multiples of `ptr_align`, which means that it will stay aligned to `ptr_align`.
for (idx, entry) in vtable_entries.iter().enumerate() {
let idx: u64 = u64::try_from(idx).unwrap();
let scalar = match entry {
VtblEntry::MetadataDropInPlace => {
let instance = ty::Instance::resolve_drop_in_place(tcx, ty);
let fn_alloc_id = tcx.create_fn_alloc(instance);
let fn_ptr = Pointer::from(fn_alloc_id);
ScalarMaybeUninit::from_pointer(fn_ptr, &tcx)
}
VtblEntry::MetadataSize => Scalar::from_uint(size, ptr_size).into(),
VtblEntry::MetadataAlign => Scalar::from_uint(align, ptr_size).into(),
VtblEntry::Vacant => continue,
VtblEntry::Method(instance) => {
// Prepare the fn ptr we write into the vtable.
let instance = instance.polymorphize(tcx);
let fn_alloc_id = tcx.create_fn_alloc(instance);
let fn_ptr = Pointer::from(fn_alloc_id);
ScalarMaybeUninit::from_pointer(fn_ptr, &tcx)
}
VtblEntry::TraitVPtr(trait_ref) => {
let super_trait_ref = trait_ref.map_bound(|trait_ref| {
ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
});
let supertrait_alloc_id = self.vtable_allocation(ty, Some(super_trait_ref));
let vptr = Pointer::from(supertrait_alloc_id);
ScalarMaybeUninit::from_pointer(vptr, &tcx)
}
};
vtable
.write_scalar(&tcx, alloc_range(ptr_size * idx, ptr_size), scalar)
.expect("failed to build vtable representation");
}
vtable.mutability = Mutability::Not;
let alloc_id = tcx.create_memory_alloc(tcx.intern_const_alloc(vtable));
let mut vtables_cache = self.vtables_cache.lock();
vtables_cache.insert((ty, poly_trait_ref), alloc_id);
alloc_id
}
vtable.mutability = Mutability::Not;
tcx.create_memory_alloc(tcx.intern_const_alloc(vtable))
}

View File

@ -30,7 +30,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
ensure_monomorphic_enough(*self.tcx, ty)?;
ensure_monomorphic_enough(*self.tcx, poly_trait_ref)?;
let vtable_allocation = self.tcx.vtable_allocation(ty, poly_trait_ref);
let vtable_allocation = self.tcx.vtable_allocation((ty, poly_trait_ref));
let vtable_ptr = self.memory.global_base_pointer(Pointer::from(vtable_allocation))?;

View File

@ -544,6 +544,12 @@ pub struct SimplifyBranchSame;
impl<'tcx> MirPass<'tcx> for SimplifyBranchSame {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
// This optimization is disabled by default for now due to
// soundness concerns; see issue #89485 and PR #89489.
if !tcx.sess.opts.debugging_opts.unsound_mir_opts {
return;
}
trace!("Running SimplifyBranchSame on {:?}", body.source);
let finder = SimplifyBranchSameOptimizationFinder { body, tcx };
let opts = finder.find();
@ -706,12 +712,24 @@ impl<'a, 'tcx> SimplifyBranchSameOptimizationFinder<'a, 'tcx> {
let helper = |rhs: &Rvalue<'tcx>,
place: &Place<'tcx>,
variant_index: &VariantIdx,
switch_value: u128,
side_to_choose| {
let place_type = place.ty(self.body, self.tcx).ty;
let adt = match *place_type.kind() {
ty::Adt(adt, _) if adt.is_enum() => adt,
_ => return StatementEquality::NotEqual,
};
// We need to make sure that the switch value that targets the bb with
// SetDiscriminant is the same as the variant discriminant.
let variant_discr = adt.discriminant_for_variant(self.tcx, *variant_index).val;
if variant_discr != switch_value {
trace!(
"NO: variant discriminant {} does not equal switch value {}",
variant_discr,
switch_value
);
return StatementEquality::NotEqual;
}
let variant_is_fieldless = adt.variants[*variant_index].fields.is_empty();
if !variant_is_fieldless {
trace!("NO: variant {:?} was not fieldless", variant_index);
@ -740,20 +758,28 @@ impl<'a, 'tcx> SimplifyBranchSameOptimizationFinder<'a, 'tcx> {
(
StatementKind::Assign(box (_, rhs)),
StatementKind::SetDiscriminant { place, variant_index },
)
// we need to make sure that the switch value that targets the bb with SetDiscriminant (y), is the same as the variant index
if Some(variant_index.index() as u128) == y_target_and_value.value => {
) if y_target_and_value.value.is_some() => {
// choose basic block of x, as that has the assign
helper(rhs, place, variant_index, x_target_and_value.target)
helper(
rhs,
place,
variant_index,
y_target_and_value.value.unwrap(),
x_target_and_value.target,
)
}
(
StatementKind::SetDiscriminant { place, variant_index },
StatementKind::Assign(box (_, rhs)),
)
// we need to make sure that the switch value that targets the bb with SetDiscriminant (x), is the same as the variant index
if Some(variant_index.index() as u128) == x_target_and_value.value => {
) if x_target_and_value.value.is_some() => {
// choose basic block of y, as that has the assign
helper(rhs, place, variant_index, y_target_and_value.target)
helper(
rhs,
place,
variant_index,
x_target_and_value.value.unwrap(),
y_target_and_value.target,
)
}
_ => {
trace!("NO: statements `{:?}` and `{:?}` not considered equal", x, y);

View File

@ -72,6 +72,17 @@ impl<'tcx> Key for mir::interpret::GlobalId<'tcx> {
}
}
impl<'tcx> Key for (Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>) {
#[inline(always)]
fn query_crate_is_local(&self) -> bool {
true
}
fn default_span(&self, _: TyCtxt<'_>) -> Span {
DUMMY_SP
}
}
impl<'tcx> Key for mir::interpret::LitToConstInput<'tcx> {
#[inline(always)]
fn query_crate_is_local(&self) -> bool {

View File

@ -558,6 +558,7 @@ symbols! {
dyn_metadata,
dyn_trait,
edition_macro_pats,
edition_panic,
eh_catch_typeinfo,
eh_personality,
emit_enum,

View File

@ -1391,7 +1391,7 @@ fn check_enum<'tcx>(
}
}
if tcx.adt_def(def_id).repr.int.is_none() {
if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
let is_unit = |var: &hir::Variant<'_>| matches!(var.data, hir::VariantData::Unit(..));
let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some();

View File

@ -65,6 +65,7 @@ use std::iter;
enum PlaceAncestryRelation {
Ancestor,
Descendant,
SamePlace,
Divergent,
}
@ -565,7 +566,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
for possible_ancestor in min_cap_list.iter_mut() {
match determine_place_ancestry_relation(&place, &possible_ancestor.place) {
// current place is descendant of possible_ancestor
PlaceAncestryRelation::Descendant => {
PlaceAncestryRelation::Descendant | PlaceAncestryRelation::SamePlace => {
ancestor_found = true;
let backup_path_expr_id = possible_ancestor.info.path_expr_id;
@ -2303,15 +2304,17 @@ fn determine_place_ancestry_relation(
let projections_b = &place_b.projections;
let same_initial_projections =
iter::zip(projections_a, projections_b).all(|(proj_a, proj_b)| proj_a == proj_b);
iter::zip(projections_a, projections_b).all(|(proj_a, proj_b)| proj_a.kind == proj_b.kind);
if same_initial_projections {
use std::cmp::Ordering;
// First min(n, m) projections are the same
// Select Ancestor/Descendant
if projections_b.len() >= projections_a.len() {
PlaceAncestryRelation::Ancestor
} else {
PlaceAncestryRelation::Descendant
match projections_b.len().cmp(&projections_a.len()) {
Ordering::Greater => PlaceAncestryRelation::Ancestor,
Ordering::Equal => PlaceAncestryRelation::SamePlace,
Ordering::Less => PlaceAncestryRelation::Descendant,
}
} else {
PlaceAncestryRelation::Divergent

View File

@ -776,29 +776,31 @@ fn infer_placeholder_type<'a>(
// us to improve in typeck so we do that now.
match tcx.sess.diagnostic().steal_diagnostic(span, StashKey::ItemNoType) {
Some(mut err) => {
// The parser provided a sub-optimal `HasPlaceholders` suggestion for the type.
// We are typeck and have the real type, so remove that and suggest the actual type.
err.suggestions.clear();
if !ty.references_error() {
// The parser provided a sub-optimal `HasPlaceholders` suggestion for the type.
// We are typeck and have the real type, so remove that and suggest the actual type.
err.suggestions.clear();
// Suggesting unnameable types won't help.
let mut mk_nameable = MakeNameable::new(tcx);
let ty = mk_nameable.fold_ty(ty);
let sugg_ty = if mk_nameable.success { Some(ty) } else { None };
if let Some(sugg_ty) = sugg_ty {
err.span_suggestion(
span,
&format!("provide a type for the {item}", item = kind),
format!("{}: {}", item_ident, sugg_ty),
Applicability::MachineApplicable,
);
} else {
err.span_note(
tcx.hir().body(body_id).value.span,
&format!("however, the inferred type `{}` cannot be named", ty.to_string()),
);
// Suggesting unnameable types won't help.
let mut mk_nameable = MakeNameable::new(tcx);
let ty = mk_nameable.fold_ty(ty);
let sugg_ty = if mk_nameable.success { Some(ty) } else { None };
if let Some(sugg_ty) = sugg_ty {
err.span_suggestion(
span,
&format!("provide a type for the {item}", item = kind),
format!("{}: {}", item_ident, sugg_ty),
Applicability::MachineApplicable,
);
} else {
err.span_note(
tcx.hir().body(body_id).value.span,
&format!("however, the inferred type `{}` cannot be named", ty.to_string()),
);
}
}
err.emit_unless(ty.references_error());
err.emit();
}
None => {
let mut diag = bad_placeholder_type(tcx, vec![span], kind);

View File

@ -619,6 +619,8 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
if let Some(hir::Guard::If(ref e)) = arm.guard {
self.consume_expr(e)
} else if let Some(hir::Guard::IfLet(_, ref e)) = arm.guard {
self.consume_expr(e)
}
self.consume_expr(&arm.body);

View File

@ -1 +1 @@
e6e620e1c7e7257babdfaed5c3bccbb654e72e83
09c42c45858d5f3aedfa670698275303a3d19afa

View File

@ -4,7 +4,7 @@ use super::Peekable;
///
/// This `struct` is created by [`Iterator::intersperse`]. See its documentation
/// for more information.
#[stable(feature = "iter_intersperse", since = "1.56.0")]
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
#[derive(Debug, Clone)]
pub struct Intersperse<I: Iterator>
where
@ -24,7 +24,7 @@ where
}
}
#[stable(feature = "iter_intersperse", since = "1.56.0")]
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
impl<I> Iterator for Intersperse<I>
where
I: Iterator,
@ -61,7 +61,7 @@ where
///
/// This `struct` is created by [`Iterator::intersperse_with`]. See its
/// documentation for more information.
#[stable(feature = "iter_intersperse", since = "1.56.0")]
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
pub struct IntersperseWith<I, G>
where
I: Iterator,
@ -71,7 +71,7 @@ where
needs_sep: bool,
}
#[stable(feature = "iter_intersperse", since = "1.56.0")]
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
impl<I, G> crate::fmt::Debug for IntersperseWith<I, G>
where
I: Iterator + crate::fmt::Debug,
@ -87,7 +87,7 @@ where
}
}
#[stable(feature = "iter_intersperse", since = "1.56.0")]
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
impl<I, G> crate::clone::Clone for IntersperseWith<I, G>
where
I: Iterator + crate::clone::Clone,
@ -113,7 +113,7 @@ where
}
}
#[stable(feature = "iter_intersperse", since = "1.56.0")]
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
impl<I, G> Iterator for IntersperseWith<I, G>
where
I: Iterator,

View File

@ -42,7 +42,7 @@ pub use self::flatten::Flatten;
#[stable(feature = "iter_copied", since = "1.36.0")]
pub use self::copied::Copied;
#[stable(feature = "iter_intersperse", since = "1.56.0")]
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
pub use self::intersperse::{Intersperse, IntersperseWith};
#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]

View File

@ -414,7 +414,7 @@ pub use self::adapters::{
Chain, Cycle, Enumerate, Filter, FilterMap, FlatMap, Fuse, Inspect, Map, Peekable, Rev, Scan,
Skip, SkipWhile, Take, TakeWhile, Zip,
};
#[stable(feature = "iter_intersperse", since = "1.56.0")]
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
pub use self::adapters::{Intersperse, IntersperseWith};
pub(crate) use self::adapters::process_results;

View File

@ -535,6 +535,8 @@ pub trait Iterator {
/// Basic usage:
///
/// ```
/// #![feature(iter_intersperse)]
///
/// let mut a = [0, 1, 2].iter().intersperse(&100);
/// assert_eq!(a.next(), Some(&0)); // The first element from `a`.
/// assert_eq!(a.next(), Some(&100)); // The separator.
@ -545,8 +547,9 @@ pub trait Iterator {
/// ```
///
/// `intersperse` can be very useful to join an iterator's items using a common element:
///
/// ```
/// #![feature(iter_intersperse)]
///
/// let hello = ["Hello", "World", "!"].iter().copied().intersperse(" ").collect::<String>();
/// assert_eq!(hello, "Hello World !");
/// ```
@ -554,7 +557,7 @@ pub trait Iterator {
/// [`Clone`]: crate::clone::Clone
/// [`intersperse_with`]: Iterator::intersperse_with
#[inline]
#[stable(feature = "iter_intersperse", since = "1.56.0")]
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
fn intersperse(self, separator: Self::Item) -> Intersperse<Self>
where
Self: Sized,
@ -579,6 +582,8 @@ pub trait Iterator {
/// Basic usage:
///
/// ```
/// #![feature(iter_intersperse)]
///
/// #[derive(PartialEq, Debug)]
/// struct NotClone(usize);
///
@ -595,8 +600,9 @@ pub trait Iterator {
///
/// `intersperse_with` can be used in situations where the separator needs
/// to be computed:
///
/// ```
/// #![feature(iter_intersperse)]
///
/// let src = ["Hello", "to", "all", "people", "!!"].iter().copied();
///
/// // The closure mutably borrows its context to generate an item.
@ -609,7 +615,7 @@ pub trait Iterator {
/// [`Clone`]: crate::clone::Clone
/// [`intersperse`]: Iterator::intersperse
#[inline]
#[stable(feature = "iter_intersperse", since = "1.56.0")]
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where
Self: Sized,

View File

@ -210,6 +210,7 @@ pub macro assert_matches {
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "debug_assert_macro"]
#[allow_internal_unstable(edition_panic)]
macro_rules! debug_assert {
($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert!($($arg)*); })
}

View File

@ -11,5 +11,5 @@ mod wake;
pub use self::wake::{Context, RawWaker, RawWakerVTable, Waker};
mod ready;
#[stable(feature = "ready_macro", since = "1.56.0")]
#[unstable(feature = "ready_macro", issue = "70922")]
pub use ready::ready;

View File

@ -8,6 +8,8 @@
/// # Examples
///
/// ```
/// #![feature(ready_macro)]
///
/// use std::task::{ready, Context, Poll};
/// use std::future::{self, Future};
/// use std::pin::Pin;
@ -27,6 +29,7 @@
/// The `ready!` call expands to:
///
/// ```
/// # #![feature(ready_macro)]
/// # use std::task::{Context, Poll};
/// # use std::future::{self, Future};
/// # use std::pin::Pin;
@ -45,7 +48,7 @@
/// # Poll::Ready(())
/// # }
/// ```
#[stable(feature = "ready_macro", since = "1.56.0")]
#[unstable(feature = "ready_macro", issue = "70922")]
#[rustc_macro_transparency = "semitransparent"]
pub macro ready($e:expr) {
match $e {

View File

@ -48,6 +48,7 @@
#![feature(int_log)]
#![feature(iter_advance_by)]
#![feature(iter_partition_in_place)]
#![feature(iter_intersperse)]
#![feature(iter_is_partitioned)]
#![feature(iter_order_by)]
#![feature(iter_map_while)]

View File

@ -166,6 +166,12 @@ impl Command {
fn clone3(cl_args: *mut clone_args, len: libc::size_t) -> libc::c_long
}
// Bypassing libc for `clone3` can make further libc calls unsafe,
// so we use it sparingly for now. See #89522 for details.
// Some tools (e.g. sandboxing tools) may also expect `fork`
// rather than `clone3`.
let want_clone3 = self.get_create_pidfd();
// If we fail to create a pidfd for any reason, this will
// stay as -1, which indicates an error.
let mut pidfd: pid_t = -1;
@ -173,7 +179,7 @@ impl Command {
// Attempt to use the `clone3` syscall, which supports more arguments
// (in particular, the ability to create a pidfd). If this fails,
// we will fall through this block to a call to `fork()`
if HAS_CLONE3.load(Ordering::Relaxed) {
if want_clone3 && HAS_CLONE3.load(Ordering::Relaxed) {
let mut flags = 0;
if self.get_create_pidfd() {
flags |= CLONE_PIDFD;
@ -212,8 +218,8 @@ impl Command {
}
}
// If we get here, the 'clone3' syscall does not exist
// or we do not have permission to call it
// Generally, we just call `fork`. If we get here after wanting `clone3`,
// then the syscall does not exist or we do not have permission to call it.
cvt(libc::fork()).map(|res| (res, pidfd))
}

View File

@ -1137,14 +1137,14 @@ impl Step for Assemble {
// for `-Z gcc-ld=lld`
let gcc_ld_dir = libdir_bin.join("gcc-ld");
t!(fs::create_dir(&gcc_ld_dir));
builder.copy(
&lld_install.join("bin").join(&src_exe),
&gcc_ld_dir.join(exe("ld", target_compiler.host)),
);
builder.copy(
&lld_install.join("bin").join(&src_exe),
&gcc_ld_dir.join(exe("ld64", target_compiler.host)),
);
for flavor in ["ld", "ld64"] {
let lld_wrapper_exe = builder.ensure(crate::tool::LldWrapper {
compiler: build_compiler,
target: target_compiler.host,
flavor_feature: flavor,
});
builder.copy(&lld_wrapper_exe, &gcc_ld_dir.join(exe(flavor, target_compiler.host)));
}
}
// Similarly, copy `llvm-dwp` into libdir for Split DWARF. Only copy it when the LLVM

View File

@ -409,11 +409,14 @@ impl Step for Rustc {
let rust_lld = exe("rust-lld", compiler.host);
builder.copy(&src_dir.join(&rust_lld), &dst_dir.join(&rust_lld));
// for `-Z gcc-ld=lld`
let gcc_lld_dir = dst_dir.join("gcc-ld");
t!(fs::create_dir(&gcc_lld_dir));
builder.copy(&src_dir.join(&rust_lld), &gcc_lld_dir.join(exe("ld", compiler.host)));
builder
.copy(&src_dir.join(&rust_lld), &gcc_lld_dir.join(exe("ld64", compiler.host)));
let gcc_lld_src_dir = src_dir.join("gcc-ld");
let gcc_lld_dst_dir = dst_dir.join("gcc-ld");
t!(fs::create_dir(&gcc_lld_dst_dir));
for flavor in ["ld", "ld64"] {
let exe_name = exe(flavor, compiler.host);
builder
.copy(&gcc_lld_src_dir.join(&exe_name), &gcc_lld_dst_dir.join(&exe_name));
}
}
// Copy over llvm-dwp if it's there

View File

@ -663,6 +663,38 @@ impl Step for Cargo {
}
}
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct LldWrapper {
pub compiler: Compiler,
pub target: TargetSelection,
pub flavor_feature: &'static str,
}
impl Step for LldWrapper {
type Output = PathBuf;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.never()
}
fn run(self, builder: &Builder<'_>) -> PathBuf {
let src_exe = builder
.ensure(ToolBuild {
compiler: self.compiler,
target: self.target,
tool: "lld-wrapper",
mode: Mode::ToolStd,
path: "src/tools/lld-wrapper",
is_optional_tool: false,
source_type: SourceType::InTree,
extra_features: vec![self.flavor_feature.to_owned()],
})
.expect("expected to build -- essential tool");
src_exe
}
}
macro_rules! tool_extended {
(($sel:ident, $builder:ident),
$($name:ident,

View File

@ -1 +1 @@
beta
stable

View File

@ -37,7 +37,8 @@ CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y
# CT_FORCE_DOWNLOAD is not set
CT_CONNECT_TIMEOUT=10
# CT_ONLY_DOWNLOAD is not set
# CT_USE_MIRROR is not set
CT_USE_MIRROR=y
CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc"
#
# Extracting

View File

@ -611,7 +611,7 @@ CT_ISL_V_0_20=y
# CT_ISL_V_0_15 is not set
# CT_ISL_NO_VERSIONS is not set
CT_ISL_VERSION="0.20"
CT_ISL_MIRRORS="http://isl.gforge.inria.fr"
CT_ISL_MIRRORS="https://ci-mirrors.rust-lang.org/rustc"
CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"

View File

@ -22,7 +22,8 @@ exit 1
mkdir build
cd build
cp ../arm-linux-gnueabi.config .config
ct-ng oldconfig
# FIXME ct-ng oldconfig is not working as intended.
# ct-ng oldconfig
hide_output ct-ng build
cd ..
rm -rf build

View File

@ -14,6 +14,7 @@ CT_CONFIGURE_has_autoconf_2_65_or_newer=y
CT_CONFIGURE_has_autoreconf_2_65_or_newer=y
CT_CONFIGURE_has_automake_1_15_or_newer=y
CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y
CT_CONFIGURE_has_python_3_4_or_newer=y
CT_CONFIGURE_has_bison_2_7_or_newer=y
CT_CONFIGURE_has_python=y
CT_CONFIGURE_has_git=y
@ -132,12 +133,6 @@ CT_ARCH_ARM=y
# CT_ARCH_XTENSA is not set
CT_ARCH="arm"
CT_ARCH_CHOICE_KSYM="ARM"
# CT_ARCH_ALPHA_EV4 is not set
# CT_ARCH_ALPHA_EV45 is not set
# CT_ARCH_ALPHA_EV5 is not set
# CT_ARCH_ALPHA_EV56 is not set
# CT_ARCH_ALPHA_EV6 is not set
# CT_ARCH_ALPHA_EV67 is not set
CT_ARCH_CPU=""
CT_ARCH_TUNE=""
CT_ARCH_ARM_SHOW=y
@ -372,8 +367,6 @@ CT_ALL_BINUTILS_CHOICES="BINUTILS"
# C-library
#
CT_LIBC_GLIBC=y
# CT_LIBC_NEWLIB is not set
# CT_LIBC_NONE is not set
# CT_LIBC_UCLIBC is not set
CT_LIBC="glibc"
CT_LIBC_CHOICE_KSYM="GLIBC"
@ -390,6 +383,7 @@ CT_GLIBC_USE="GLIBC"
CT_GLIBC_PKG_NAME="glibc"
CT_GLIBC_SRC_RELEASE=y
CT_GLIBC_PATCH_ORDER="global"
# CT_GLIBC_V_2_29 is not set
# CT_GLIBC_V_2_28 is not set
# CT_GLIBC_V_2_27 is not set
# CT_GLIBC_V_2_26 is not set
@ -408,7 +402,6 @@ CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
CT_GLIBC_SIGNATURE_FORMAT="packed/.sig"
CT_GLIBC_2_29_or_older=y
CT_GLIBC_older_than_2_29=y
CT_GLIBC_REQUIRE_older_than_2_29=y
CT_GLIBC_2_27_or_older=y
CT_GLIBC_older_than_2_27=y
CT_GLIBC_2_26_or_older=y
@ -448,12 +441,6 @@ CT_GLIBC_FORCE_UNWIND=y
CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y
# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set
CT_GLIBC_MIN_KERNEL="3.2.101"
# CT_GLIBC_SSP_DEFAULT is not set
# CT_GLIBC_SSP_NO is not set
# CT_GLIBC_SSP_YES is not set
# CT_GLIBC_SSP_ALL is not set
# CT_GLIBC_SSP_STRONG is not set
# CT_NEWLIB_USE_REDHAT is not set
CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC"
CT_LIBC_SUPPORT_THREADS_ANY=y
CT_LIBC_SUPPORT_THREADS_NATIVE=y
@ -625,7 +612,7 @@ CT_ISL_V_0_20=y
# CT_ISL_V_0_15 is not set
# CT_ISL_NO_VERSIONS is not set
CT_ISL_VERSION="0.20"
CT_ISL_MIRRORS="http://isl.gforge.inria.fr"
CT_ISL_MIRRORS="https://ci-mirrors.rust-lang.org/rustc"
CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"

View File

@ -22,7 +22,8 @@ exit 1
mkdir build
cd build
cp ../arm-linux-gnueabihf.config .config
ct-ng oldconfig
# FIXME ct-ng oldconfig is not working as intended.
# ct-ng oldconfig
hide_output ct-ng build
cd ..
rm -rf build

View File

@ -17,8 +17,6 @@ CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y
CT_CONFIGURE_has_python_3_4_or_newer=y
CT_CONFIGURE_has_bison_2_7_or_newer=y
CT_CONFIGURE_has_python=y
CT_CONFIGURE_has_dtc=y
CT_CONFIGURE_has_svn=y
CT_CONFIGURE_has_git=y
CT_CONFIGURE_has_md5sum=y
CT_CONFIGURE_has_sha1sum=y
@ -612,7 +610,7 @@ CT_ISL_V_0_20=y
# CT_ISL_V_0_15 is not set
# CT_ISL_NO_VERSIONS is not set
CT_ISL_VERSION="0.20"
CT_ISL_MIRRORS="http://isl.gforge.inria.fr"
CT_ISL_MIRRORS="https://ci-mirrors.rust-lang.org/rustc"
CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"

View File

@ -22,7 +22,8 @@ exit 1
mkdir build
cd build
cp ../armv7-linux-gnueabihf.config .config
ct-ng oldconfig
# FIXME ct-ng oldconfig is not working as intended.
# ct-ng oldconfig
hide_output ct-ng build
cd ..
rm -rf build

View File

@ -37,7 +37,8 @@ CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y
# CT_FORCE_DOWNLOAD is not set
CT_CONNECT_TIMEOUT=10
# CT_ONLY_DOWNLOAD is not set
# CT_USE_MIRROR is not set
CT_USE_MIRROR=y
CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc"
#
# Extracting

View File

@ -37,7 +37,8 @@ CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y
# CT_FORCE_DOWNLOAD is not set
CT_CONNECT_TIMEOUT=10
# CT_ONLY_DOWNLOAD is not set
# CT_USE_MIRROR is not set
CT_USE_MIRROR=y
CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc"
#
# Extracting

View File

@ -722,7 +722,7 @@ CT_ISL_V_0_20=y
# CT_ISL_V_0_15 is not set
# CT_ISL_NO_VERSIONS is not set
CT_ISL_VERSION="0.20"
CT_ISL_MIRRORS="http://isl.gforge.inria.fr"
CT_ISL_MIRRORS="https://ci-mirrors.rust-lang.org/rustc"
CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"

View File

@ -37,7 +37,8 @@ CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y
# CT_FORCE_DOWNLOAD is not set
CT_CONNECT_TIMEOUT=10
# CT_ONLY_DOWNLOAD is not set
# CT_USE_MIRROR is not set
CT_USE_MIRROR=y
CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc"
#
# Extracting

View File

@ -0,0 +1,37 @@
# `arbitrary_enum_discriminant`
The tracking issue for this feature is: [#60553]
[#60553]: https://github.com/rust-lang/rust/issues/60553
------------------------
The `arbitrary_enum_discriminant` feature permits tuple-like and
struct-like enum variants with `#[repr(<int-type>)]` to have explicit discriminants.
## Examples
```rust
#![feature(arbitrary_enum_discriminant)]
#[allow(dead_code)]
#[repr(u8)]
enum Enum {
Unit = 3,
Tuple(u16) = 2,
Struct {
a: u8,
b: u16,
} = 1,
}
impl Enum {
fn tag(&self) -> u8 {
unsafe { *(self as *const Self as *const u8) }
}
}
assert_eq!(3, Enum::Unit.tag());
assert_eq!(2, Enum::Tuple(5).tag());
assert_eq!(1, Enum::Struct{a: 7, b: 11}.tag());
```

View File

@ -13,6 +13,7 @@
#![feature(never_type)]
#![feature(once_cell)]
#![feature(type_ascription)]
#![feature(iter_intersperse)]
#![recursion_limit = "256"]
#![warn(rustc::internal)]

View File

@ -86,13 +86,21 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
// the rexport defines the path that a user will actually see. Accordingly,
// we add the rexport as an item here, and then skip over the original
// definition in `visit_item()` below.
//
// We also skip `#[macro_export] macro_rules!` that have already been inserted,
// it can happen if within the same module a `#[macro_export] macro_rules!`
// is declared but also a reexport of itself producing two exports of the same
// macro in the same module.
let mut inserted = FxHashSet::default();
for export in self.cx.tcx.module_exports(CRATE_DEF_ID).unwrap_or(&[]) {
if let Res::Def(DefKind::Macro(_), def_id) = export.res {
if let Some(local_def_id) = def_id.as_local() {
if self.cx.tcx.has_attr(def_id, sym::macro_export) {
let hir_id = self.cx.tcx.hir().local_def_id_to_hir_id(local_def_id);
let item = self.cx.tcx.hir().expect_item(hir_id);
top_level_module.items.push((item, None));
if inserted.insert(def_id) {
let hir_id = self.cx.tcx.hir().local_def_id_to_hir_id(local_def_id);
let item = self.cx.tcx.hir().expect_item(hir_id);
top_level_module.items.push((item, None));
}
}
}
}

View File

@ -0,0 +1,41 @@
// revisions:rpass1 rpass2
// This test case makes sure re-order the methods in a vtable will
// trigger recompilation of codegen units that instantiate it.
//
// See https://github.com/rust-lang/rust/issues/89598
trait Foo {
#[cfg(rpass1)]
fn method1(&self) -> u32;
fn method2(&self) -> u32;
#[cfg(rpass2)]
fn method1(&self) -> u32;
}
impl Foo for u32 {
fn method1(&self) -> u32 { 17 }
fn method2(&self) -> u32 { 42 }
}
fn main() {
// Before #89598 was fixed, the vtable allocation would be cached during
// a MIR optimization pass and then the codegen pass for the main object
// file would not register a dependency on it (because of the missing
// dep-tracking).
//
// In the rpass2 session, the main object file would not be re-compiled,
// thus the mod1::foo(x) call would pass in an outdated vtable, while the
// mod1 object would expect the new, re-ordered vtable, resulting in a
// call to the wrong method.
let x: &dyn Foo = &0u32;
assert_eq!(mod1::foo(x), 17);
}
mod mod1 {
pub(super) fn foo(x: &dyn super::Foo) -> u32 {
x.method1()
}
}

View File

@ -0,0 +1,17 @@
// edition:2018
#![no_core]
#![feature(no_core)]
// @count macro.json "$.index[*][?(@.name=='macro')].inner.items[*]" 2
// @set repro_id = macro.json "$.index[*][?(@.name=='repro')].id"
// @has - "$.index[*][?(@.name=='macro')].inner.items[*]" $repro_id
#[macro_export]
macro_rules! repro {
() => {};
}
// @set repro2_id = macro.json "$.index[*][?(@.inner.name=='repro2')].id"
// @has - "$.index[*][?(@.name=='macro')].inner.items[*]" $repro2_id
pub use crate::repro as repro2;

View File

@ -0,0 +1,14 @@
// edition:2018
#![no_core]
#![feature(no_core)]
// @matches 'issue_89852/sidebar-items.js' '"repro"'
// @!matches 'issue_89852/sidebar-items.js' '"repro".*"repro"'
#[macro_export]
macro_rules! repro {
() => {};
}
pub use crate::repro as repro2;

View File

@ -0,0 +1,24 @@
// edition:2021
// run-pass
#![feature(if_let_guard)]
#[allow(unused_must_use)]
#[allow(dead_code)]
fn print_error_count(registry: &Registry) {
|x: &Registry| {
match &x {
Registry if let _ = registry.try_find_description() => { }
//~^ WARNING: irrefutable `if let` guard pattern
_ => {}
}
};
}
struct Registry;
impl Registry {
pub fn try_find_description(&self) {
unimplemented!()
}
}
fn main() {}

View File

@ -0,0 +1,12 @@
warning: irrefutable `if let` guard pattern
--> $DIR/issue-88118-2.rs:10:29
|
LL | Registry if let _ = registry.try_find_description() => { }
| ^
|
= note: `#[warn(irrefutable_let_patterns)]` on by default
= note: this pattern will always match, so the guard is useless
= help: consider removing the guard and adding a `let` inside the match arm
warning: 1 warning emitted

View File

@ -0,0 +1,40 @@
// Regression test for #89606. Used to ICE.
//
// check-pass
// revisions: twenty_eighteen twenty_twentyone
// [twenty_eighteen]compile-flags: --edition 2018
// [twenty_twentyone]compile-flags: --edition 2021
struct S<'a>(Option<&'a mut i32>);
fn by_ref(s: &mut S<'_>) {
(|| {
let S(_o) = s;
s.0 = None;
})();
}
fn by_value(s: S<'_>) {
(|| {
let S(ref _o) = s;
let _g = s.0;
})();
}
struct V<'a>((Option<&'a mut i32>,));
fn nested(v: &mut V<'_>) {
(|| {
let V((_o,)) = v;
v.0 = (None, );
})();
}
fn main() {
let mut s = S(None);
by_ref(&mut s);
by_value(s);
let mut v = V((None, ));
nested(&mut v);
}

View File

@ -1,4 +1,5 @@
#![crate_type="lib"]
#![feature(arbitrary_enum_discriminant)]
enum Enum {
//~^ ERROR `#[repr(inttype)]` must be specified

View File

@ -1,5 +1,5 @@
error[E0732]: `#[repr(inttype)]` must be specified
--> $DIR/arbitrary_enum_discriminant-no-repr.rs:3:1
--> $DIR/arbitrary_enum_discriminant-no-repr.rs:4:1
|
LL | / enum Enum {
LL | |

View File

@ -1,5 +1,5 @@
// run-pass
#![feature(const_raw_ptr_deref, test)]
#![feature(arbitrary_enum_discriminant, const_raw_ptr_deref, test)]
extern crate test;

View File

@ -1,6 +1,6 @@
// run-pass
#![allow(stable_features)]
#![feature(core, core_intrinsics)]
#![feature(arbitrary_enum_discriminant, core, core_intrinsics)]
extern crate core;
use core::intrinsics::discriminant_value;

View File

@ -0,0 +1,10 @@
#![crate_type="lib"]
enum Enum {
Unit = 1,
//~^ ERROR custom discriminant values are not allowed in enums with tuple or struct variants
Tuple() = 2,
//~^ ERROR discriminants on non-unit variants are experimental
Struct{} = 3,
//~^ ERROR discriminants on non-unit variants are experimental
}

View File

@ -0,0 +1,36 @@
error[E0658]: discriminants on non-unit variants are experimental
--> $DIR/feature-gate-arbitrary_enum_discriminant.rs:6:13
|
LL | Tuple() = 2,
| ^
|
= note: see issue #60553 <https://github.com/rust-lang/rust/issues/60553> for more information
= help: add `#![feature(arbitrary_enum_discriminant)]` to the crate attributes to enable
error[E0658]: discriminants on non-unit variants are experimental
--> $DIR/feature-gate-arbitrary_enum_discriminant.rs:8:14
|
LL | Struct{} = 3,
| ^
|
= note: see issue #60553 <https://github.com/rust-lang/rust/issues/60553> for more information
= help: add `#![feature(arbitrary_enum_discriminant)]` to the crate attributes to enable
error[E0658]: custom discriminant values are not allowed in enums with tuple or struct variants
--> $DIR/feature-gate-arbitrary_enum_discriminant.rs:4:10
|
LL | Unit = 1,
| ^ disallowed custom discriminant
LL |
LL | Tuple() = 2,
| ----------- tuple variant defined here
LL |
LL | Struct{} = 3,
| ------------ struct variant defined here
|
= note: see issue #60553 <https://github.com/rust-lang/rust/issues/60553> for more information
= help: add `#![feature(arbitrary_enum_discriminant)]` to the crate attributes to enable
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@ -1,4 +1,4 @@
#![feature(core_intrinsics)]
#![feature(arbitrary_enum_discriminant, core_intrinsics)]
extern crate core;
use core::intrinsics::discriminant_value;

View File

@ -1,4 +1,4 @@
#![feature(core_intrinsics)]
#![feature(arbitrary_enum_discriminant, core_intrinsics)]
extern crate core;
use core::intrinsics::discriminant_value;

View File

@ -1,5 +1,5 @@
// run-pass
#![feature(repr128)]
#![feature(repr128, arbitrary_enum_discriminant)]
//~^ WARN the feature `repr128` is incomplete
#[derive(PartialEq, Debug)]

View File

@ -1,7 +1,7 @@
warning: the feature `repr128` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/issue-70509-partial_eq.rs:2:12
|
LL | #![feature(repr128)]
LL | #![feature(repr128, arbitrary_enum_discriminant)]
| ^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

View File

@ -5,7 +5,7 @@
// This test checks panic emitted from `mem::{uninitialized,zeroed}`.
#![feature(never_type)]
#![feature(never_type, arbitrary_enum_discriminant)]
#![allow(deprecated, invalid_value)]
use std::{

View File

@ -0,0 +1,18 @@
// Regression test for issue #89485.
// run-pass
#[derive(Debug, Eq, PartialEq)]
pub enum Type {
A = 1,
B = 2,
}
pub fn encode(v: Type) -> Type {
match v {
Type::A => Type::B,
_ => v,
}
}
fn main() {
assert_eq!(Type::B, encode(Type::A));
}

View File

@ -0,0 +1,7 @@
enum X {
A = 3,
//~^ ERROR custom discriminant values are not allowed in enums with tuple or struct variants
B(usize)
}
fn main() {}

View File

@ -0,0 +1,15 @@
error[E0658]: custom discriminant values are not allowed in enums with tuple or struct variants
--> $DIR/issue-17383.rs:2:9
|
LL | A = 3,
| ^ disallowed custom discriminant
LL |
LL | B(usize)
| -------- tuple variant defined here
|
= note: see issue #60553 <https://github.com/rust-lang/rust/issues/60553> for more information
= help: add `#![feature(arbitrary_enum_discriminant)]` to the crate attributes to enable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.

View File

@ -0,0 +1,4 @@
fn main() {
const EMPTY_ARRAY = [];
//~^ missing type for `const` item
}

View File

@ -0,0 +1,8 @@
error: missing type for `const` item
--> $DIR/issue-89574.rs:2:11
|
LL | const EMPTY_ARRAY = [];
| ^^^^^^^^^^^ help: provide a type for the item: `EMPTY_ARRAY: <type>`
error: aborting due to previous error

View File

@ -4,3 +4,4 @@ fn main() {}
const A: u8; //~ ERROR free constant item without body
const B; //~ ERROR free constant item without body
//~^ ERROR missing type for `const` item

View File

@ -14,5 +14,11 @@ LL | const B;
| |
| help: provide a definition for the constant: `= <expr>;`
error: aborting due to 2 previous errors
error: missing type for `const` item
--> $DIR/item-free-const-no-body-semantic-fail.rs:6:7
|
LL | const B;
| ^ help: provide a type for the item: `B: <type>`
error: aborting due to 3 previous errors

View File

@ -4,6 +4,8 @@ fn main() {}
static A: u8; //~ ERROR free static item without body
static B; //~ ERROR free static item without body
//~^ ERROR missing type for `static` item
static mut C: u8; //~ ERROR free static item without body
static mut D; //~ ERROR free static item without body
//~^ ERROR missing type for `static mut` item

View File

@ -15,7 +15,7 @@ LL | static B;
| help: provide a definition for the static: `= <expr>;`
error: free static item without body
--> $DIR/item-free-static-no-body-semantic-fail.rs:8:1
--> $DIR/item-free-static-no-body-semantic-fail.rs:9:1
|
LL | static mut C: u8;
| ^^^^^^^^^^^^^^^^-
@ -23,12 +23,24 @@ LL | static mut C: u8;
| help: provide a definition for the static: `= <expr>;`
error: free static item without body
--> $DIR/item-free-static-no-body-semantic-fail.rs:9:1
--> $DIR/item-free-static-no-body-semantic-fail.rs:10:1
|
LL | static mut D;
| ^^^^^^^^^^^^-
| |
| help: provide a definition for the static: `= <expr>;`
error: aborting due to 4 previous errors
error: missing type for `static` item
--> $DIR/item-free-static-no-body-semantic-fail.rs:6:8
|
LL | static B;
| ^ help: provide a type for the item: `B: <type>`
error: missing type for `static mut` item
--> $DIR/item-free-static-no-body-semantic-fail.rs:10:12
|
LL | static mut D;
| ^ help: provide a type for the item: `D: <type>`
error: aborting due to 6 previous errors

View File

@ -0,0 +1,12 @@
enum Color {
Red = 0xff0000,
//~^ ERROR custom discriminant values are not allowed in enums with tuple or struct variants
Green = 0x00ff00,
Blue = 0x0000ff,
Black = 0x000000,
White = 0xffffff,
Other(usize),
Other2(usize, usize),
}
fn main() {}

View File

@ -0,0 +1,25 @@
error[E0658]: custom discriminant values are not allowed in enums with tuple or struct variants
--> $DIR/tag-variant-disr-non-nullary.rs:2:11
|
LL | Red = 0xff0000,
| ^^^^^^^^ disallowed custom discriminant
LL |
LL | Green = 0x00ff00,
| ^^^^^^^^ disallowed custom discriminant
LL | Blue = 0x0000ff,
| ^^^^^^^^ disallowed custom discriminant
LL | Black = 0x000000,
| ^^^^^^^^ disallowed custom discriminant
LL | White = 0xffffff,
| ^^^^^^^^ disallowed custom discriminant
LL | Other(usize),
| ------------ tuple variant defined here
LL | Other2(usize, usize),
| -------------------- tuple variant defined here
|
= note: see issue #60553 <https://github.com/rust-lang/rust/issues/60553> for more information
= help: add `#![feature(arbitrary_enum_discriminant)]` to the crate attributes to enable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.

View File

@ -0,0 +1,24 @@
// edition:2021
fn main() {
debug_assert!(false, 123);
//~^ ERROR must be a string literal
assert!(false, 123);
//~^ ERROR must be a string literal
panic!(false, 123);
//~^ ERROR must be a string literal
std::debug_assert!(false, 123);
//~^ ERROR must be a string literal
std::assert!(false, 123);
//~^ ERROR must be a string literal
std::panic!(false, 123);
//~^ ERROR must be a string literal
core::debug_assert!(false, 123);
//~^ ERROR must be a string literal
core::assert!(false, 123);
//~^ ERROR must be a string literal
core::panic!(false, 123);
//~^ ERROR must be a string literal
}

View File

@ -0,0 +1,101 @@
error: format argument must be a string literal
--> $DIR/panic.rs:4:26
|
LL | debug_assert!(false, 123);
| ^^^
|
help: you might be missing a string literal to format with
|
LL | debug_assert!(false, "{}", 123);
| +++++
error: format argument must be a string literal
--> $DIR/panic.rs:6:20
|
LL | assert!(false, 123);
| ^^^
|
help: you might be missing a string literal to format with
|
LL | assert!(false, "{}", 123);
| +++++
error: format argument must be a string literal
--> $DIR/panic.rs:8:12
|
LL | panic!(false, 123);
| ^^^^^
|
help: you might be missing a string literal to format with
|
LL | panic!("{} {}", false, 123);
| ++++++++
error: format argument must be a string literal
--> $DIR/panic.rs:11:31
|
LL | std::debug_assert!(false, 123);
| ^^^
|
help: you might be missing a string literal to format with
|
LL | std::debug_assert!(false, "{}", 123);
| +++++
error: format argument must be a string literal
--> $DIR/panic.rs:13:25
|
LL | std::assert!(false, 123);
| ^^^
|
help: you might be missing a string literal to format with
|
LL | std::assert!(false, "{}", 123);
| +++++
error: format argument must be a string literal
--> $DIR/panic.rs:15:17
|
LL | std::panic!(false, 123);
| ^^^^^
|
help: you might be missing a string literal to format with
|
LL | std::panic!("{} {}", false, 123);
| ++++++++
error: format argument must be a string literal
--> $DIR/panic.rs:18:32
|
LL | core::debug_assert!(false, 123);
| ^^^
|
help: you might be missing a string literal to format with
|
LL | core::debug_assert!(false, "{}", 123);
| +++++
error: format argument must be a string literal
--> $DIR/panic.rs:20:26
|
LL | core::assert!(false, 123);
| ^^^
|
help: you might be missing a string literal to format with
|
LL | core::assert!(false, "{}", 123);
| +++++
error: format argument must be a string literal
--> $DIR/panic.rs:22:18
|
LL | core::panic!(false, 123);
| ^^^^^
|
help: you might be missing a string literal to format with
|
LL | core::panic!("{} {}", false, 123);
| ++++++++
error: aborting due to 9 previous errors

View File

@ -1,5 +1,5 @@
fn main() {
const FOO = "hello" + 1; //~ ERROR cannot add `{integer}` to `&str`
//~^ ERROR cannot add `{integer}` to `&str`
//~^ missing type for `const` item
println!("{}", FOO);
}

View File

@ -6,13 +6,11 @@ LL | const FOO = "hello" + 1;
| |
| &str
error[E0369]: cannot add `{integer}` to `&str`
--> $DIR/issue-79040.rs:2:25
error: missing type for `const` item
--> $DIR/issue-79040.rs:2:11
|
LL | const FOO = "hello" + 1;
| ------- ^ - {integer}
| |
| &str
| ^^^ help: provide a type for the item: `FOO: <type>`
error: aborting due to 2 previous errors

View File

@ -0,0 +1,11 @@
[package]
name = "lld-wrapper"
version = "0.1.0"
edition = "2018"
license = "MIT OR Apache-2.0"
[dependencies]
[features]
ld = []
ld64 = []

View File

@ -0,0 +1,125 @@
//! Script to invoke the bundled rust-lld with the correct flavor. The flavor is selected by
//! feature.
//!
//! lld supports multiple command line interfaces. If `-flavor <flavor>` are passed as the first
//! two arguments the `<flavor>` command line interface is used to process the remaining arguments.
//! If no `-flavor` argument is present the flavor is determined by the executable name.
//!
//! In Rust with `-Z gcc-ld=lld` we have gcc or clang invoke rust-lld. Since there is no way to
//! make gcc/clang pass `-flavor <flavor>` as the first two arguments in the linker invocation
//! and since Windows does not support symbolic links for files this wrapper is used in place of a
//! symblic link. It execs `../rust-lld -flavor ld` if the feature `ld` is enabled and
//! `../rust-lld -flavor ld64` if `ld64` is enabled. On Windows it spawns a `..\rust-lld.exe`
//! child process.
#[cfg(not(any(feature = "ld", feature = "ld64")))]
compile_error!("One of the features ld and ld64 must be enabled.");
#[cfg(all(feature = "ld", feature = "ld64"))]
compile_error!("Only one of the feature ld or ld64 can be enabled.");
#[cfg(feature = "ld")]
const FLAVOR: &str = "ld";
#[cfg(feature = "ld64")]
const FLAVOR: &str = "ld64";
use std::env;
use std::fmt::Display;
use std::path::{Path, PathBuf};
use std::process;
trait ResultExt<T, E> {
fn unwrap_or_exit_with(self, context: &str) -> T;
}
impl<T, E> ResultExt<T, E> for Result<T, E>
where
E: Display,
{
fn unwrap_or_exit_with(self, context: &str) -> T {
match self {
Ok(t) => t,
Err(e) => {
eprintln!("lld-wrapper: {}: {}", context, e);
process::exit(1);
}
}
}
}
trait OptionExt<T> {
fn unwrap_or_exit_with(self, context: &str) -> T;
}
impl<T> OptionExt<T> for Option<T> {
fn unwrap_or_exit_with(self, context: &str) -> T {
match self {
Some(t) => t,
None => {
eprintln!("lld-wrapper: {}", context);
process::exit(1);
}
}
}
}
/// Returns the path to rust-lld in the parent directory.
///
/// Exits if the parent directory cannot be determined.
fn get_rust_lld_path(current_exe_path: &Path) -> PathBuf {
let mut rust_lld_exe_name = "rust-lld".to_owned();
rust_lld_exe_name.push_str(env::consts::EXE_SUFFIX);
let mut rust_lld_path = current_exe_path
.parent()
.unwrap_or_exit_with("directory containing current executable could not be determined")
.parent()
.unwrap_or_exit_with("parent directory could not be determined")
.to_owned();
rust_lld_path.push(rust_lld_exe_name);
rust_lld_path
}
/// Returns the command for invoking rust-lld with the correct flavor.
///
/// Exits on error.
fn get_rust_lld_command(current_exe_path: &Path) -> process::Command {
let rust_lld_path = get_rust_lld_path(current_exe_path);
let mut command = process::Command::new(rust_lld_path);
command.arg("-flavor");
command.arg(FLAVOR);
command.args(env::args_os().skip(1));
command
}
#[cfg(unix)]
fn exec_lld(mut command: process::Command) {
use std::os::unix::prelude::CommandExt;
Result::<(), _>::Err(command.exec()).unwrap_or_exit_with("could not exec rust-lld");
unreachable!("lld-wrapper: after exec without error");
}
#[cfg(not(unix))]
fn exec_lld(mut command: process::Command) {
// Windows has no exec(), spawn a child process and wait for it
let exit_status = command.status().unwrap_or_exit_with("error running rust-lld child process");
if !exit_status.success() {
match exit_status.code() {
Some(code) => {
// return the original lld exit code
process::exit(code)
}
None => {
eprintln!("lld-wrapper: rust-lld child process exited with error: {}", exit_status,);
process::exit(1);
}
}
}
}
fn main() {
let current_exe_path =
env::current_exe().unwrap_or_exit_with("could not get the path of the current executable");
exec_lld(get_rust_lld_command(current_exe_path.as_ref()));
}

View File

@ -1 +1 @@
1.56.0-beta.4 (e6e620e1c 2021-10-04)
1.56.0 (09c42c458 2021-10-18)