Merge ref '3f1552a273' from rust-lang/rust
Pull recent changes from https://github.com/rust-lang/rust via Josh. Upstream ref:3f1552a273Filtered ref: fbfa7b30a3ad5abd6a5db7e3ef15adc8da1ecc37 Upstream diff:9d82de19df...3f1552a273This merge was created using https://github.com/rust-lang/josh-sync.
This commit is contained in:
commit
1672251dad
132 changed files with 2532 additions and 1820 deletions
1
.mailmap
1
.mailmap
|
|
@ -609,6 +609,7 @@ Shohei Wada <pc@wada314.jp>
|
|||
Shotaro Yamada <sinkuu@sinkuu.xyz>
|
||||
Shotaro Yamada <sinkuu@sinkuu.xyz> <sinkuu@users.noreply.github.com>
|
||||
Shyam Sundar B <shyambaskaran@outlook.com>
|
||||
Sidney Cammeresi <sac@cheesecake.org> <sac@readyset.io>
|
||||
Simon Barber-Dueck <sbarberdueck@gmail.com> Simon BD <simon@server>
|
||||
Simon Sapin <simon@exyr.org> <simon.sapin@exyr.org>
|
||||
Simonas Kazlauskas <git@kazlauskas.me> Simonas Kazlauskas <github@kazlauskas.me>
|
||||
|
|
|
|||
|
|
@ -4817,9 +4817,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustfix"
|
||||
version = "0.8.1"
|
||||
version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81864b097046da5df3758fdc6e4822bbb70afa06317e8ca45ea1b51cb8c5e5a4"
|
||||
checksum = "82fa69b198d894d84e23afde8e9ab2af4400b2cba20d6bf2b428a8b01c222c5a"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
|
|
|||
126
RELEASES.md
126
RELEASES.md
|
|
@ -1,3 +1,129 @@
|
|||
Version 1.90 (2025-09-18)
|
||||
==========================
|
||||
|
||||
<a id="1.90-Language"></a>
|
||||
|
||||
Language
|
||||
--------
|
||||
- [Split up the `unknown_or_malformed_diagnostic_attributes` lint](https://github.com/rust-lang/rust/pull/140717). This lint has been split up into four finer-grained lints, with `unknown_or_malformed_diagnostic_attributes` now being the lint group that contains these lints:
|
||||
1. `unknown_diagnostic_attributes`: unknown to the current compiler
|
||||
2. `misplaced_diagnostic_attributes`: placed on the wrong item
|
||||
3. `malformed_diagnostic_attributes`: malformed attribute syntax or options
|
||||
4. `malformed_diagnostic_format_literals`: malformed format string literal
|
||||
- [Allow constants whose final value has references to mutable/external memory, but reject such constants as patterns](https://github.com/rust-lang/rust/pull/140942)
|
||||
- [Allow volatile access to non-Rust memory, including address 0](https://github.com/rust-lang/rust/pull/141260)
|
||||
|
||||
|
||||
<a id="1.90-Compiler"></a>
|
||||
|
||||
Compiler
|
||||
--------
|
||||
- [Use `lld` by default on `x86_64-unknown-linux-gnu`](https://github.com/rust-lang/rust/pull/140525).
|
||||
- [Tier 3 `musl` targets now link dynamically by default](https://github.com/rust-lang/rust/pull/144410). Affected targets:
|
||||
- `mips64-unknown-linux-muslabi64`
|
||||
- `powerpc64-unknown-linux-musl`
|
||||
- `powerpc-unknown-linux-musl`
|
||||
- `powerpc-unknown-linux-muslspe`
|
||||
- `riscv32gc-unknown-linux-musl`
|
||||
- `s390x-unknown-linux-musl`
|
||||
- `thumbv7neon-unknown-linux-musleabihf`
|
||||
|
||||
|
||||
<a id="1.90-Platform-Support"></a>
|
||||
|
||||
Platform Support
|
||||
----------------
|
||||
- [Demote `x86_64-apple-darwin` to Tier 2 with host tools](https://github.com/rust-lang/rust/pull/145252)
|
||||
|
||||
|
||||
Refer to Rust's [platform support page][platform-support-doc]
|
||||
for more information on Rust's tiered platform support.
|
||||
|
||||
[platform-support-doc]: https://doc.rust-lang.org/rustc/platform-support.html
|
||||
|
||||
<a id="1.90-Libraries"></a>
|
||||
|
||||
Libraries
|
||||
---------
|
||||
- [Stabilize `u*::{checked,overflowing,saturating,wrapping}_sub_signed`](https://github.com/rust-lang/rust/issues/126043)
|
||||
- [Allow comparisons between `CStr`, `CString`, and `Cow<CStr>`](https://github.com/rust-lang/rust/pull/137268)
|
||||
- [Remove some unsized tuple impls since unsized tuples can't be constructed](https://github.com/rust-lang/rust/pull/138340)
|
||||
- [Set `MSG_NOSIGNAL` for `UnixStream`](https://github.com/rust-lang/rust/pull/140005)
|
||||
- [`proc_macro::Ident::new` now supports `$crate`.](https://github.com/rust-lang/rust/pull/141996)
|
||||
- [Guarantee the pointer returned from `Thread::into_raw` has at least 8 bytes of alignment](https://github.com/rust-lang/rust/pull/143859)
|
||||
|
||||
|
||||
<a id="1.90-Stabilized-APIs"></a>
|
||||
|
||||
Stabilized APIs
|
||||
---------------
|
||||
|
||||
- [`u{n}::checked_sub_signed`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.checked_sub_signed)
|
||||
- [`u{n}::overflowing_sub_signed`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.overflowing_sub_signed)
|
||||
- [`u{n}::saturating_sub_signed`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.saturating_sub_signed)
|
||||
- [`u{n}::wrapping_sub_signed`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.wrapping_sub_signed)
|
||||
- [`impl Copy for IntErrorKind`](https://doc.rust-lang.org/stable/std/num/enum.IntErrorKind.html#impl-Copy-for-IntErrorKind)
|
||||
- [`impl Hash for IntErrorKind`](https://doc.rust-lang.org/stable/std/num/enum.IntErrorKind.html#impl-Hash-for-IntErrorKind)
|
||||
- [`impl PartialEq<&CStr> for CStr`](https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#impl-PartialEq%3C%26CStr%3E-for-CStr)
|
||||
- [`impl PartialEq<CString> for CStr`](https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#impl-PartialEq%3CCString%3E-for-CStr)
|
||||
- [`impl PartialEq<Cow<CStr>> for CStr`](https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#impl-PartialEq%3CCow%3C'_,+CStr%3E%3E-for-CStr)
|
||||
- [`impl PartialEq<&CStr> for CString`](https://doc.rust-lang.org/stable/std/ffi/struct.CString.html#impl-PartialEq%3C%26CStr%3E-for-CString)
|
||||
- [`impl PartialEq<CStr> for CString`](https://doc.rust-lang.org/stable/std/ffi/struct.CString.html#impl-PartialEq%3CCStr%3E-for-CString)
|
||||
- [`impl PartialEq<Cow<CStr>> for CString`](https://doc.rust-lang.org/stable/std/ffi/struct.CString.html#impl-PartialEq%3CCow%3C'_,+CStr%3E%3E-for-CString)
|
||||
- [`impl PartialEq<&CStr> for Cow<CStr>`](https://doc.rust-lang.org/stable/std/borrow/enum.Cow.html#impl-PartialEq%3C%26CStr%3E-for-Cow%3C'_,+CStr%3E)
|
||||
- [`impl PartialEq<CStr> for Cow<CStr>`](https://doc.rust-lang.org/stable/std/borrow/enum.Cow.html#impl-PartialEq%3CCStr%3E-for-Cow%3C'_,+CStr%3E)
|
||||
- [`impl PartialEq<CString> for Cow<CStr>`](https://doc.rust-lang.org/stable/std/borrow/enum.Cow.html#impl-PartialEq%3CCString%3E-for-Cow%3C'_,+CStr%3E)
|
||||
|
||||
|
||||
These previously stable APIs are now stable in const contexts:
|
||||
|
||||
- [`<[T]>::reverse`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.reverse)
|
||||
- [`f32::floor`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.floor)
|
||||
- [`f32::ceil`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.ceil)
|
||||
- [`f32::trunc`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.trunc)
|
||||
- [`f32::fract`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.fract)
|
||||
- [`f32::round`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.round)
|
||||
- [`f32::round_ties_even`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.round_ties_even)
|
||||
- [`f64::floor`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.floor)
|
||||
- [`f64::ceil`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.ceil)
|
||||
- [`f64::trunc`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.trunc)
|
||||
- [`f64::fract`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.fract)
|
||||
- [`f64::round`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.round)
|
||||
- [`f64::round_ties_even`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.round_ties_even)
|
||||
|
||||
|
||||
<a id="1.90-Cargo"></a>
|
||||
|
||||
Cargo
|
||||
-----
|
||||
- [Add `http.proxy-cainfo` config for proxy certs](https://github.com/rust-lang/cargo/pull/15374/)
|
||||
- [Use `gix` for `cargo package`](https://github.com/rust-lang/cargo/pull/15534/)
|
||||
- [feat(publish): Stabilize multi-package publishing](https://github.com/rust-lang/cargo/pull/15636/)
|
||||
|
||||
<a id="1.90-Rustdoc"></a>
|
||||
|
||||
Rustdoc
|
||||
-----
|
||||
- [Add ways to collapse all impl blocks](https://github.com/rust-lang/rust/pull/141663). Previously the "Summary" button and "-" keyboard shortcut would never collapse `impl` blocks, now they do when shift is held
|
||||
- [Display unsafe attributes with `unsafe()` wrappers](https://github.com/rust-lang/rust/pull/143662)
|
||||
|
||||
|
||||
<a id="1.90-Compatibility-Notes"></a>
|
||||
|
||||
Compatibility Notes
|
||||
-------------------
|
||||
- [Use `lld` by default on `x86_64-unknown-linux-gnu`](https://github.com/rust-lang/rust/pull/140525).
|
||||
See also <https://blog.rust-lang.org/2025/09/01/rust-lld-on-1.90.0-stable/>.
|
||||
- [Make `core::iter::Fuse`'s `Default` impl construct `I::default()` internally as promised in the docs instead of always being empty](https://github.com/rust-lang/rust/pull/140985)
|
||||
- [Set `MSG_NOSIGNAL` for `UnixStream`](https://github.com/rust-lang/rust/pull/140005)
|
||||
This may change program behavior but results in the same behavior as other primitives (e.g., stdout, network sockets).
|
||||
Programs relying on signals to terminate them should update handling of sockets to handle errors on write by exiting.
|
||||
- [On Unix `std::env::home_dir` will use the fallback if the `HOME` environment variable is empty](https://github.com/rust-lang/rust/pull/141840)
|
||||
- We now [reject unsupported `extern "{abi}"`s consistently in all positions](https://github.com/rust-lang/rust/pull/142134). This primarily affects the use of implementing traits on an `extern "{abi}"` function pointer, like `extern "stdcall" fn()`, on a platform that doesn't support that, like aarch64-unknown-linux-gnu. Direct usage of these unsupported ABI strings by declaring or defining functions was already rejected, so this is only a change for consistency.
|
||||
- [const-eval: error when initializing a static writes to that static](https://github.com/rust-lang/rust/pull/143084)
|
||||
- [Check that the `proc_macro_derive` macro has correct arguments when applied to the crate root](https://github.com/rust-lang/rust/pull/143607)
|
||||
|
||||
|
||||
Version 1.89.0 (2025-08-07)
|
||||
==========================
|
||||
|
||||
|
|
|
|||
|
|
@ -51,43 +51,4 @@ pub(crate) fn expand_deriving_const_param_ty(
|
|||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push);
|
||||
|
||||
let trait_def = TraitDef {
|
||||
span,
|
||||
path: path_std!(marker::UnsizedConstParamTy),
|
||||
skip_path_as_bound: false,
|
||||
needs_copy_as_bound_if_packed: false,
|
||||
additional_bounds: vec![ty::Ty::Path(path_std!(cmp::Eq))],
|
||||
supports_unions: false,
|
||||
methods: Vec::new(),
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push);
|
||||
}
|
||||
|
||||
pub(crate) fn expand_deriving_unsized_const_param_ty(
|
||||
cx: &ExtCtxt<'_>,
|
||||
span: Span,
|
||||
mitem: &MetaItem,
|
||||
item: &Annotatable,
|
||||
push: &mut dyn FnMut(Annotatable),
|
||||
is_const: bool,
|
||||
) {
|
||||
let trait_def = TraitDef {
|
||||
span,
|
||||
path: path_std!(marker::UnsizedConstParamTy),
|
||||
skip_path_as_bound: false,
|
||||
needs_copy_as_bound_if_packed: false,
|
||||
additional_bounds: vec![ty::Ty::Path(path_std!(cmp::Eq))],
|
||||
supports_unions: false,
|
||||
methods: Vec::new(),
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,7 +129,6 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
|
|||
Clone: clone::expand_deriving_clone,
|
||||
Copy: bounds::expand_deriving_copy,
|
||||
ConstParamTy: bounds::expand_deriving_const_param_ty,
|
||||
UnsizedConstParamTy: bounds::expand_deriving_unsized_const_param_ty,
|
||||
Debug: debug::expand_deriving_debug,
|
||||
Default: default::expand_deriving_default,
|
||||
Eq: eq::expand_deriving_eq,
|
||||
|
|
|
|||
|
|
@ -240,6 +240,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
|||
}
|
||||
InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
|
||||
constraints.extend_from_slice(&[
|
||||
"~{fflags}".to_string(),
|
||||
"~{vtype}".to_string(),
|
||||
"~{vl}".to_string(),
|
||||
"~{vxsat}".to_string(),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use itertools::Itertools as _;
|
||||
use rustc_abi::{self as abi, FIRST_VARIANT};
|
||||
use rustc_abi::{self as abi, BackendRepr, FIRST_VARIANT};
|
||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
|
||||
|
|
@ -25,6 +25,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
match *rvalue {
|
||||
mir::Rvalue::Use(ref operand) => {
|
||||
let cg_operand = self.codegen_operand(bx, operand);
|
||||
// Crucially, we do *not* use `OperandValue::Ref` for types with
|
||||
// `BackendRepr::Scalar | BackendRepr::ScalarPair`. This ensures we match the MIR
|
||||
// semantics regarding when assignment operators allow overlap of LHS and RHS.
|
||||
if matches!(
|
||||
cg_operand.layout.backend_repr,
|
||||
BackendRepr::Scalar(..) | BackendRepr::ScalarPair(..),
|
||||
) {
|
||||
debug_assert!(!matches!(cg_operand.val, OperandValue::Ref(..)));
|
||||
}
|
||||
// FIXME: consider not copying constants through stack. (Fixable by codegen'ing
|
||||
// constants into `OperandValue::Ref`; why don’t we do that yet if we don’t?)
|
||||
cg_operand.val.store(bx, dest);
|
||||
|
|
|
|||
|
|
@ -858,7 +858,7 @@ where
|
|||
/// Also, if you use this you are responsible for validating that things get copied at the
|
||||
/// right type.
|
||||
#[instrument(skip(self), level = "trace")]
|
||||
fn copy_op_no_validate(
|
||||
pub(super) fn copy_op_no_validate(
|
||||
&mut self,
|
||||
src: &impl Projectable<'tcx, M::Provenance>,
|
||||
dest: &impl Writeable<'tcx, M::Provenance>,
|
||||
|
|
|
|||
|
|
@ -310,7 +310,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
operands: &IndexSlice<FieldIdx, mir::Operand<'tcx>>,
|
||||
dest: &PlaceTy<'tcx, M::Provenance>,
|
||||
) -> InterpResult<'tcx> {
|
||||
self.write_uninit(dest)?; // make sure all the padding ends up as uninit
|
||||
let (variant_index, variant_dest, active_field_index) = match *kind {
|
||||
mir::AggregateKind::Adt(_, variant_index, _, _, active_field_index) => {
|
||||
let variant_dest = self.project_downcast(dest, variant_index)?;
|
||||
|
|
@ -346,9 +345,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
let field_index = active_field_index.unwrap_or(field_index);
|
||||
let field_dest = self.project_field(&variant_dest, field_index)?;
|
||||
let op = self.eval_operand(operand, Some(field_dest.layout))?;
|
||||
self.copy_op(&op, &field_dest)?;
|
||||
// We validate manually below so we don't have to do it here.
|
||||
self.copy_op_no_validate(&op, &field_dest, /*allow_transmute*/ false)?;
|
||||
}
|
||||
self.write_discriminant(variant_index, dest)
|
||||
self.write_discriminant(variant_index, dest)?;
|
||||
// Validate that the entire thing is valid, and reset padding that might be in between the
|
||||
// fields.
|
||||
if M::enforce_validity(self, dest.layout()) {
|
||||
self.validate_operand(
|
||||
dest,
|
||||
M::enforce_validity_recursively(self, dest.layout()),
|
||||
/*reset_provenance_and_padding*/ true,
|
||||
)?;
|
||||
}
|
||||
interp_ok(())
|
||||
}
|
||||
|
||||
/// Repeats `operand` into the destination. `dest` must have array type, and that type
|
||||
|
|
|
|||
|
|
@ -370,7 +370,6 @@ language_item_table! {
|
|||
CoercePointeeValidated, sym::coerce_pointee_validated, coerce_pointee_validated_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
|
||||
ConstParamTy, sym::const_param_ty, const_param_ty_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
UnsizedConstParamTy, sym::unsized_const_param_ty, unsized_const_param_ty_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
|
||||
Poll, sym::Poll, poll, Target::Enum, GenericRequirement::None;
|
||||
PollReady, sym::Ready, poll_ready_variant, Target::Variant, GenericRequirement::None;
|
||||
|
|
|
|||
|
|
@ -819,17 +819,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &ty::GenericParamDef) -> Result<(), Er
|
|||
let span = tcx.def_span(param.def_id);
|
||||
let def_id = param.def_id.expect_local();
|
||||
|
||||
if tcx.features().unsized_const_params() {
|
||||
enter_wf_checking_ctxt(tcx, tcx.local_parent(def_id), |wfcx| {
|
||||
wfcx.register_bound(
|
||||
ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(ty)),
|
||||
wfcx.param_env,
|
||||
ty,
|
||||
tcx.require_lang_item(LangItem::UnsizedConstParamTy, span),
|
||||
);
|
||||
Ok(())
|
||||
})
|
||||
} else if tcx.features().adt_const_params() {
|
||||
if tcx.features().adt_const_params() {
|
||||
enter_wf_checking_ctxt(tcx, tcx.local_parent(def_id), |wfcx| {
|
||||
wfcx.register_bound(
|
||||
ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(ty)),
|
||||
|
|
@ -880,7 +870,6 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &ty::GenericParamDef) -> Result<(), Er
|
|||
tcx,
|
||||
tcx.param_env(param.def_id),
|
||||
ty,
|
||||
LangItem::ConstParamTy,
|
||||
cause,
|
||||
) {
|
||||
// Can never implement `ConstParamTy`, don't suggest anything.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
//! Check properties that are required by built-in traits and set
|
||||
//! up data structures required by type-checking/codegen.
|
||||
|
||||
use std::assert_matches::assert_matches;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
|
|
@ -40,10 +39,7 @@ pub(super) fn check_trait<'tcx>(
|
|||
checker.check(lang_items.async_drop_trait(), visit_implementation_of_drop)?;
|
||||
checker.check(lang_items.copy_trait(), visit_implementation_of_copy)?;
|
||||
checker.check(lang_items.const_param_ty_trait(), |checker| {
|
||||
visit_implementation_of_const_param_ty(checker, LangItem::ConstParamTy)
|
||||
})?;
|
||||
checker.check(lang_items.unsized_const_param_ty_trait(), |checker| {
|
||||
visit_implementation_of_const_param_ty(checker, LangItem::UnsizedConstParamTy)
|
||||
visit_implementation_of_const_param_ty(checker)
|
||||
})?;
|
||||
checker.check(lang_items.coerce_unsized_trait(), visit_implementation_of_coerce_unsized)?;
|
||||
checker
|
||||
|
|
@ -138,12 +134,7 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_implementation_of_const_param_ty(
|
||||
checker: &Checker<'_>,
|
||||
kind: LangItem,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
assert_matches!(kind, LangItem::ConstParamTy | LangItem::UnsizedConstParamTy);
|
||||
|
||||
fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
|
||||
let tcx = checker.tcx;
|
||||
let header = checker.impl_header;
|
||||
let impl_did = checker.impl_def_id;
|
||||
|
|
@ -157,7 +148,7 @@ fn visit_implementation_of_const_param_ty(
|
|||
}
|
||||
|
||||
let cause = traits::ObligationCause::misc(DUMMY_SP, impl_did);
|
||||
match type_allowed_to_implement_const_param_ty(tcx, param_env, self_type, kind, cause) {
|
||||
match type_allowed_to_implement_const_param_ty(tcx, param_env, self_type, cause) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(ConstParamTyImplementationError::InfrigingFields(fields)) => {
|
||||
let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -72,12 +72,27 @@ pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx {
|
|||
self.register_predicate_obligation(infcx, obligation);
|
||||
}
|
||||
}
|
||||
|
||||
/// Go over the list of pending obligations and try to evaluate them.
|
||||
///
|
||||
/// For each result:
|
||||
/// Ok: remove the obligation from the list
|
||||
/// Ambiguous: leave the obligation in the list to be evaluated later
|
||||
/// Err: remove the obligation from the list and return an error
|
||||
///
|
||||
/// Returns a list of errors from obligations that evaluated to Err.
|
||||
#[must_use]
|
||||
fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<E>;
|
||||
|
||||
fn collect_remaining_errors(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<E>;
|
||||
|
||||
/// Evaluate all pending obligations, return error if they can't be evaluated.
|
||||
///
|
||||
/// For each result:
|
||||
/// Ok: remove the obligation from the list
|
||||
/// Ambiguous: remove the obligation from the list and return an error
|
||||
/// Err: remove the obligation from the list and return an error
|
||||
///
|
||||
/// Returns a list of errors from obligations that evaluated to Ambiguous or Err.
|
||||
#[must_use]
|
||||
fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<E> {
|
||||
let errors = self.select_where_possible(infcx);
|
||||
|
|
|
|||
|
|
@ -843,6 +843,10 @@ trait UnusedDelimLint {
|
|||
&& !snip.ends_with(' ')
|
||||
{
|
||||
" "
|
||||
} else if let Ok(snip) = sm.span_to_prev_source(value_span)
|
||||
&& snip.ends_with(|c: char| c.is_alphanumeric())
|
||||
{
|
||||
" "
|
||||
} else {
|
||||
""
|
||||
};
|
||||
|
|
@ -852,6 +856,10 @@ trait UnusedDelimLint {
|
|||
&& !snip.starts_with(' ')
|
||||
{
|
||||
" "
|
||||
} else if let Ok(snip) = sm.span_to_prev_source(value_span)
|
||||
&& snip.starts_with(|c: char| c.is_alphanumeric())
|
||||
{
|
||||
" "
|
||||
} else {
|
||||
""
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ const OPTIONAL_COMPONENTS: &[&str] = &[
|
|||
"mips",
|
||||
"powerpc",
|
||||
"systemz",
|
||||
"jsbackend",
|
||||
"webassembly",
|
||||
"msp430",
|
||||
"sparc",
|
||||
|
|
|
|||
|
|
@ -79,122 +79,6 @@ extern "C" void LLVMRustTimeTraceProfilerFinish(const char *FileName) {
|
|||
timeTraceProfilerCleanup();
|
||||
}
|
||||
|
||||
#ifdef LLVM_COMPONENT_X86
|
||||
#define SUBTARGET_X86 SUBTARGET(X86)
|
||||
#else
|
||||
#define SUBTARGET_X86
|
||||
#endif
|
||||
|
||||
#ifdef LLVM_COMPONENT_ARM
|
||||
#define SUBTARGET_ARM SUBTARGET(ARM)
|
||||
#else
|
||||
#define SUBTARGET_ARM
|
||||
#endif
|
||||
|
||||
#ifdef LLVM_COMPONENT_AARCH64
|
||||
#define SUBTARGET_AARCH64 SUBTARGET(AArch64)
|
||||
#else
|
||||
#define SUBTARGET_AARCH64
|
||||
#endif
|
||||
|
||||
#ifdef LLVM_COMPONENT_AVR
|
||||
#define SUBTARGET_AVR SUBTARGET(AVR)
|
||||
#else
|
||||
#define SUBTARGET_AVR
|
||||
#endif
|
||||
|
||||
#ifdef LLVM_COMPONENT_M68k
|
||||
#define SUBTARGET_M68K SUBTARGET(M68k)
|
||||
#else
|
||||
#define SUBTARGET_M68K
|
||||
#endif
|
||||
|
||||
#ifdef LLVM_COMPONENT_CSKY
|
||||
#define SUBTARGET_CSKY SUBTARGET(CSKY)
|
||||
#else
|
||||
#define SUBTARGET_CSKY
|
||||
#endif
|
||||
|
||||
#ifdef LLVM_COMPONENT_MIPS
|
||||
#define SUBTARGET_MIPS SUBTARGET(Mips)
|
||||
#else
|
||||
#define SUBTARGET_MIPS
|
||||
#endif
|
||||
|
||||
#ifdef LLVM_COMPONENT_POWERPC
|
||||
#define SUBTARGET_PPC SUBTARGET(PPC)
|
||||
#else
|
||||
#define SUBTARGET_PPC
|
||||
#endif
|
||||
|
||||
#ifdef LLVM_COMPONENT_SYSTEMZ
|
||||
#define SUBTARGET_SYSTEMZ SUBTARGET(SystemZ)
|
||||
#else
|
||||
#define SUBTARGET_SYSTEMZ
|
||||
#endif
|
||||
|
||||
#ifdef LLVM_COMPONENT_MSP430
|
||||
#define SUBTARGET_MSP430 SUBTARGET(MSP430)
|
||||
#else
|
||||
#define SUBTARGET_MSP430
|
||||
#endif
|
||||
|
||||
#ifdef LLVM_COMPONENT_RISCV
|
||||
#define SUBTARGET_RISCV SUBTARGET(RISCV)
|
||||
#else
|
||||
#define SUBTARGET_RISCV
|
||||
#endif
|
||||
|
||||
#ifdef LLVM_COMPONENT_SPARC
|
||||
#define SUBTARGET_SPARC SUBTARGET(Sparc)
|
||||
#else
|
||||
#define SUBTARGET_SPARC
|
||||
#endif
|
||||
|
||||
#ifdef LLVM_COMPONENT_XTENSA
|
||||
#define SUBTARGET_XTENSA SUBTARGET(XTENSA)
|
||||
#else
|
||||
#define SUBTARGET_XTENSA
|
||||
#endif
|
||||
|
||||
#ifdef LLVM_COMPONENT_HEXAGON
|
||||
#define SUBTARGET_HEXAGON SUBTARGET(Hexagon)
|
||||
#else
|
||||
#define SUBTARGET_HEXAGON
|
||||
#endif
|
||||
|
||||
#ifdef LLVM_COMPONENT_LOONGARCH
|
||||
#define SUBTARGET_LOONGARCH SUBTARGET(LoongArch)
|
||||
#else
|
||||
#define SUBTARGET_LOONGARCH
|
||||
#endif
|
||||
|
||||
#define GEN_SUBTARGETS \
|
||||
SUBTARGET_X86 \
|
||||
SUBTARGET_ARM \
|
||||
SUBTARGET_AARCH64 \
|
||||
SUBTARGET_AVR \
|
||||
SUBTARGET_M68K \
|
||||
SUBTARGET_CSKY \
|
||||
SUBTARGET_MIPS \
|
||||
SUBTARGET_PPC \
|
||||
SUBTARGET_SYSTEMZ \
|
||||
SUBTARGET_MSP430 \
|
||||
SUBTARGET_SPARC \
|
||||
SUBTARGET_HEXAGON \
|
||||
SUBTARGET_XTENSA \
|
||||
SUBTARGET_RISCV \
|
||||
SUBTARGET_LOONGARCH
|
||||
|
||||
#define SUBTARGET(x) \
|
||||
namespace llvm { \
|
||||
extern const SubtargetFeatureKV x##FeatureKV[]; \
|
||||
extern const SubtargetFeatureKV x##SubTypeKV[]; \
|
||||
}
|
||||
|
||||
GEN_SUBTARGETS
|
||||
#undef SUBTARGET
|
||||
|
||||
// This struct and various functions are sort of a hack right now, but the
|
||||
// problem is that we've got in-memory LLVM modules after we generate and
|
||||
// optimize all codegen-units for one compilation in rustc. To be compatible
|
||||
|
|
@ -340,14 +224,6 @@ static FloatABI::ABIType fromRust(LLVMRustFloatABI RustFloatAbi) {
|
|||
report_fatal_error("Bad FloatABI.");
|
||||
}
|
||||
|
||||
/// getLongestEntryLength - Return the length of the longest entry in the table.
|
||||
template <typename KV> static size_t getLongestEntryLength(ArrayRef<KV> Table) {
|
||||
size_t MaxLen = 0;
|
||||
for (auto &I : Table)
|
||||
MaxLen = std::max(MaxLen, std::strlen(I.Key));
|
||||
return MaxLen;
|
||||
}
|
||||
|
||||
extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM,
|
||||
RustStringRef OutStr) {
|
||||
ArrayRef<SubtargetSubTypeKV> CPUTable =
|
||||
|
|
|
|||
|
|
@ -179,12 +179,6 @@ pub fn initialize_available_targets() {
|
|||
LLVMInitializeSystemZAsmPrinter,
|
||||
LLVMInitializeSystemZAsmParser
|
||||
);
|
||||
init_target!(
|
||||
llvm_component = "jsbackend",
|
||||
LLVMInitializeJSBackendTargetInfo,
|
||||
LLVMInitializeJSBackendTarget,
|
||||
LLVMInitializeJSBackendTargetMC
|
||||
);
|
||||
init_target!(
|
||||
llvm_component = "msp430",
|
||||
LLVMInitializeMSP430TargetInfo,
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ middle_failed_writing_file =
|
|||
# Note: We only mention patterns here since the error can only occur with references, and those
|
||||
# are forbidden in const generics.
|
||||
middle_invalid_const_in_valtree = constant {$global_const_id} cannot be used as pattern
|
||||
.note = constants that reference mutable or external memory cannot be used as pattern
|
||||
.note = constants that reference mutable or external memory cannot be used as patterns
|
||||
|
||||
middle_layout_cycle =
|
||||
a cycle occurred during layout computation
|
||||
|
|
|
|||
|
|
@ -327,9 +327,11 @@ pub enum StatementKind<'tcx> {
|
|||
/// interesting for optimizations? Do we want to allow such optimizations?
|
||||
///
|
||||
/// **Needs clarification**: We currently require that the LHS place not overlap with any place
|
||||
/// read as part of computation of the RHS for some rvalues (generally those not producing
|
||||
/// primitives). This requirement is under discussion in [#68364]. As a part of this discussion,
|
||||
/// it is also unclear in what order the components are evaluated.
|
||||
/// read as part of computation of the RHS for some rvalues. This requirement is under
|
||||
/// discussion in [#68364]. Specifically, overlap is permitted only for assignments of a type
|
||||
/// with `BackendRepr::Scalar | BackendRepr::ScalarPair` where all the scalar fields are
|
||||
/// [`Scalar::Initialized`][rustc_abi::Scalar::Initialized]. As a part of this discussion, it is
|
||||
/// also unclear in what order the components are evaluated.
|
||||
///
|
||||
/// [#68364]: https://github.com/rust-lang/rust/issues/68364
|
||||
///
|
||||
|
|
|
|||
|
|
@ -567,13 +567,15 @@ fn save_as_intervals<'tcx>(
|
|||
// the written-to locals as live in the second half of the statement.
|
||||
// We also ensure that operands read by terminators conflict with writes by that terminator.
|
||||
// For instance a function call may read args after having written to the destination.
|
||||
VisitPlacesWith(|place, ctxt| match DefUse::for_place(place, ctxt) {
|
||||
DefUse::Def | DefUse::Use | DefUse::PartialWrite => {
|
||||
if let Some(relevant) = relevant.shrink[place.local] {
|
||||
values.insert(relevant, twostep);
|
||||
VisitPlacesWith(|place: Place<'tcx>, ctxt| {
|
||||
if let Some(relevant) = relevant.shrink[place.local] {
|
||||
match DefUse::for_place(place, ctxt) {
|
||||
DefUse::Def | DefUse::Use | DefUse::PartialWrite => {
|
||||
values.insert(relevant, twostep);
|
||||
}
|
||||
DefUse::NonUse => {}
|
||||
}
|
||||
}
|
||||
DefUse::NonUse => {}
|
||||
})
|
||||
.visit_terminator(term, loc);
|
||||
|
||||
|
|
@ -588,15 +590,32 @@ fn save_as_intervals<'tcx>(
|
|||
twostep = TwoStepIndex::from_u32(twostep.as_u32() + 1);
|
||||
debug_assert_eq!(twostep, two_step_loc(loc, Effect::After));
|
||||
append_at(&mut values, &state, twostep);
|
||||
// Ensure we have a non-zero live range even for dead stores. This is done by marking
|
||||
// all the written-to locals as live in the second half of the statement.
|
||||
VisitPlacesWith(|place, ctxt| match DefUse::for_place(place, ctxt) {
|
||||
DefUse::Def | DefUse::PartialWrite => {
|
||||
if let Some(relevant) = relevant.shrink[place.local] {
|
||||
values.insert(relevant, twostep);
|
||||
// Like terminators, ensure we have a non-zero live range even for dead stores.
|
||||
// Some rvalues interleave reads and writes, for instance `Rvalue::Aggregate`, see
|
||||
// https://github.com/rust-lang/rust/issues/146383. By precaution, treat statements
|
||||
// as behaving so by default.
|
||||
// We make an exception for simple assignments `_a.stuff = {copy|move} _b.stuff`,
|
||||
// as marking `_b` live here would prevent unification.
|
||||
let is_simple_assignment = match stmt.kind {
|
||||
StatementKind::Assign(box (
|
||||
lhs,
|
||||
Rvalue::CopyForDeref(rhs)
|
||||
| Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)),
|
||||
)) => lhs.projection == rhs.projection,
|
||||
_ => false,
|
||||
};
|
||||
VisitPlacesWith(|place: Place<'tcx>, ctxt| {
|
||||
if let Some(relevant) = relevant.shrink[place.local] {
|
||||
match DefUse::for_place(place, ctxt) {
|
||||
DefUse::Def | DefUse::PartialWrite => {
|
||||
values.insert(relevant, twostep);
|
||||
}
|
||||
DefUse::Use if !is_simple_assignment => {
|
||||
values.insert(relevant, twostep);
|
||||
}
|
||||
DefUse::Use | DefUse::NonUse => {}
|
||||
}
|
||||
}
|
||||
DefUse::Use | DefUse::NonUse => {}
|
||||
})
|
||||
.visit_statement(stmt, loc);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,14 @@
|
|||
//! Miscellaneous type-system utilities that are too small to deserve their own modules.
|
||||
|
||||
use std::assert_matches::assert_matches;
|
||||
|
||||
use hir::LangItem;
|
||||
use rustc_ast::Mutability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
|
||||
use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypeVisitableExt, TypingMode};
|
||||
use rustc_span::sym;
|
||||
|
||||
use crate::regions::InferCtxtRegionExt;
|
||||
use crate::traits::{self, FulfillmentError, ObligationCause};
|
||||
use crate::traits::{self, FulfillmentError, Obligation, ObligationCause};
|
||||
|
||||
pub enum CopyImplementationError<'tcx> {
|
||||
InfringingFields(Vec<(&'tcx ty::FieldDef, Ty<'tcx>, InfringingFieldsReason<'tcx>)>),
|
||||
|
|
@ -98,10 +97,9 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>(
|
|||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
self_type: Ty<'tcx>,
|
||||
lang_item: LangItem,
|
||||
parent_cause: ObligationCause<'tcx>,
|
||||
) -> Result<(), ConstParamTyImplementationError<'tcx>> {
|
||||
assert_matches!(lang_item, LangItem::ConstParamTy | LangItem::UnsizedConstParamTy);
|
||||
let mut need_unstable_feature_bound = false;
|
||||
|
||||
let inner_tys: Vec<_> = match *self_type.kind() {
|
||||
// Trivially okay as these types are all:
|
||||
|
|
@ -112,18 +110,14 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>(
|
|||
|
||||
// Handle types gated under `feature(unsized_const_params)`
|
||||
// FIXME(unsized_const_params): Make `const N: [u8]` work then forbid references
|
||||
ty::Slice(inner_ty) | ty::Ref(_, inner_ty, Mutability::Not)
|
||||
if lang_item == LangItem::UnsizedConstParamTy =>
|
||||
{
|
||||
ty::Slice(inner_ty) | ty::Ref(_, inner_ty, Mutability::Not) => {
|
||||
need_unstable_feature_bound = true;
|
||||
vec![inner_ty]
|
||||
}
|
||||
ty::Str if lang_item == LangItem::UnsizedConstParamTy => {
|
||||
ty::Str => {
|
||||
need_unstable_feature_bound = true;
|
||||
vec![Ty::new_slice(tcx, tcx.types.u8)]
|
||||
}
|
||||
ty::Str | ty::Slice(..) | ty::Ref(_, _, Mutability::Not) => {
|
||||
return Err(ConstParamTyImplementationError::UnsizedConstParamsFeatureRequired);
|
||||
}
|
||||
|
||||
ty::Array(inner_ty, _) => vec![inner_ty],
|
||||
|
||||
// `str` morally acts like a newtype around `[u8]`
|
||||
|
|
@ -137,7 +131,7 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>(
|
|||
adt,
|
||||
args,
|
||||
parent_cause.clone(),
|
||||
lang_item,
|
||||
LangItem::ConstParamTy,
|
||||
)
|
||||
.map_err(ConstParamTyImplementationError::InfrigingFields)?;
|
||||
|
||||
|
|
@ -153,11 +147,25 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>(
|
|||
let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
|
||||
let ocx = traits::ObligationCtxt::new_with_diagnostics(&infcx);
|
||||
|
||||
// Make sure impls certain types are gated with #[unstable_feature_bound(unsized_const_params)]
|
||||
if need_unstable_feature_bound {
|
||||
ocx.register_obligation(Obligation::new(
|
||||
tcx,
|
||||
parent_cause.clone(),
|
||||
param_env,
|
||||
ty::ClauseKind::UnstableFeature(sym::unsized_const_params),
|
||||
));
|
||||
|
||||
if !ocx.select_all_or_error().is_empty() {
|
||||
return Err(ConstParamTyImplementationError::UnsizedConstParamsFeatureRequired);
|
||||
}
|
||||
}
|
||||
|
||||
ocx.register_bound(
|
||||
parent_cause.clone(),
|
||||
param_env,
|
||||
inner_ty,
|
||||
tcx.require_lang_item(lang_item, parent_cause.span),
|
||||
tcx.require_lang_item(LangItem::ConstParamTy, parent_cause.span),
|
||||
);
|
||||
|
||||
let errors = ocx.select_all_or_error();
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ impl<'a, T> PeekMut<'a, T> {
|
|||
|
||||
/// Removes the peeked value from the vector and returns it.
|
||||
#[unstable(feature = "vec_peek_mut", issue = "122742")]
|
||||
pub fn pop(self) -> T {
|
||||
pub fn pop(this: Self) -> T {
|
||||
// SAFETY: PeekMut is only constructed if the vec is non-empty
|
||||
unsafe { self.vec.pop().unwrap_unchecked() }
|
||||
unsafe { this.vec.pop().unwrap_unchecked() }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use std::ops::Bound::*;
|
|||
use std::panic::{AssertUnwindSafe, catch_unwind};
|
||||
use std::rc::Rc;
|
||||
use std::sync::atomic::{AtomicU32, Ordering};
|
||||
use std::vec::{Drain, IntoIter};
|
||||
use std::vec::{Drain, IntoIter, PeekMut};
|
||||
|
||||
use crate::testing::macros::struct_with_counted_drop;
|
||||
|
||||
|
|
@ -2647,7 +2647,7 @@ fn test_peek_mut() {
|
|||
assert_eq!(*p, 2);
|
||||
*p = 0;
|
||||
assert_eq!(*p, 0);
|
||||
p.pop();
|
||||
PeekMut::pop(p);
|
||||
assert_eq!(vec.len(), 1);
|
||||
} else {
|
||||
unreachable!()
|
||||
|
|
|
|||
|
|
@ -472,6 +472,11 @@ impl<T: Copy> SpecArrayClone for T {
|
|||
// The Default impls cannot be done with const generics because `[T; 0]` doesn't
|
||||
// require Default to be implemented, and having different impl blocks for
|
||||
// different numbers isn't supported yet.
|
||||
//
|
||||
// Trying to improve the `[T; 0]` situation has proven to be difficult.
|
||||
// Please see these issues for more context on past attempts and crater runs:
|
||||
// - https://github.com/rust-lang/rust/issues/61415
|
||||
// - https://github.com/rust-lang/rust/pull/145457
|
||||
|
||||
macro_rules! array_impl_default {
|
||||
{$n:expr, $t:ident $($ts:ident)*} => {
|
||||
|
|
|
|||
|
|
@ -334,9 +334,8 @@ pub macro PartialEq($item:item) {
|
|||
#[doc(alias = "!=")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_diagnostic_item = "Eq"]
|
||||
#[const_trait]
|
||||
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
|
||||
pub trait Eq: [const] PartialEq<Self> + PointeeSized {
|
||||
pub const trait Eq: [const] PartialEq<Self> + PointeeSized {
|
||||
// this method is used solely by `impl Eq or #[derive(Eq)]` to assert that every component of a
|
||||
// type implements `Eq` itself. The current deriving infrastructure means doing this assertion
|
||||
// without using a method on this trait is nearly impossible.
|
||||
|
|
@ -966,9 +965,8 @@ impl<T: Clone> Clone for Reverse<T> {
|
|||
#[doc(alias = ">=")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_diagnostic_item = "Ord"]
|
||||
#[const_trait]
|
||||
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
|
||||
pub trait Ord: [const] Eq + [const] PartialOrd<Self> + PointeeSized {
|
||||
pub const trait Ord: [const] Eq + [const] PartialOrd<Self> + PointeeSized {
|
||||
/// This method returns an [`Ordering`] between `self` and `other`.
|
||||
///
|
||||
/// By convention, `self.cmp(&other)` returns the ordering matching the expression
|
||||
|
|
@ -1352,9 +1350,8 @@ pub macro Ord($item:item) {
|
|||
)]
|
||||
#[rustc_diagnostic_item = "PartialOrd"]
|
||||
#[allow(multiple_supertrait_upcastable)] // FIXME(sized_hierarchy): remove this
|
||||
#[const_trait]
|
||||
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
|
||||
pub trait PartialOrd<Rhs: PointeeSized = Self>: PartialEq<Rhs> + PointeeSized {
|
||||
pub const trait PartialOrd<Rhs: PointeeSized = Self>: PartialEq<Rhs> + PointeeSized {
|
||||
/// This method returns an ordering between `self` and `other` values if one exists.
|
||||
///
|
||||
/// # Examples
|
||||
|
|
|
|||
|
|
@ -1083,7 +1083,7 @@ pub trait Tuple {}
|
|||
// We name this differently than the derive macro so that the `adt_const_params` can
|
||||
// be used independently of `unsized_const_params` without requiring a full path
|
||||
// to the derive macro every time it is used. This should be renamed on stabilization.
|
||||
pub trait ConstParamTy_: UnsizedConstParamTy + StructuralPartialEq + Eq {}
|
||||
pub trait ConstParamTy_: StructuralPartialEq + Eq {}
|
||||
|
||||
/// Derive macro generating an impl of the trait `ConstParamTy`.
|
||||
#[rustc_builtin_macro]
|
||||
|
|
@ -1093,23 +1093,6 @@ pub macro ConstParamTy($item:item) {
|
|||
/* compiler built-in */
|
||||
}
|
||||
|
||||
#[lang = "unsized_const_param_ty"]
|
||||
#[unstable(feature = "unsized_const_params", issue = "95174")]
|
||||
#[diagnostic::on_unimplemented(message = "`{Self}` can't be used as a const parameter type")]
|
||||
/// A marker for types which can be used as types of `const` generic parameters.
|
||||
///
|
||||
/// Equivalent to [`ConstParamTy_`] except that this is used by
|
||||
/// the `unsized_const_params` to allow for fake unstable impls.
|
||||
pub trait UnsizedConstParamTy: StructuralPartialEq + Eq {}
|
||||
|
||||
/// Derive macro generating an impl of the trait `ConstParamTy`.
|
||||
#[rustc_builtin_macro]
|
||||
#[allow_internal_unstable(unsized_const_params)]
|
||||
#[unstable(feature = "unsized_const_params", issue = "95174")]
|
||||
pub macro UnsizedConstParamTy($item:item) {
|
||||
/* compiler built-in */
|
||||
}
|
||||
|
||||
// FIXME(adt_const_params): handle `ty::FnDef`/`ty::Closure`
|
||||
marker_impls! {
|
||||
#[unstable(feature = "adt_const_params", issue = "95174")]
|
||||
|
|
@ -1124,17 +1107,11 @@ marker_impls! {
|
|||
|
||||
marker_impls! {
|
||||
#[unstable(feature = "unsized_const_params", issue = "95174")]
|
||||
UnsizedConstParamTy for
|
||||
usize, u8, u16, u32, u64, u128,
|
||||
isize, i8, i16, i32, i64, i128,
|
||||
bool,
|
||||
char,
|
||||
(),
|
||||
{T: UnsizedConstParamTy, const N: usize} [T; N],
|
||||
|
||||
#[unstable_feature_bound(unsized_const_params)]
|
||||
ConstParamTy_ for
|
||||
str,
|
||||
{T: UnsizedConstParamTy} [T],
|
||||
{T: UnsizedConstParamTy + ?Sized} &T,
|
||||
{T: ConstParamTy_} [T],
|
||||
{T: ConstParamTy_ + ?Sized} &T,
|
||||
}
|
||||
|
||||
/// A common trait implemented by all function pointers.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::marker::{ConstParamTy_, UnsizedConstParamTy};
|
||||
use crate::marker::ConstParamTy_;
|
||||
|
||||
/// Marks that `Src` is transmutable into `Self`.
|
||||
///
|
||||
|
|
@ -83,6 +83,7 @@ use crate::marker::{ConstParamTy_, UnsizedConstParamTy};
|
|||
/// Furthermore, stability does not imply portability. For example, the size of
|
||||
/// `usize` is stable, but not portable.
|
||||
#[unstable(feature = "transmutability", issue = "99571")]
|
||||
#[unstable_feature_bound(transmutability)]
|
||||
#[lang = "transmute_trait"]
|
||||
#[rustc_deny_explicit_impl]
|
||||
#[rustc_do_not_implement_via_object]
|
||||
|
|
@ -288,9 +289,8 @@ pub struct Assume {
|
|||
}
|
||||
|
||||
#[unstable(feature = "transmutability", issue = "99571")]
|
||||
#[unstable_feature_bound(transmutability)]
|
||||
impl ConstParamTy_ for Assume {}
|
||||
#[unstable(feature = "transmutability", issue = "99571")]
|
||||
impl UnsizedConstParamTy for Assume {}
|
||||
|
||||
impl Assume {
|
||||
/// With this, [`TransmuteFrom`] does not assume you have ensured any safety
|
||||
|
|
|
|||
|
|
@ -335,43 +335,6 @@ macro_rules! define_bignum {
|
|||
}
|
||||
(self, borrow)
|
||||
}
|
||||
|
||||
/// Divide self by another bignum, overwriting `q` with the quotient and `r` with the
|
||||
/// remainder.
|
||||
pub fn div_rem(&self, d: &$name, q: &mut $name, r: &mut $name) {
|
||||
// Stupid slow base-2 long division taken from
|
||||
// https://en.wikipedia.org/wiki/Division_algorithm
|
||||
// FIXME use a greater base ($ty) for the long division.
|
||||
assert!(!d.is_zero());
|
||||
let digitbits = <$ty>::BITS as usize;
|
||||
for digit in &mut q.base[..] {
|
||||
*digit = 0;
|
||||
}
|
||||
for digit in &mut r.base[..] {
|
||||
*digit = 0;
|
||||
}
|
||||
r.size = d.size;
|
||||
q.size = 1;
|
||||
let mut q_is_zero = true;
|
||||
let end = self.bit_length();
|
||||
for i in (0..end).rev() {
|
||||
r.mul_pow2(1);
|
||||
r.base[0] |= self.get_bit(i) as $ty;
|
||||
if &*r >= d {
|
||||
r.sub(d);
|
||||
// Set bit `i` of q to 1.
|
||||
let digit_idx = i / digitbits;
|
||||
let bit_idx = i % digitbits;
|
||||
if q_is_zero {
|
||||
q.size = digit_idx + 1;
|
||||
q_is_zero = false;
|
||||
}
|
||||
q.base[digit_idx] |= 1 << bit_idx;
|
||||
}
|
||||
}
|
||||
debug_assert!(q.base[q.size..].iter().all(|&d| d == 0));
|
||||
debug_assert!(r.base[r.size..].iter().all(|&d| d == 0));
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::cmp::PartialEq for $name {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// See core/src/primitive_docs.rs for documentation.
|
||||
|
||||
use crate::cmp::Ordering::{self, *};
|
||||
use crate::marker::{ConstParamTy_, StructuralPartialEq, UnsizedConstParamTy};
|
||||
use crate::marker::{ConstParamTy_, StructuralPartialEq};
|
||||
use crate::ops::ControlFlow::{self, Break, Continue};
|
||||
|
||||
// Recursive macro for implementing n-ary tuple functions and operations
|
||||
|
|
@ -47,17 +47,11 @@ macro_rules! tuple_impls {
|
|||
maybe_tuple_doc! {
|
||||
$($T)+ @
|
||||
#[unstable(feature = "adt_const_params", issue = "95174")]
|
||||
#[unstable_feature_bound(unsized_const_params)]
|
||||
impl<$($T: ConstParamTy_),+> ConstParamTy_ for ($($T,)+)
|
||||
{}
|
||||
}
|
||||
|
||||
maybe_tuple_doc! {
|
||||
$($T)+ @
|
||||
#[unstable(feature = "unsized_const_params", issue = "95174")]
|
||||
impl<$($T: UnsizedConstParamTy),+> UnsizedConstParamTy for ($($T,)+)
|
||||
{}
|
||||
}
|
||||
|
||||
maybe_tuple_doc! {
|
||||
$($T)+ @
|
||||
#[unstable(feature = "structural_match", issue = "31434")]
|
||||
|
|
|
|||
|
|
@ -505,3 +505,10 @@ fn test_escape_ascii_iter() {
|
|||
let _ = it.advance_back_by(4);
|
||||
assert_eq!(it.to_string(), r#"fastpath\xffremainder"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_u8() {
|
||||
for c in 128..=255 {
|
||||
assert_eq!(core::ascii::Char::from_u8(c), None);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -173,6 +173,21 @@ mod debug_struct {
|
|||
format!("{Bar:#?}")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_field_with() {
|
||||
struct Foo;
|
||||
impl fmt::Debug for Foo {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt.debug_struct("Foo")
|
||||
.field_with("bar", |f| f.write_str("true"))
|
||||
.field_with("baz", |f| f.write_str("false"))
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!("Foo {\n bar: true,\n baz: false,\n}", format!("{Foo:#?}"))
|
||||
}
|
||||
}
|
||||
|
||||
mod debug_tuple {
|
||||
|
|
|
|||
|
|
@ -57,6 +57,36 @@ fn test_fmt_debug_of_raw_pointers() {
|
|||
check_fmt(vtable as *const dyn Debug, "Pointer { addr: ", ", metadata: DynMetadata(");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fmt_debug_of_mut_reference() {
|
||||
let mut x: u32 = 0;
|
||||
|
||||
assert_eq!(format!("{:?}", &mut x), "0");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_write_impls() {
|
||||
use core::fmt::Write;
|
||||
|
||||
struct Buf(String);
|
||||
|
||||
impl Write for Buf {
|
||||
fn write_str(&mut self, s: &str) -> core::fmt::Result {
|
||||
self.0.write_str(s)
|
||||
}
|
||||
}
|
||||
|
||||
let mut buf = Buf(String::new());
|
||||
buf.write_char('a').unwrap();
|
||||
|
||||
assert_eq!(buf.0, "a");
|
||||
|
||||
let mut buf = Buf(String::new());
|
||||
buf.write_fmt(format_args!("a")).unwrap();
|
||||
|
||||
assert_eq!(buf.0, "a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_estimated_capacity() {
|
||||
assert_eq!(format_args!("").estimated_capacity(), 0);
|
||||
|
|
|
|||
|
|
@ -323,3 +323,9 @@ fn test_format_debug_hex() {
|
|||
assert_eq!(format!("{:02x?}", b"Foo\0"), "[46, 6f, 6f, 00]");
|
||||
assert_eq!(format!("{:02X?}", b"Foo\0"), "[46, 6F, 6F, 00]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "Formatting argument out of range"]
|
||||
fn test_rt_width_too_long() {
|
||||
let _ = format!("Hello {:width$}!", "x", width = u16::MAX as usize + 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#![feature(core_private_bignum)]
|
||||
#![feature(core_private_diy_float)]
|
||||
#![feature(cstr_display)]
|
||||
#![feature(debug_closure_helpers)]
|
||||
#![feature(dec2flt)]
|
||||
#![feature(drop_guard)]
|
||||
#![feature(duration_constants)]
|
||||
|
|
|
|||
|
|
@ -167,25 +167,6 @@ fn test_div_rem_small() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_div_rem() {
|
||||
fn div_rem(n: u64, d: u64) -> (Big, Big) {
|
||||
let mut q = Big::from_small(42);
|
||||
let mut r = Big::from_small(42);
|
||||
Big::from_u64(n).div_rem(&Big::from_u64(d), &mut q, &mut r);
|
||||
(q, r)
|
||||
}
|
||||
assert_eq!(div_rem(1, 1), (Big::from_small(1), Big::from_small(0)));
|
||||
assert_eq!(div_rem(4, 3), (Big::from_small(1), Big::from_small(1)));
|
||||
assert_eq!(div_rem(1, 7), (Big::from_small(0), Big::from_small(1)));
|
||||
assert_eq!(div_rem(45, 9), (Big::from_small(5), Big::from_small(0)));
|
||||
assert_eq!(div_rem(103, 9), (Big::from_small(11), Big::from_small(4)));
|
||||
assert_eq!(div_rem(123456, 77), (Big::from_u64(1603), Big::from_small(25)));
|
||||
assert_eq!(div_rem(0xffff, 1), (Big::from_u64(0xffff), Big::from_small(0)));
|
||||
assert_eq!(div_rem(0xeeee, 0xffff), (Big::from_small(0), Big::from_u64(0xeeee)));
|
||||
assert_eq!(div_rem(2_000_000, 2), (Big::from_u64(1_000_000), Big::from_u64(0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_zero() {
|
||||
assert!(Big::from_small(0).is_zero());
|
||||
|
|
|
|||
|
|
@ -489,6 +489,14 @@ fn is_aligned() {
|
|||
assert_ne!(ptr.is_aligned_to(8), ptr.wrapping_add(1).is_aligned_to(8));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "is_aligned_to: align is not a power-of-two"]
|
||||
fn invalid_is_aligned() {
|
||||
let data = 42;
|
||||
let ptr: *const i32 = &data;
|
||||
assert!(ptr.is_aligned_to(3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn offset_from() {
|
||||
let mut a = [0; 5];
|
||||
|
|
|
|||
|
|
@ -21,29 +21,31 @@ use libc::fstatat as fstatat64;
|
|||
#[cfg(any(all(target_os = "linux", not(target_env = "musl")), target_os = "hurd"))]
|
||||
use libc::fstatat64;
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "solaris",
|
||||
target_os = "fuchsia",
|
||||
target_os = "redox",
|
||||
target_os = "illumos",
|
||||
target_os = "aix",
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "fuchsia",
|
||||
target_os = "illumos",
|
||||
target_os = "nto",
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "vita",
|
||||
all(target_os = "linux", target_env = "musl"),
|
||||
))]
|
||||
use libc::readdir as readdir64;
|
||||
#[cfg(not(any(
|
||||
target_os = "aix",
|
||||
target_os = "android",
|
||||
target_os = "linux",
|
||||
target_os = "solaris",
|
||||
target_os = "freebsd",
|
||||
target_os = "fuchsia",
|
||||
target_os = "hurd",
|
||||
target_os = "illumos",
|
||||
target_os = "l4re",
|
||||
target_os = "fuchsia",
|
||||
target_os = "redox",
|
||||
target_os = "aix",
|
||||
target_os = "linux",
|
||||
target_os = "nto",
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "vita",
|
||||
target_os = "hurd",
|
||||
)))]
|
||||
use libc::readdir_r as readdir64_r;
|
||||
#[cfg(any(all(target_os = "linux", not(target_env = "musl")), target_os = "hurd"))]
|
||||
|
|
@ -271,16 +273,17 @@ unsafe impl Send for Dir {}
|
|||
unsafe impl Sync for Dir {}
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "linux",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "fuchsia",
|
||||
target_os = "redox",
|
||||
target_os = "aix",
|
||||
target_os = "nto",
|
||||
target_os = "vita",
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "fuchsia",
|
||||
target_os = "hurd",
|
||||
target_os = "illumos",
|
||||
target_os = "linux",
|
||||
target_os = "nto",
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "vita",
|
||||
))]
|
||||
pub struct DirEntry {
|
||||
dir: Arc<InnerReadDir>,
|
||||
|
|
@ -295,16 +298,17 @@ pub struct DirEntry {
|
|||
// we're not using the immediate `d_name` on these targets. Keeping this as an
|
||||
// `entry` field in `DirEntry` helps reduce the `cfg` boilerplate elsewhere.
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "linux",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "fuchsia",
|
||||
target_os = "redox",
|
||||
target_os = "aix",
|
||||
target_os = "nto",
|
||||
target_os = "vita",
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "fuchsia",
|
||||
target_os = "hurd",
|
||||
target_os = "illumos",
|
||||
target_os = "linux",
|
||||
target_os = "nto",
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "vita",
|
||||
))]
|
||||
struct dirent64_min {
|
||||
d_ino: u64,
|
||||
|
|
@ -319,16 +323,17 @@ struct dirent64_min {
|
|||
}
|
||||
|
||||
#[cfg(not(any(
|
||||
target_os = "android",
|
||||
target_os = "linux",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "fuchsia",
|
||||
target_os = "redox",
|
||||
target_os = "aix",
|
||||
target_os = "nto",
|
||||
target_os = "vita",
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "fuchsia",
|
||||
target_os = "hurd",
|
||||
target_os = "illumos",
|
||||
target_os = "linux",
|
||||
target_os = "nto",
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "vita",
|
||||
)))]
|
||||
pub struct DirEntry {
|
||||
dir: Arc<InnerReadDir>,
|
||||
|
|
@ -698,16 +703,17 @@ impl Iterator for ReadDir {
|
|||
type Item = io::Result<DirEntry>;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "linux",
|
||||
target_os = "solaris",
|
||||
target_os = "fuchsia",
|
||||
target_os = "redox",
|
||||
target_os = "illumos",
|
||||
target_os = "aix",
|
||||
target_os = "nto",
|
||||
target_os = "vita",
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "fuchsia",
|
||||
target_os = "hurd",
|
||||
target_os = "illumos",
|
||||
target_os = "linux",
|
||||
target_os = "nto",
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "vita",
|
||||
))]
|
||||
fn next(&mut self) -> Option<io::Result<DirEntry>> {
|
||||
use crate::sys::os::{errno, set_errno};
|
||||
|
|
@ -768,6 +774,9 @@ impl Iterator for ReadDir {
|
|||
// only access those bytes.
|
||||
#[cfg(not(target_os = "vita"))]
|
||||
let entry = dirent64_min {
|
||||
#[cfg(target_os = "freebsd")]
|
||||
d_ino: (*entry_ptr).d_fileno,
|
||||
#[cfg(not(target_os = "freebsd"))]
|
||||
d_ino: (*entry_ptr).d_ino as u64,
|
||||
#[cfg(not(any(
|
||||
target_os = "solaris",
|
||||
|
|
@ -791,16 +800,17 @@ impl Iterator for ReadDir {
|
|||
}
|
||||
|
||||
#[cfg(not(any(
|
||||
target_os = "android",
|
||||
target_os = "linux",
|
||||
target_os = "solaris",
|
||||
target_os = "fuchsia",
|
||||
target_os = "redox",
|
||||
target_os = "illumos",
|
||||
target_os = "aix",
|
||||
target_os = "nto",
|
||||
target_os = "vita",
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "fuchsia",
|
||||
target_os = "hurd",
|
||||
target_os = "illumos",
|
||||
target_os = "linux",
|
||||
target_os = "nto",
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "vita",
|
||||
)))]
|
||||
fn next(&mut self) -> Option<io::Result<DirEntry>> {
|
||||
if self.end_of_stream {
|
||||
|
|
@ -970,36 +980,32 @@ impl DirEntry {
|
|||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "aix",
|
||||
target_os = "android",
|
||||
target_os = "cygwin",
|
||||
target_os = "emscripten",
|
||||
target_os = "android",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "haiku",
|
||||
target_os = "l4re",
|
||||
target_os = "fuchsia",
|
||||
target_os = "redox",
|
||||
target_os = "vxworks",
|
||||
target_os = "espidf",
|
||||
target_os = "freebsd",
|
||||
target_os = "fuchsia",
|
||||
target_os = "haiku",
|
||||
target_os = "horizon",
|
||||
target_os = "vita",
|
||||
target_os = "aix",
|
||||
target_os = "nto",
|
||||
target_os = "hurd",
|
||||
target_os = "illumos",
|
||||
target_os = "l4re",
|
||||
target_os = "linux",
|
||||
target_os = "nto",
|
||||
target_os = "redox",
|
||||
target_os = "rtems",
|
||||
target_os = "solaris",
|
||||
target_os = "vita",
|
||||
target_os = "vxworks",
|
||||
target_vendor = "apple",
|
||||
))]
|
||||
pub fn ino(&self) -> u64 {
|
||||
self.entry.d_ino as u64
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "freebsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "dragonfly"
|
||||
))]
|
||||
#[cfg(any(target_os = "openbsd", target_os = "netbsd", target_os = "dragonfly"))]
|
||||
pub fn ino(&self) -> u64 {
|
||||
self.entry.d_fileno as u64
|
||||
}
|
||||
|
|
@ -1014,7 +1020,6 @@ impl DirEntry {
|
|||
#[cfg(any(
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_vendor = "apple",
|
||||
))]
|
||||
|
|
@ -1030,7 +1035,6 @@ impl DirEntry {
|
|||
#[cfg(not(any(
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_vendor = "apple",
|
||||
)))]
|
||||
|
|
@ -1040,6 +1044,7 @@ impl DirEntry {
|
|||
|
||||
#[cfg(not(any(
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
|
|
@ -1055,6 +1060,7 @@ impl DirEntry {
|
|||
}
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
|
|
|
|||
|
|
@ -63,6 +63,21 @@ build/
|
|||
debug/
|
||||
release/
|
||||
|
||||
# Build directory for various tools like `typos` that are only ever
|
||||
# built for the host system, and always with stage0 cargo.
|
||||
misc-tools/
|
||||
bin/
|
||||
target/
|
||||
|
||||
# Directory where js dependencies like tsc and eslint are stored.
|
||||
node_modules/
|
||||
.bin/
|
||||
|
||||
# Copy of package.json and package-lock.json, because npm requires these
|
||||
# to be in the same directory as `node_modules`.
|
||||
package.json
|
||||
package-lock.json
|
||||
|
||||
# Output of the dist-related steps like dist-std, dist-rustc, and dist-docs
|
||||
dist/
|
||||
|
||||
|
|
|
|||
|
|
@ -1039,6 +1039,9 @@ class RustBuild(object):
|
|||
# See also: <https://github.com/rust-lang/rust/issues/70208>.
|
||||
if "CARGO_BUILD_TARGET" in env:
|
||||
del env["CARGO_BUILD_TARGET"]
|
||||
# if in CI, don't use incremental build when building bootstrap.
|
||||
if "GITHUB_ACTIONS" in env:
|
||||
env["CARGO_INCREMENTAL"] = "0"
|
||||
env["CARGO_TARGET_DIR"] = build_dir
|
||||
env["RUSTC"] = self.rustc()
|
||||
env["LD_LIBRARY_PATH"] = (
|
||||
|
|
@ -1145,7 +1148,8 @@ class RustBuild(object):
|
|||
os.path.join(self.rust_root, "src/bootstrap/Cargo.toml"),
|
||||
"-Zroot-dir=" + self.rust_root,
|
||||
]
|
||||
args.extend("--verbose" for _ in range(self.verbose))
|
||||
# verbose cargo output is very noisy, so only enable it with -vv
|
||||
args.extend("--verbose" for _ in range(self.verbose - 1))
|
||||
|
||||
if "BOOTSTRAP_TRACING" in env:
|
||||
args.append("--features=tracing")
|
||||
|
|
|
|||
|
|
@ -3418,9 +3418,6 @@ impl Step for TierCheck {
|
|||
);
|
||||
cargo.arg(builder.src.join("src/doc/rustc/src/platform-support.md"));
|
||||
cargo.arg(builder.rustc(self.test_compiler));
|
||||
if builder.is_verbose() {
|
||||
cargo.arg("--verbose");
|
||||
}
|
||||
|
||||
let _guard = builder.msg_test(
|
||||
"platform support check",
|
||||
|
|
|
|||
|
|
@ -394,6 +394,9 @@ macro_rules! bootstrap_tool {
|
|||
}
|
||||
|
||||
impl<'a> Builder<'a> {
|
||||
/// Ensure a tool is built, then get the path to its executable.
|
||||
///
|
||||
/// The actual building, if any, will be handled via [`ToolBuild`].
|
||||
pub fn tool_exe(&self, tool: Tool) -> PathBuf {
|
||||
match tool {
|
||||
$(Tool::$name =>
|
||||
|
|
@ -1552,6 +1555,8 @@ pub const TEST_FLOAT_PARSE_ALLOW_FEATURES: &str = "f16,cfg_target_has_reliable_f
|
|||
impl Builder<'_> {
|
||||
/// Gets a `BootstrapCommand` which is ready to run `tool` in `stage` built for
|
||||
/// `host`.
|
||||
///
|
||||
/// This also ensures that the given tool is built (using [`ToolBuild`]).
|
||||
pub fn tool_cmd(&self, tool: Tool) -> BootstrapCommand {
|
||||
let mut cmd = command(self.tool_exe(tool));
|
||||
let compiler = self.compiler(0, self.config.host_target);
|
||||
|
|
|
|||
|
|
@ -1133,7 +1133,7 @@ impl Builder<'_> {
|
|||
cargo.env("RUSTC_BACKTRACE_ON_ICE", "1");
|
||||
}
|
||||
|
||||
if self.is_verbose() {
|
||||
if self.is_verbose_than(1) {
|
||||
// This provides very useful logs especially when debugging build cache-related stuff.
|
||||
cargo.env("CARGO_LOG", "cargo::core::compiler::fingerprint=info");
|
||||
}
|
||||
|
|
@ -1275,8 +1275,9 @@ impl Builder<'_> {
|
|||
cargo.env("WINAPI_NO_BUNDLED_LIBRARIES", "1");
|
||||
}
|
||||
|
||||
for _ in 0..self.verbosity {
|
||||
cargo.arg("-v");
|
||||
// verbose cargo output is very noisy, so only enable it with -vv
|
||||
for _ in 0..self.verbosity.saturating_sub(1) {
|
||||
cargo.arg("--verbose");
|
||||
}
|
||||
|
||||
match (mode, self.config.rust_codegen_units_std, self.config.rust_codegen_units) {
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ than building it.
|
|||
|
||||
if !has_target {
|
||||
panic!(
|
||||
"No such target exists in the target list,\n\
|
||||
"{target_str}: No such target exists in the target list,\n\
|
||||
make sure to correctly specify the location \
|
||||
of the JSON specification file \
|
||||
for custom targets!\n\
|
||||
|
|
|
|||
|
|
@ -701,4 +701,4 @@ RFC process, with approval by the compiler and infra teams. Any such proposal
|
|||
will be communicated widely to the Rust community, both when initially proposed
|
||||
and before being dropped from a stable release.
|
||||
|
||||
[MCP]: https://forge.rust-lang.org/compiler/mcp.html
|
||||
[MCP]: https://forge.rust-lang.org/compiler/proposals-and-stabilization.html#how-do-i-submit-an-mcp
|
||||
|
|
|
|||
|
|
@ -203,6 +203,10 @@ impl CodegenBackend {
|
|||
Self::Llvm => "llvm",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_llvm(self) -> bool {
|
||||
matches!(self, Self::Llvm)
|
||||
}
|
||||
}
|
||||
|
||||
/// Configuration for `compiletest` *per invocation*.
|
||||
|
|
|
|||
|
|
@ -1446,6 +1446,7 @@ pub(crate) fn make_test_description<R: Read>(
|
|||
cache: &DirectivesCache,
|
||||
name: String,
|
||||
path: &Utf8Path,
|
||||
filterable_path: &Utf8Path,
|
||||
src: R,
|
||||
test_revision: Option<&str>,
|
||||
poisoned: &mut bool,
|
||||
|
|
@ -1520,7 +1521,13 @@ pub(crate) fn make_test_description<R: Read>(
|
|||
_ => ShouldPanic::No,
|
||||
};
|
||||
|
||||
CollectedTestDesc { name, ignore, ignore_message, should_panic }
|
||||
CollectedTestDesc {
|
||||
name,
|
||||
filterable_path: filterable_path.to_owned(),
|
||||
ignore,
|
||||
ignore_message,
|
||||
should_panic,
|
||||
}
|
||||
}
|
||||
|
||||
fn ignore_cdb(config: &Config, line: &str) -> IgnoreDecision {
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ pub(super) fn handle_needs(
|
|||
},
|
||||
Need {
|
||||
name: "needs-enzyme",
|
||||
condition: config.has_enzyme,
|
||||
ignore_reason: "ignored when LLVM Enzyme is disabled",
|
||||
condition: config.has_enzyme && config.default_codegen_backend.is_llvm(),
|
||||
ignore_reason: "ignored when LLVM Enzyme is disabled or LLVM is not the default codegen backend",
|
||||
},
|
||||
Need {
|
||||
name: "needs-run-enabled",
|
||||
|
|
@ -161,8 +161,8 @@ pub(super) fn handle_needs(
|
|||
},
|
||||
Need {
|
||||
name: "needs-llvm-zstd",
|
||||
condition: cache.llvm_zstd,
|
||||
ignore_reason: "ignored if LLVM wasn't build with zstd for ELF section compression",
|
||||
condition: cache.llvm_zstd && config.default_codegen_backend.is_llvm(),
|
||||
ignore_reason: "ignored if LLVM wasn't build with zstd for ELF section compression or LLVM is not the default codegen backend",
|
||||
},
|
||||
Need {
|
||||
name: "needs-rustc-debug-assertions",
|
||||
|
|
@ -279,7 +279,10 @@ pub(super) fn handle_needs(
|
|||
|
||||
// Handled elsewhere.
|
||||
if name == "needs-llvm-components" {
|
||||
return IgnoreDecision::Continue;
|
||||
if config.default_codegen_backend.is_llvm() {
|
||||
return IgnoreDecision::Continue;
|
||||
}
|
||||
return IgnoreDecision::Ignore { reason: "LLVM specific test".into() };
|
||||
}
|
||||
|
||||
let mut found_valid = false;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ fn make_test_description<R: Read>(
|
|||
config: &Config,
|
||||
name: String,
|
||||
path: &Utf8Path,
|
||||
filterable_path: &Utf8Path,
|
||||
src: R,
|
||||
revision: Option<&str>,
|
||||
) -> CollectedTestDesc {
|
||||
|
|
@ -24,6 +25,7 @@ fn make_test_description<R: Read>(
|
|||
&cache,
|
||||
name,
|
||||
path,
|
||||
filterable_path,
|
||||
src,
|
||||
revision,
|
||||
&mut poisoned,
|
||||
|
|
@ -221,7 +223,7 @@ fn parse_rs(config: &Config, contents: &str) -> EarlyProps {
|
|||
fn check_ignore(config: &Config, contents: &str) -> bool {
|
||||
let tn = String::new();
|
||||
let p = Utf8Path::new("a.rs");
|
||||
let d = make_test_description(&config, tn, p, std::io::Cursor::new(contents), None);
|
||||
let d = make_test_description(&config, tn, p, p, std::io::Cursor::new(contents), None);
|
||||
d.ignore
|
||||
}
|
||||
|
||||
|
|
@ -231,9 +233,9 @@ fn should_fail() {
|
|||
let tn = String::new();
|
||||
let p = Utf8Path::new("a.rs");
|
||||
|
||||
let d = make_test_description(&config, tn.clone(), p, std::io::Cursor::new(""), None);
|
||||
let d = make_test_description(&config, tn.clone(), p, p, std::io::Cursor::new(""), None);
|
||||
assert_eq!(d.should_panic, ShouldPanic::No);
|
||||
let d = make_test_description(&config, tn, p, std::io::Cursor::new("//@ should-fail"), None);
|
||||
let d = make_test_description(&config, tn, p, p, std::io::Cursor::new("//@ should-fail"), None);
|
||||
assert_eq!(d.should_panic, ShouldPanic::Yes);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ use std::num::NonZero;
|
|||
use std::sync::{Arc, Mutex, mpsc};
|
||||
use std::{env, hint, io, mem, panic, thread};
|
||||
|
||||
use camino::Utf8PathBuf;
|
||||
|
||||
use crate::common::{Config, TestPaths};
|
||||
use crate::output_capture::{self, ConsoleOut};
|
||||
use crate::panic_hook;
|
||||
|
|
@ -293,8 +295,15 @@ fn filter_tests(opts: &Config, tests: Vec<CollectedTest>) -> Vec<CollectedTest>
|
|||
let mut filtered = tests;
|
||||
|
||||
let matches_filter = |test: &CollectedTest, filter_str: &str| {
|
||||
let test_name = &test.desc.name;
|
||||
if opts.filter_exact { test_name == filter_str } else { test_name.contains(filter_str) }
|
||||
if opts.filter_exact {
|
||||
// When `--exact` is used we must use `filterable_path` to get
|
||||
// reasonable filtering behavior.
|
||||
test.desc.filterable_path.as_str() == filter_str
|
||||
} else {
|
||||
// For compatibility we use the name (which includes the full path)
|
||||
// if `--exact` is not used.
|
||||
test.desc.name.contains(filter_str)
|
||||
}
|
||||
};
|
||||
|
||||
// Remove tests that don't match the test filter
|
||||
|
|
@ -339,6 +348,7 @@ pub(crate) struct CollectedTest {
|
|||
/// Information that was historically needed to create a libtest `TestDesc`.
|
||||
pub(crate) struct CollectedTestDesc {
|
||||
pub(crate) name: String,
|
||||
pub(crate) filterable_path: Utf8PathBuf,
|
||||
pub(crate) ignore: bool,
|
||||
pub(crate) ignore_message: Option<Cow<'static, str>>,
|
||||
pub(crate) should_panic: ShouldPanic,
|
||||
|
|
|
|||
|
|
@ -317,11 +317,17 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
|||
.free
|
||||
.iter()
|
||||
.map(|f| {
|
||||
// Here `f` is relative to `./tests/run-make`. So if you run
|
||||
//
|
||||
// ./x test tests/run-make/crate-loading
|
||||
//
|
||||
// then `f` is "crate-loading".
|
||||
let path = Utf8Path::new(f);
|
||||
let mut iter = path.iter().skip(1);
|
||||
|
||||
// We skip the test folder and check if the user passed `rmake.rs`.
|
||||
if iter.next().is_some_and(|s| s == "rmake.rs") && iter.next().is_none() {
|
||||
// Strip the "rmake.rs" suffix. For example, if `f` is
|
||||
// "crate-loading/rmake.rs" then this gives us "crate-loading".
|
||||
path.parent().unwrap().to_string()
|
||||
} else {
|
||||
f.to_string()
|
||||
|
|
@ -329,6 +335,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
|||
})
|
||||
.collect::<Vec<_>>()
|
||||
} else {
|
||||
// Note that the filters are relative to the root dir of the different test
|
||||
// suites. For example, with:
|
||||
//
|
||||
// ./x test tests/ui/lint/unused
|
||||
//
|
||||
// the filter is "lint/unused".
|
||||
matches.free.clone()
|
||||
};
|
||||
let compare_mode = matches.opt_str("compare-mode").map(|s| {
|
||||
|
|
@ -472,7 +484,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
|||
let value = matches
|
||||
.opt_str("new-output-capture")
|
||||
.or_else(|| env::var("COMPILETEST_NEW_OUTPUT_CAPTURE").ok())
|
||||
.unwrap_or_else(|| "off".to_owned());
|
||||
.unwrap_or_else(|| "on".to_owned());
|
||||
parse_bool_option(&value)
|
||||
.unwrap_or_else(|| panic!("unknown `--new-output-capture` value `{value}` given"))
|
||||
},
|
||||
|
|
@ -911,7 +923,8 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te
|
|||
collector.tests.extend(revisions.into_iter().map(|revision| {
|
||||
// Create a test name and description to hand over to the executor.
|
||||
let src_file = fs::File::open(&test_path).expect("open test file to parse ignores");
|
||||
let test_name = make_test_name(&cx.config, testpaths, revision);
|
||||
let (test_name, filterable_path) =
|
||||
make_test_name_and_filterable_path(&cx.config, testpaths, revision);
|
||||
// Create a description struct for the test/revision.
|
||||
// This is where `ignore-*`/`only-*`/`needs-*` directives are handled,
|
||||
// because they historically needed to set the libtest ignored flag.
|
||||
|
|
@ -920,6 +933,7 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te
|
|||
&cx.cache,
|
||||
test_name,
|
||||
&test_path,
|
||||
&filterable_path,
|
||||
src_file,
|
||||
revision,
|
||||
&mut collector.poisoned,
|
||||
|
|
@ -1072,7 +1086,11 @@ impl Stamp {
|
|||
}
|
||||
|
||||
/// Creates a name for this test/revision that can be handed over to the executor.
|
||||
fn make_test_name(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> String {
|
||||
fn make_test_name_and_filterable_path(
|
||||
config: &Config,
|
||||
testpaths: &TestPaths,
|
||||
revision: Option<&str>,
|
||||
) -> (String, Utf8PathBuf) {
|
||||
// Print the name of the file, relative to the sources root.
|
||||
let path = testpaths.file.strip_prefix(&config.src_root).unwrap();
|
||||
let debugger = match config.debugger {
|
||||
|
|
@ -1084,14 +1102,23 @@ fn make_test_name(config: &Config, testpaths: &TestPaths, revision: Option<&str>
|
|||
None => String::new(),
|
||||
};
|
||||
|
||||
format!(
|
||||
let name = format!(
|
||||
"[{}{}{}] {}{}",
|
||||
config.mode,
|
||||
debugger,
|
||||
mode_suffix,
|
||||
path,
|
||||
revision.map_or("".to_string(), |rev| format!("#{}", rev))
|
||||
)
|
||||
);
|
||||
|
||||
// `path` is the full path from the repo root like, `tests/ui/foo/bar.rs`.
|
||||
// Filtering is applied without the `tests/ui/` part, so strip that off.
|
||||
// First strip off "tests" to make sure we don't have some unexpected path.
|
||||
let mut filterable_path = path.strip_prefix("tests").unwrap().to_owned();
|
||||
// Now strip off e.g. "ui" or "run-make" component.
|
||||
filterable_path = filterable_path.components().skip(1).collect();
|
||||
|
||||
(name, filterable_path)
|
||||
}
|
||||
|
||||
/// Checks that test discovery didn't find any tests whose name stem is a prefix
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
//@revisions: stack tree
|
||||
// Ensure this even hits the aliasing model
|
||||
//@compile-flags: -Zmiri-disable-validation
|
||||
//@[tree]compile-flags: -Zmiri-tree-borrows
|
||||
//@error-in-other-file: pointer not dereferenceable
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
//@revisions: stack tree
|
||||
// Ensure this even hits the aliasing model
|
||||
//@compile-flags: -Zmiri-disable-validation
|
||||
//@[tree]compile-flags: -Zmiri-tree-borrows
|
||||
//@error-in-other-file: is a dangling pointer
|
||||
use std::ptr::NonNull;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ help: <TAG> was created by a SharedReadOnly retag at offsets [0x4..0x8]
|
|||
|
|
||||
LL | let ret = unsafe { &(*xraw).1 };
|
||||
| ^^^^^^^^^^
|
||||
help: <TAG> was later invalidated at offsets [0x0..0x8] by a write access
|
||||
help: <TAG> was later invalidated at offsets [0x4..0x8] by a write access
|
||||
--> tests/fail/both_borrows/return_invalid_shr.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { *xraw = (42, 23) }; // unfreeze
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ help: the accessed tag <TAG> was created here, in the initial state Frozen
|
|||
|
|
||||
LL | let ret = unsafe { &(*xraw).1 };
|
||||
| ^^^^^^^^^^
|
||||
help: the accessed tag <TAG> later transitioned to Disabled due to a foreign write access at offsets [0x0..0x8]
|
||||
help: the accessed tag <TAG> later transitioned to Disabled due to a foreign write access at offsets [0x4..0x8]
|
||||
--> tests/fail/both_borrows/return_invalid_shr.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { *xraw = (42, 23) }; // unfreeze
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ help: <TAG> was created by a SharedReadOnly retag at offsets [0x4..0x8]
|
|||
|
|
||||
LL | let ret = Some(unsafe { &(*xraw).1 });
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: <TAG> was later invalidated at offsets [0x0..0x8] by a write access
|
||||
help: <TAG> was later invalidated at offsets [0x4..0x8] by a write access
|
||||
--> tests/fail/both_borrows/return_invalid_shr_option.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { *xraw = (42, 23) }; // unfreeze
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ help: the accessed tag <TAG> was created here, in the initial state Frozen
|
|||
|
|
||||
LL | let ret = Some(unsafe { &(*xraw).1 });
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: the accessed tag <TAG> later transitioned to Disabled due to a foreign write access at offsets [0x0..0x8]
|
||||
help: the accessed tag <TAG> later transitioned to Disabled due to a foreign write access at offsets [0x4..0x8]
|
||||
--> tests/fail/both_borrows/return_invalid_shr_option.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { *xraw = (42, 23) }; // unfreeze
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ help: <TAG> was created by a SharedReadOnly retag at offsets [0x4..0x8]
|
|||
|
|
||||
LL | let ret = (unsafe { &(*xraw).1 },);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: <TAG> was later invalidated at offsets [0x0..0x8] by a write access
|
||||
help: <TAG> was later invalidated at offsets [0x4..0x8] by a write access
|
||||
--> tests/fail/both_borrows/return_invalid_shr_tuple.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { *xraw = (42, 23) }; // unfreeze
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ help: the accessed tag <TAG> was created here, in the initial state Frozen
|
|||
|
|
||||
LL | let ret = (unsafe { &(*xraw).1 },);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: the accessed tag <TAG> later transitioned to Disabled due to a foreign write access at offsets [0x0..0x8]
|
||||
help: the accessed tag <TAG> later transitioned to Disabled due to a foreign write access at offsets [0x4..0x8]
|
||||
--> tests/fail/both_borrows/return_invalid_shr_tuple.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { *xraw = (42, 23) }; // unfreeze
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
//! This is like `pass/overlapping_assignment_aggregate_scalar.rs` but with a non-scalar
|
||||
//! type, and that makes it definite UB.
|
||||
#![feature(custom_mir, core_intrinsics)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
use std::intrinsics::mir::*;
|
||||
|
||||
#[custom_mir(dialect = "runtime")]
|
||||
fn main() {
|
||||
mir! {
|
||||
let _1: ([u8; 1],);
|
||||
{
|
||||
_1.0 = [0_u8; 1];
|
||||
_1 = (_1.0, ); //~ERROR: overlapping ranges
|
||||
Return()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
error: Undefined Behavior: `copy_nonoverlapping` called on overlapping ranges
|
||||
--> tests/fail/overlapping_assignment_aggregate.rs:LL:CC
|
||||
|
|
||||
LL | _1 = (_1.0, );
|
||||
| ^^^^^^^^^^^^^ Undefined Behavior occurred here
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
= note: inside `main` at tests/fail/overlapping_assignment_aggregate.rs:LL:CC
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
@ -2,7 +2,7 @@ error: Undefined Behavior: constructing invalid value: encountered 0, but expect
|
|||
--> tests/fail/validity/nonzero.rs:LL:CC
|
||||
|
|
||||
LL | let _x = Some(unsafe { NonZero(0) });
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
|
||||
| ^^^^^^^^^^ Undefined Behavior occurred here
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
#![feature(custom_mir, core_intrinsics)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
use std::intrinsics::mir::*;
|
||||
|
||||
#[custom_mir(dialect = "runtime")]
|
||||
fn main() {
|
||||
mir! {
|
||||
let _1: (u8,);
|
||||
{
|
||||
_1.0 = 0_u8;
|
||||
// This is a scalar type, so overlap is (for now) not UB.
|
||||
// However, we used to treat such overlapping assignments incorrectly
|
||||
// (see <https://github.com/rust-lang/rust/issues/146383#issuecomment-3273224645>).
|
||||
_1 = (_1.0, );
|
||||
Return()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -39,7 +39,6 @@ fn init_compiler_benchmarks(
|
|||
"--exact-match",
|
||||
crates.join(",").as_str(),
|
||||
])
|
||||
.env("RUST_LOG", "collector=debug")
|
||||
.env("RUSTC", env.rustc_stage_0().as_str())
|
||||
.env("RUSTC_BOOTSTRAP", "1")
|
||||
.workdir(&env.rustc_perf_dir());
|
||||
|
|
|
|||
|
|
@ -48,40 +48,116 @@ const LICENSES: &[&str] = &[
|
|||
|
||||
type ExceptionList = &'static [(&'static str, &'static str)];
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(crate) struct WorkspaceInfo<'a> {
|
||||
/// Path to the directory containing the workspace root Cargo.toml file.
|
||||
pub(crate) path: &'a str,
|
||||
/// The list of license exceptions.
|
||||
pub(crate) exceptions: ExceptionList,
|
||||
/// Optionally:
|
||||
/// * A list of crates for which dependencies need to be explicitly allowed.
|
||||
/// * The list of allowed dependencies.
|
||||
/// * The source code location of the allowed dependencies list
|
||||
crates_and_deps: Option<(&'a [&'a str], &'a [&'a str], ListLocation)>,
|
||||
/// Submodules required for the workspace
|
||||
pub(crate) submodules: &'a [&'a str],
|
||||
}
|
||||
|
||||
/// The workspaces to check for licensing and optionally permitted dependencies.
|
||||
///
|
||||
/// Each entry consists of a tuple with the following elements:
|
||||
///
|
||||
/// * The path to the workspace root Cargo.toml file.
|
||||
/// * The list of license exceptions.
|
||||
/// * Optionally a tuple of:
|
||||
/// * A list of crates for which dependencies need to be explicitly allowed.
|
||||
/// * The list of allowed dependencies.
|
||||
/// * Submodules required for the workspace.
|
||||
// FIXME auto detect all cargo workspaces
|
||||
pub(crate) const WORKSPACES: &[(&str, ExceptionList, Option<(&[&str], &[&str])>, &[&str])] = &[
|
||||
pub(crate) const WORKSPACES: &[WorkspaceInfo<'static>] = &[
|
||||
// The root workspace has to be first for check_rustfix to work.
|
||||
(".", EXCEPTIONS, Some((&["rustc-main"], PERMITTED_RUSTC_DEPENDENCIES)), &[]),
|
||||
("library", EXCEPTIONS_STDLIB, Some((&["sysroot"], PERMITTED_STDLIB_DEPENDENCIES)), &[]),
|
||||
// Outside of the alphabetical section because rustfmt formats it using multiple lines.
|
||||
(
|
||||
"compiler/rustc_codegen_cranelift",
|
||||
EXCEPTIONS_CRANELIFT,
|
||||
Some((&["rustc_codegen_cranelift"], PERMITTED_CRANELIFT_DEPENDENCIES)),
|
||||
&[],
|
||||
),
|
||||
// tidy-alphabetical-start
|
||||
("compiler/rustc_codegen_gcc", EXCEPTIONS_GCC, None, &[]),
|
||||
("src/bootstrap", EXCEPTIONS_BOOTSTRAP, None, &[]),
|
||||
("src/tools/cargo", EXCEPTIONS_CARGO, None, &["src/tools/cargo"]),
|
||||
//("src/tools/miri/test-cargo-miri", &[], None), // FIXME uncomment once all deps are vendored
|
||||
//("src/tools/miri/test_dependencies", &[], None), // FIXME uncomment once all deps are vendored
|
||||
("src/tools/rust-analyzer", EXCEPTIONS_RUST_ANALYZER, None, &[]),
|
||||
("src/tools/rustbook", EXCEPTIONS_RUSTBOOK, None, &["src/doc/book", "src/doc/reference"]),
|
||||
("src/tools/rustc-perf", EXCEPTIONS_RUSTC_PERF, None, &["src/tools/rustc-perf"]),
|
||||
("src/tools/test-float-parse", EXCEPTIONS, None, &[]),
|
||||
("tests/run-make-cargo/uefi-qemu/uefi_qemu_test", EXCEPTIONS_UEFI_QEMU_TEST, None, &[]),
|
||||
// tidy-alphabetical-end
|
||||
WorkspaceInfo {
|
||||
path: ".",
|
||||
exceptions: EXCEPTIONS,
|
||||
crates_and_deps: Some((
|
||||
&["rustc-main"],
|
||||
PERMITTED_RUSTC_DEPENDENCIES,
|
||||
PERMITTED_RUSTC_DEPS_LOCATION,
|
||||
)),
|
||||
submodules: &[],
|
||||
},
|
||||
WorkspaceInfo {
|
||||
path: "library",
|
||||
exceptions: EXCEPTIONS_STDLIB,
|
||||
crates_and_deps: Some((
|
||||
&["sysroot"],
|
||||
PERMITTED_STDLIB_DEPENDENCIES,
|
||||
PERMITTED_STDLIB_DEPS_LOCATION,
|
||||
)),
|
||||
submodules: &[],
|
||||
},
|
||||
{
|
||||
WorkspaceInfo {
|
||||
path: "compiler/rustc_codegen_cranelift",
|
||||
exceptions: EXCEPTIONS_CRANELIFT,
|
||||
crates_and_deps: Some((
|
||||
&["rustc_codegen_cranelift"],
|
||||
PERMITTED_CRANELIFT_DEPENDENCIES,
|
||||
PERMITTED_CRANELIFT_DEPS_LOCATION,
|
||||
)),
|
||||
submodules: &[],
|
||||
}
|
||||
},
|
||||
WorkspaceInfo {
|
||||
path: "compiler/rustc_codegen_gcc",
|
||||
exceptions: EXCEPTIONS_GCC,
|
||||
crates_and_deps: None,
|
||||
submodules: &[],
|
||||
},
|
||||
WorkspaceInfo {
|
||||
path: "src/bootstrap",
|
||||
exceptions: EXCEPTIONS_BOOTSTRAP,
|
||||
crates_and_deps: None,
|
||||
submodules: &[],
|
||||
},
|
||||
WorkspaceInfo {
|
||||
path: "src/tools/cargo",
|
||||
exceptions: EXCEPTIONS_CARGO,
|
||||
crates_and_deps: None,
|
||||
submodules: &["src/tools/cargo"],
|
||||
},
|
||||
// FIXME uncomment once all deps are vendored
|
||||
// WorkspaceInfo {
|
||||
// path: "src/tools/miri/test-cargo-miri",
|
||||
// crates_and_deps: None
|
||||
// submodules: &[],
|
||||
// },
|
||||
// WorkspaceInfo {
|
||||
// path: "src/tools/miri/test_dependencies",
|
||||
// crates_and_deps: None,
|
||||
// submodules: &[],
|
||||
// }
|
||||
WorkspaceInfo {
|
||||
path: "src/tools/rust-analyzer",
|
||||
exceptions: EXCEPTIONS_RUST_ANALYZER,
|
||||
crates_and_deps: None,
|
||||
submodules: &[],
|
||||
},
|
||||
WorkspaceInfo {
|
||||
path: "src/tools/rustbook",
|
||||
exceptions: EXCEPTIONS_RUSTBOOK,
|
||||
crates_and_deps: None,
|
||||
submodules: &["src/doc/book", "src/doc/reference"],
|
||||
},
|
||||
WorkspaceInfo {
|
||||
path: "src/tools/rustc-perf",
|
||||
exceptions: EXCEPTIONS_RUSTC_PERF,
|
||||
crates_and_deps: None,
|
||||
submodules: &["src/tools/rustc-perf"],
|
||||
},
|
||||
WorkspaceInfo {
|
||||
path: "src/tools/test-float-parse",
|
||||
exceptions: EXCEPTIONS,
|
||||
crates_and_deps: None,
|
||||
submodules: &[],
|
||||
},
|
||||
WorkspaceInfo {
|
||||
path: "tests/run-make-cargo/uefi-qemu/uefi_qemu_test",
|
||||
exceptions: EXCEPTIONS_UEFI_QEMU_TEST,
|
||||
crates_and_deps: None,
|
||||
submodules: &[],
|
||||
},
|
||||
];
|
||||
|
||||
/// These are exceptions to Rust's permissive licensing policy, and
|
||||
|
|
@ -226,7 +302,20 @@ const EXCEPTIONS_UEFI_QEMU_TEST: ExceptionList = &[
|
|||
("r-efi", "MIT OR Apache-2.0 OR LGPL-2.1-or-later"), // LGPL is not acceptable, but we use it under MIT OR Apache-2.0
|
||||
];
|
||||
|
||||
const PERMITTED_DEPS_LOCATION: &str = concat!(file!(), ":", line!());
|
||||
#[derive(Clone, Copy)]
|
||||
struct ListLocation {
|
||||
path: &'static str,
|
||||
line: u32,
|
||||
}
|
||||
|
||||
/// Creates a [`ListLocation`] for the current location (with an additional offset to the actual list start);
|
||||
macro_rules! location {
|
||||
(+ $offset:literal) => {
|
||||
ListLocation { path: file!(), line: line!() + $offset }
|
||||
};
|
||||
}
|
||||
|
||||
const PERMITTED_RUSTC_DEPS_LOCATION: ListLocation = location!(+6);
|
||||
|
||||
/// Crates rustc is allowed to depend on. Avoid adding to the list if possible.
|
||||
///
|
||||
|
|
@ -458,6 +547,8 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
|
|||
// tidy-alphabetical-end
|
||||
];
|
||||
|
||||
const PERMITTED_STDLIB_DEPS_LOCATION: ListLocation = location!(+2);
|
||||
|
||||
const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[
|
||||
// tidy-alphabetical-start
|
||||
"addr2line",
|
||||
|
|
@ -499,6 +590,8 @@ const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[
|
|||
// tidy-alphabetical-end
|
||||
];
|
||||
|
||||
const PERMITTED_CRANELIFT_DEPS_LOCATION: ListLocation = location!(+2);
|
||||
|
||||
const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
|
||||
// tidy-alphabetical-start
|
||||
"allocator-api2",
|
||||
|
|
@ -573,29 +666,30 @@ pub fn check(root: &Path, cargo: &Path, bless: bool, bad: &mut bool) {
|
|||
|
||||
check_proc_macro_dep_list(root, cargo, bless, bad);
|
||||
|
||||
for &(workspace, exceptions, permitted_deps, submodules) in WORKSPACES {
|
||||
for &WorkspaceInfo { path, exceptions, crates_and_deps, submodules } in WORKSPACES {
|
||||
if has_missing_submodule(root, submodules) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if !root.join(workspace).join("Cargo.lock").exists() {
|
||||
tidy_error!(bad, "the `{workspace}` workspace doesn't have a Cargo.lock");
|
||||
if !root.join(path).join("Cargo.lock").exists() {
|
||||
tidy_error!(bad, "the `{path}` workspace doesn't have a Cargo.lock");
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut cmd = cargo_metadata::MetadataCommand::new();
|
||||
cmd.cargo_path(cargo)
|
||||
.manifest_path(root.join(workspace).join("Cargo.toml"))
|
||||
.manifest_path(root.join(path).join("Cargo.toml"))
|
||||
.features(cargo_metadata::CargoOpt::AllFeatures)
|
||||
.other_options(vec!["--locked".to_owned()]);
|
||||
let metadata = t!(cmd.exec());
|
||||
|
||||
check_license_exceptions(&metadata, workspace, exceptions, bad);
|
||||
if let Some((crates, permitted_deps)) = permitted_deps {
|
||||
check_permitted_dependencies(&metadata, workspace, permitted_deps, crates, bad);
|
||||
check_license_exceptions(&metadata, path, exceptions, bad);
|
||||
if let Some((crates, permitted_deps, location)) = crates_and_deps {
|
||||
let descr = crates.get(0).unwrap_or(&path);
|
||||
check_permitted_dependencies(&metadata, descr, permitted_deps, crates, location, bad);
|
||||
}
|
||||
|
||||
if workspace == "library" {
|
||||
if path == "library" {
|
||||
check_runtime_license_exceptions(&metadata, bad);
|
||||
check_runtime_no_duplicate_dependencies(&metadata, bad);
|
||||
check_runtime_no_proc_macros(&metadata, bad);
|
||||
|
|
@ -840,6 +934,7 @@ fn check_permitted_dependencies(
|
|||
descr: &str,
|
||||
permitted_dependencies: &[&'static str],
|
||||
restricted_dependency_crates: &[&'static str],
|
||||
permitted_location: ListLocation,
|
||||
bad: &mut bool,
|
||||
) {
|
||||
let mut has_permitted_dep_error = false;
|
||||
|
|
@ -900,7 +995,7 @@ fn check_permitted_dependencies(
|
|||
}
|
||||
|
||||
if has_permitted_dep_error {
|
||||
eprintln!("Go to `{PERMITTED_DEPS_LOCATION}` for the list.");
|
||||
eprintln!("Go to `{}:{}` for the list.", permitted_location.path, permitted_location.line);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
use crate::deps::WorkspaceInfo;
|
||||
|
||||
/// List of allowed sources for packages.
|
||||
const ALLOWED_SOURCES: &[&str] = &[
|
||||
r#""registry+https://github.com/rust-lang/crates.io-index""#,
|
||||
|
|
@ -13,22 +15,22 @@ const ALLOWED_SOURCES: &[&str] = &[
|
|||
/// Checks for external package sources. `root` is the path to the directory that contains the
|
||||
/// workspace `Cargo.toml`.
|
||||
pub fn check(root: &Path, bad: &mut bool) {
|
||||
for &(workspace, _, _, submodules) in crate::deps::WORKSPACES {
|
||||
for &WorkspaceInfo { path, submodules, .. } in crate::deps::WORKSPACES {
|
||||
if crate::deps::has_missing_submodule(root, submodules) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// FIXME check other workspaces too
|
||||
// `Cargo.lock` of rust.
|
||||
let path = root.join(workspace).join("Cargo.lock");
|
||||
let lockfile = root.join(path).join("Cargo.lock");
|
||||
|
||||
if !path.exists() {
|
||||
tidy_error!(bad, "the `{workspace}` workspace doesn't have a Cargo.lock");
|
||||
if !lockfile.exists() {
|
||||
tidy_error!(bad, "the `{path}` workspace doesn't have a Cargo.lock");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Open and read the whole file.
|
||||
let cargo_lock = t!(fs::read_to_string(&path));
|
||||
let cargo_lock = t!(fs::read_to_string(&lockfile));
|
||||
|
||||
// Process each line.
|
||||
for line in cargo_lock.lines() {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ extern crate minicore;
|
|||
use minicore::*;
|
||||
|
||||
// CHECK-LABEL: @flags_clobber
|
||||
// CHECK: call void asm sideeffect "", "~{vtype},~{vl},~{vxsat},~{vxrm}"()
|
||||
// CHECK: call void asm sideeffect "", "~{fflags},~{vtype},~{vl},~{vxsat},~{vxrm}"()
|
||||
#[no_mangle]
|
||||
pub unsafe fn flags_clobber() {
|
||||
asm!("", options(nostack, nomem));
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn variadic(a: f64, mut args: ...) -> f64 {
|
||||
// CHECK: call void @llvm.lifetime.start.p0(i64 {{[0-9]+}}, ptr nonnull %args)
|
||||
// CHECK: call void @llvm.lifetime.start.p0({{(i64 [0-9]+, )?}}ptr nonnull %args)
|
||||
// CHECK: call void @llvm.va_start.p0(ptr nonnull %args)
|
||||
|
||||
let b = args.arg::<f64>();
|
||||
|
|
@ -17,5 +17,5 @@ unsafe extern "C" fn variadic(a: f64, mut args: ...) -> f64 {
|
|||
a + b + c
|
||||
|
||||
// CHECK: call void @llvm.va_end.p0(ptr nonnull %args)
|
||||
// CHECK: call void @llvm.lifetime.end.p0(i64 {{[0-9]+}}, ptr nonnull %args)
|
||||
// CHECK: call void @llvm.lifetime.end.p0({{(i64 [0-9]+, )?}}ptr nonnull %args)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,19 @@
|
|||
//@ add-core-stubs
|
||||
//@ compile-flags: -Copt-level=3 -C no-prepopulate-passes
|
||||
//@ revisions: riscv64 loongarch64
|
||||
|
||||
//@[riscv64] only-riscv64
|
||||
//@[riscv64] compile-flags: --target riscv64gc-unknown-linux-gnu
|
||||
//@[riscv64] needs-llvm-components: riscv
|
||||
|
||||
//@[loongarch64] only-loongarch64
|
||||
//@[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu
|
||||
//@[loongarch64] needs-llvm-components: loongarch
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(no_core)]
|
||||
#![no_core]
|
||||
|
||||
extern crate minicore;
|
||||
use minicore::*;
|
||||
|
||||
#[no_mangle]
|
||||
// riscv64: define noundef i8 @arg_attr_u8(i8 noundef zeroext %x)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
- // MIR for `rewrap` before DestinationPropagation
|
||||
+ // MIR for `rewrap` after DestinationPropagation
|
||||
|
||||
fn rewrap() -> (u8,) {
|
||||
let mut _0: (u8,);
|
||||
let mut _1: (u8,);
|
||||
let mut _2: (u8,);
|
||||
|
||||
bb0: {
|
||||
- (_1.0: u8) = const 0_u8;
|
||||
- _0 = copy _1;
|
||||
+ (_0.0: u8) = const 0_u8;
|
||||
+ nop;
|
||||
_2 = (copy (_0.0: u8),);
|
||||
_0 = copy _2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
- // MIR for `rewrap` before DestinationPropagation
|
||||
+ // MIR for `rewrap` after DestinationPropagation
|
||||
|
||||
fn rewrap() -> (u8,) {
|
||||
let mut _0: (u8,);
|
||||
let mut _1: (u8,);
|
||||
let mut _2: (u8,);
|
||||
|
||||
bb0: {
|
||||
- (_1.0: u8) = const 0_u8;
|
||||
- _0 = copy _1;
|
||||
+ (_0.0: u8) = const 0_u8;
|
||||
+ nop;
|
||||
_2 = (copy (_0.0: u8),);
|
||||
_0 = copy _2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
51
tests/mir-opt/dest-prop/aggregate.rs
Normal file
51
tests/mir-opt/dest-prop/aggregate.rs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
//@ test-mir-pass: DestinationPropagation
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
|
||||
#![feature(custom_mir, core_intrinsics)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
use std::intrinsics::mir::*;
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
fn dump_var<T>(_: T) {}
|
||||
|
||||
// EMIT_MIR aggregate.rewrap.DestinationPropagation.diff
|
||||
#[custom_mir(dialect = "runtime")]
|
||||
fn rewrap() -> (u8,) {
|
||||
// CHECK-LABEL: fn rewrap(
|
||||
// CHECK: (_0.0: u8) = const 0_u8;
|
||||
// CHECK: _2 = (copy (_0.0: u8),);
|
||||
// CHECK: _0 = copy _2;
|
||||
mir! {
|
||||
let _1: (u8,);
|
||||
let _2: (u8,);
|
||||
{
|
||||
_1.0 = 0;
|
||||
RET = _1;
|
||||
_2 = (RET.0, );
|
||||
RET = _2;
|
||||
Return()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// EMIT_MIR aggregate.swap.DestinationPropagation.diff
|
||||
#[custom_mir(dialect = "runtime")]
|
||||
fn swap() -> (MaybeUninit<[u8; 10]>, MaybeUninit<[u8; 10]>) {
|
||||
// CHECK-LABEL: fn swap(
|
||||
// CHECK: _0 = const
|
||||
// CHECK: _2 = copy _0;
|
||||
// CHECK: _0 = (copy (_2.1: {{.*}}), copy (_2.0: {{.*}}));
|
||||
mir! {
|
||||
let _1: (MaybeUninit<[u8; 10]>, MaybeUninit<[u8; 10]>);
|
||||
let _2: (MaybeUninit<[u8; 10]>, MaybeUninit<[u8; 10]>);
|
||||
let _3: ();
|
||||
{
|
||||
_1 = const { (MaybeUninit::new([0; 10]), MaybeUninit::new([1; 10])) };
|
||||
_2 = _1;
|
||||
_1 = (_2.1, _2.0);
|
||||
RET = _1;
|
||||
Return()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
- // MIR for `swap` before DestinationPropagation
|
||||
+ // MIR for `swap` after DestinationPropagation
|
||||
|
||||
fn swap() -> (MaybeUninit<[u8; 10]>, MaybeUninit<[u8; 10]>) {
|
||||
let mut _0: (std::mem::MaybeUninit<[u8; 10]>, std::mem::MaybeUninit<[u8; 10]>);
|
||||
let mut _1: (std::mem::MaybeUninit<[u8; 10]>, std::mem::MaybeUninit<[u8; 10]>);
|
||||
let mut _2: (std::mem::MaybeUninit<[u8; 10]>, std::mem::MaybeUninit<[u8; 10]>);
|
||||
let mut _3: ();
|
||||
|
||||
bb0: {
|
||||
- _1 = const swap::{constant#6};
|
||||
- _2 = copy _1;
|
||||
- _1 = (copy (_2.1: std::mem::MaybeUninit<[u8; 10]>), copy (_2.0: std::mem::MaybeUninit<[u8; 10]>));
|
||||
- _0 = copy _1;
|
||||
+ _0 = const swap::{constant#6};
|
||||
+ _2 = copy _0;
|
||||
+ _0 = (copy (_2.1: std::mem::MaybeUninit<[u8; 10]>), copy (_2.0: std::mem::MaybeUninit<[u8; 10]>));
|
||||
+ nop;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
- // MIR for `swap` before DestinationPropagation
|
||||
+ // MIR for `swap` after DestinationPropagation
|
||||
|
||||
fn swap() -> (MaybeUninit<[u8; 10]>, MaybeUninit<[u8; 10]>) {
|
||||
let mut _0: (std::mem::MaybeUninit<[u8; 10]>, std::mem::MaybeUninit<[u8; 10]>);
|
||||
let mut _1: (std::mem::MaybeUninit<[u8; 10]>, std::mem::MaybeUninit<[u8; 10]>);
|
||||
let mut _2: (std::mem::MaybeUninit<[u8; 10]>, std::mem::MaybeUninit<[u8; 10]>);
|
||||
let mut _3: ();
|
||||
|
||||
bb0: {
|
||||
- _1 = const swap::{constant#6};
|
||||
- _2 = copy _1;
|
||||
- _1 = (copy (_2.1: std::mem::MaybeUninit<[u8; 10]>), copy (_2.0: std::mem::MaybeUninit<[u8; 10]>));
|
||||
- _0 = copy _1;
|
||||
+ _0 = const swap::{constant#6};
|
||||
+ _2 = copy _0;
|
||||
+ _0 = (copy (_2.1: std::mem::MaybeUninit<[u8; 10]>), copy (_2.0: std::mem::MaybeUninit<[u8; 10]>));
|
||||
+ nop;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -8,7 +8,7 @@ trait Get {
|
|||
}
|
||||
|
||||
trait Other {
|
||||
fn uhoh<U: Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Sized, Self: Get, Self: Get {}
|
||||
fn uhoh<U: Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Sized, Self: Get {}
|
||||
//~^ ERROR the trait bound `Self: Get` is not satisfied
|
||||
//~| ERROR the trait bound `Self: Get` is not satisfied
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#![feature(adt_const_params, unsized_const_params)]
|
||||
|
||||
#[derive(std::marker::UnsizedConstParamTy, Eq, PartialEq)]
|
||||
#[derive(std::marker::ConstParamTy, Eq, PartialEq)]
|
||||
pub struct Foo([u8]);
|
||||
|
||||
#[derive(std::marker::ConstParamTy, Eq, PartialEq)]
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#![allow(incomplete_features)]
|
||||
#![feature(adt_const_params, unsized_const_params)]
|
||||
|
||||
fn check(_: impl std::marker::UnsizedConstParamTy) {}
|
||||
fn check(_: impl std::marker::ConstParamTy_) {}
|
||||
|
||||
fn main() {
|
||||
check(main); //~ error: `fn() {main}` can't be used as a const parameter type
|
||||
|
|
|
|||
|
|
@ -2,15 +2,15 @@ error[E0277]: `fn() {main}` can't be used as a const parameter type
|
|||
--> $DIR/const_param_ty_bad.rs:7:11
|
||||
|
|
||||
LL | check(main);
|
||||
| ----- ^^^^ the trait `UnsizedConstParamTy` is not implemented for fn item `fn() {main}`
|
||||
| ----- ^^^^ the trait `ConstParamTy_` is not implemented for fn item `fn() {main}`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `check`
|
||||
--> $DIR/const_param_ty_bad.rs:4:18
|
||||
|
|
||||
LL | fn check(_: impl std::marker::UnsizedConstParamTy) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
LL | fn check(_: impl std::marker::ConstParamTy_) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
help: use parentheses to call this function
|
||||
|
|
||||
LL | check(main());
|
||||
|
|
@ -24,12 +24,12 @@ LL | check(|| {});
|
|||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: the trait `UnsizedConstParamTy` is not implemented for closure `{closure@$DIR/const_param_ty_bad.rs:8:11: 8:13}`
|
||||
= help: the trait `ConstParamTy_` is not implemented for closure `{closure@$DIR/const_param_ty_bad.rs:8:11: 8:13}`
|
||||
note: required by a bound in `check`
|
||||
--> $DIR/const_param_ty_bad.rs:4:18
|
||||
|
|
||||
LL | fn check(_: impl std::marker::UnsizedConstParamTy) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
LL | fn check(_: impl std::marker::ConstParamTy_) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
help: use parentheses to call this closure
|
||||
|
|
||||
LL - check(|| {});
|
||||
|
|
@ -40,15 +40,15 @@ error[E0277]: `fn()` can't be used as a const parameter type
|
|||
--> $DIR/const_param_ty_bad.rs:9:11
|
||||
|
|
||||
LL | check(main as fn());
|
||||
| ----- ^^^^^^^^^^^^ the trait `UnsizedConstParamTy` is not implemented for `fn()`
|
||||
| ----- ^^^^^^^^^^^^ the trait `ConstParamTy_` is not implemented for `fn()`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `check`
|
||||
--> $DIR/const_param_ty_bad.rs:4:18
|
||||
|
|
||||
LL | fn check(_: impl std::marker::UnsizedConstParamTy) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
LL | fn check(_: impl std::marker::ConstParamTy_) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
help: use parentheses to call this function pointer
|
||||
|
|
||||
LL | check(main as fn()());
|
||||
|
|
@ -58,16 +58,16 @@ error[E0277]: `&mut ()` can't be used as a const parameter type
|
|||
--> $DIR/const_param_ty_bad.rs:10:11
|
||||
|
|
||||
LL | check(&mut ());
|
||||
| ----- ^^^^^^^ the trait `UnsizedConstParamTy` is not implemented for `&mut ()`
|
||||
| ----- ^^^^^^^ the trait `ConstParamTy_` is not implemented for `&mut ()`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= note: `UnsizedConstParamTy` is implemented for `&()`, but not for `&mut ()`
|
||||
= note: `ConstParamTy_` is implemented for `&()`, but not for `&mut ()`
|
||||
note: required by a bound in `check`
|
||||
--> $DIR/const_param_ty_bad.rs:4:18
|
||||
|
|
||||
LL | fn check(_: impl std::marker::UnsizedConstParamTy) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
LL | fn check(_: impl std::marker::ConstParamTy_) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
help: consider removing the leading `&`-reference
|
||||
|
|
||||
LL - check(&mut ());
|
||||
|
|
@ -78,31 +78,31 @@ error[E0277]: `*mut ()` can't be used as a const parameter type
|
|||
--> $DIR/const_param_ty_bad.rs:11:11
|
||||
|
|
||||
LL | check(&mut () as *mut ());
|
||||
| ----- ^^^^^^^^^^^^^^^^^^ the trait `UnsizedConstParamTy` is not implemented for `*mut ()`
|
||||
| ----- ^^^^^^^^^^^^^^^^^^ the trait `ConstParamTy_` is not implemented for `*mut ()`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: the trait `UnsizedConstParamTy` is implemented for `()`
|
||||
= help: the trait `ConstParamTy_` is implemented for `()`
|
||||
note: required by a bound in `check`
|
||||
--> $DIR/const_param_ty_bad.rs:4:18
|
||||
|
|
||||
LL | fn check(_: impl std::marker::UnsizedConstParamTy) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
LL | fn check(_: impl std::marker::ConstParamTy_) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
|
||||
error[E0277]: `*const ()` can't be used as a const parameter type
|
||||
--> $DIR/const_param_ty_bad.rs:12:11
|
||||
|
|
||||
LL | check(&() as *const ());
|
||||
| ----- ^^^^^^^^^^^^^^^^ the trait `UnsizedConstParamTy` is not implemented for `*const ()`
|
||||
| ----- ^^^^^^^^^^^^^^^^ the trait `ConstParamTy_` is not implemented for `*const ()`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: the trait `UnsizedConstParamTy` is implemented for `()`
|
||||
= help: the trait `ConstParamTy_` is implemented for `()`
|
||||
note: required by a bound in `check`
|
||||
--> $DIR/const_param_ty_bad.rs:4:18
|
||||
|
|
||||
LL | fn check(_: impl std::marker::UnsizedConstParamTy) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
LL | fn check(_: impl std::marker::ConstParamTy_) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
#![feature(adt_const_params, unsized_const_params)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::marker::{ConstParamTy_, UnsizedConstParamTy};
|
||||
use std::marker::ConstParamTy_;
|
||||
|
||||
fn foo(a: &dyn ConstParamTy_) {}
|
||||
//~^ ERROR: the trait `ConstParamTy_`
|
||||
|
||||
fn bar(a: &dyn UnsizedConstParamTy) {}
|
||||
//~^ ERROR: the trait `UnsizedConstParamTy`
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -15,23 +15,6 @@ LL - fn foo(a: &dyn ConstParamTy_) {}
|
|||
LL + fn foo(a: &impl ConstParamTy_) {}
|
||||
|
|
||||
|
||||
error[E0038]: the trait `UnsizedConstParamTy` is not dyn compatible
|
||||
--> $DIR/const_param_ty_dyn_compatibility.rs:9:16
|
||||
|
|
||||
LL | fn bar(a: &dyn UnsizedConstParamTy) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^ `UnsizedConstParamTy` is not dyn compatible
|
||||
|
|
||||
note: for a trait to be dyn compatible it needs to allow building a vtable
|
||||
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
--> $SRC_DIR/core/src/cmp.rs:LL:COL
|
||||
|
|
||||
= note: the trait is not dyn compatible because it uses `Self` as a type parameter
|
||||
help: consider using an opaque type instead
|
||||
|
|
||||
LL - fn bar(a: &dyn UnsizedConstParamTy) {}
|
||||
LL + fn bar(a: &impl UnsizedConstParamTy) {}
|
||||
|
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
#[derive(PartialEq, Eq)]
|
||||
struct NotParam;
|
||||
|
||||
fn check<T: std::marker::UnsizedConstParamTy + ?Sized>() {}
|
||||
fn check<T: std::marker::ConstParamTy_ + ?Sized>() {}
|
||||
|
||||
fn main() {
|
||||
check::<&NotParam>(); //~ error: `NotParam` can't be used as a const parameter type
|
||||
|
|
|
|||
|
|
@ -4,17 +4,17 @@ error[E0277]: `NotParam` can't be used as a const parameter type
|
|||
LL | check::<&NotParam>();
|
||||
| ^^^^^^^^^ unsatisfied trait bound
|
||||
|
|
||||
help: the trait `UnsizedConstParamTy` is not implemented for `NotParam`
|
||||
help: the trait `ConstParamTy_` is not implemented for `NotParam`
|
||||
--> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:5:1
|
||||
|
|
||||
LL | struct NotParam;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
= note: required for `&NotParam` to implement `UnsizedConstParamTy`
|
||||
= note: required for `&NotParam` to implement `ConstParamTy_`
|
||||
note: required by a bound in `check`
|
||||
--> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:7:13
|
||||
|
|
||||
LL | fn check<T: std::marker::UnsizedConstParamTy + ?Sized>() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
LL | fn check<T: std::marker::ConstParamTy_ + ?Sized>() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
|
||||
error[E0277]: `NotParam` can't be used as a const parameter type
|
||||
--> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:11:13
|
||||
|
|
@ -22,17 +22,17 @@ error[E0277]: `NotParam` can't be used as a const parameter type
|
|||
LL | check::<[NotParam]>();
|
||||
| ^^^^^^^^^^ unsatisfied trait bound
|
||||
|
|
||||
help: the trait `UnsizedConstParamTy` is not implemented for `NotParam`
|
||||
help: the trait `ConstParamTy_` is not implemented for `NotParam`
|
||||
--> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:5:1
|
||||
|
|
||||
LL | struct NotParam;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
= note: required for `[NotParam]` to implement `UnsizedConstParamTy`
|
||||
= note: required for `[NotParam]` to implement `ConstParamTy_`
|
||||
note: required by a bound in `check`
|
||||
--> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:7:13
|
||||
|
|
||||
LL | fn check<T: std::marker::UnsizedConstParamTy + ?Sized>() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
LL | fn check<T: std::marker::ConstParamTy_ + ?Sized>() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
|
||||
error[E0277]: `NotParam` can't be used as a const parameter type
|
||||
--> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:12:13
|
||||
|
|
@ -40,17 +40,17 @@ error[E0277]: `NotParam` can't be used as a const parameter type
|
|||
LL | check::<[NotParam; 17]>();
|
||||
| ^^^^^^^^^^^^^^ unsatisfied trait bound
|
||||
|
|
||||
help: the trait `UnsizedConstParamTy` is not implemented for `NotParam`
|
||||
help: the trait `ConstParamTy_` is not implemented for `NotParam`
|
||||
--> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:5:1
|
||||
|
|
||||
LL | struct NotParam;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
= note: required for `[NotParam; 17]` to implement `UnsizedConstParamTy`
|
||||
= note: required for `[NotParam; 17]` to implement `ConstParamTy_`
|
||||
note: required by a bound in `check`
|
||||
--> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:7:13
|
||||
|
|
||||
LL | fn check<T: std::marker::UnsizedConstParamTy + ?Sized>() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
LL | fn check<T: std::marker::ConstParamTy_ + ?Sized>() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#![feature(adt_const_params, unsized_const_params)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::marker::UnsizedConstParamTy;
|
||||
use std::marker::{ConstParamTy, ConstParamTy_};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
struct S<T> {
|
||||
|
|
@ -11,15 +11,15 @@ struct S<T> {
|
|||
gen: T,
|
||||
}
|
||||
|
||||
impl<T: UnsizedConstParamTy> UnsizedConstParamTy for S<T> {}
|
||||
impl<T: ConstParamTy_> ConstParamTy_ for S<T> {}
|
||||
|
||||
#[derive(PartialEq, Eq, UnsizedConstParamTy)]
|
||||
#[derive(PartialEq, Eq, ConstParamTy)]
|
||||
struct D<T> {
|
||||
field: u8,
|
||||
gen: T,
|
||||
}
|
||||
|
||||
fn check<T: UnsizedConstParamTy + ?Sized>() {}
|
||||
fn check<T: ConstParamTy_ + ?Sized>() {}
|
||||
|
||||
fn main() {
|
||||
check::<u8>();
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ struct NotParam;
|
|||
#[derive(PartialEq, Eq)]
|
||||
struct CantParam(NotParam);
|
||||
|
||||
impl std::marker::UnsizedConstParamTy for CantParam {}
|
||||
impl std::marker::ConstParamTy_ for CantParam {}
|
||||
//~^ error: the trait `ConstParamTy_` cannot be implemented for this type
|
||||
|
||||
#[derive(std::marker::UnsizedConstParamTy, Eq, PartialEq)]
|
||||
#[derive(std::marker::ConstParamTy, Eq, PartialEq)]
|
||||
//~^ error: the trait `ConstParamTy_` cannot be implemented for this type
|
||||
struct CantParamDerive(NotParam);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type
|
||||
--> $DIR/const_param_ty_impl_bad_field.rs:10:43
|
||||
--> $DIR/const_param_ty_impl_bad_field.rs:10:37
|
||||
|
|
||||
LL | struct CantParam(NotParam);
|
||||
| -------- this field does not implement `ConstParamTy_`
|
||||
LL |
|
||||
LL | impl std::marker::UnsizedConstParamTy for CantParam {}
|
||||
| ^^^^^^^^^
|
||||
LL | impl std::marker::ConstParamTy_ for CantParam {}
|
||||
| ^^^^^^^^^
|
||||
|
||||
error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type
|
||||
--> $DIR/const_param_ty_impl_bad_field.rs:13:10
|
||||
|
|
||||
LL | #[derive(std::marker::UnsizedConstParamTy, Eq, PartialEq)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #[derive(std::marker::ConstParamTy, Eq, PartialEq)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL |
|
||||
LL | struct CantParamDerive(NotParam);
|
||||
| -------- this field does not implement `ConstParamTy_`
|
||||
|
|
|
|||
|
|
@ -3,20 +3,20 @@
|
|||
|
||||
#[derive(PartialEq, Eq)]
|
||||
struct ImplementsConstParamTy;
|
||||
impl std::marker::UnsizedConstParamTy for ImplementsConstParamTy {}
|
||||
impl std::marker::ConstParamTy_ for ImplementsConstParamTy {}
|
||||
|
||||
struct CantParam(ImplementsConstParamTy);
|
||||
|
||||
impl std::marker::UnsizedConstParamTy for CantParam {}
|
||||
impl std::marker::ConstParamTy_ for CantParam {}
|
||||
//~^ error: the type `CantParam` does not `#[derive(PartialEq)]`
|
||||
//~| ERROR the trait bound `CantParam: Eq` is not satisfied
|
||||
|
||||
#[derive(std::marker::UnsizedConstParamTy)]
|
||||
#[derive(std::marker::ConstParamTy)]
|
||||
//~^ error: the type `CantParamDerive` does not `#[derive(PartialEq)]`
|
||||
//~| ERROR the trait bound `CantParamDerive: Eq` is not satisfied
|
||||
struct CantParamDerive(ImplementsConstParamTy);
|
||||
|
||||
fn check<T: std::marker::UnsizedConstParamTy>() {}
|
||||
fn check<T: std::marker::ConstParamTy_>() {}
|
||||
|
||||
fn main() {
|
||||
check::<ImplementsConstParamTy>();
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
error[E0277]: the trait bound `CantParam: Eq` is not satisfied
|
||||
--> $DIR/const_param_ty_impl_no_structural_eq.rs:10:43
|
||||
--> $DIR/const_param_ty_impl_no_structural_eq.rs:10:37
|
||||
|
|
||||
LL | impl std::marker::UnsizedConstParamTy for CantParam {}
|
||||
| ^^^^^^^^^ the trait `Eq` is not implemented for `CantParam`
|
||||
LL | impl std::marker::ConstParamTy_ for CantParam {}
|
||||
| ^^^^^^^^^ the trait `Eq` is not implemented for `CantParam`
|
||||
|
|
||||
note: required by a bound in `UnsizedConstParamTy`
|
||||
note: required by a bound in `ConstParamTy_`
|
||||
--> $SRC_DIR/core/src/marker.rs:LL:COL
|
||||
help: consider annotating `CantParam` with `#[derive(Eq)]`
|
||||
|
|
||||
|
|
@ -13,26 +13,26 @@ LL | struct CantParam(ImplementsConstParamTy);
|
|||
|
|
||||
|
||||
error[E0277]: the type `CantParam` does not `#[derive(PartialEq)]`
|
||||
--> $DIR/const_param_ty_impl_no_structural_eq.rs:10:43
|
||||
--> $DIR/const_param_ty_impl_no_structural_eq.rs:10:37
|
||||
|
|
||||
LL | impl std::marker::UnsizedConstParamTy for CantParam {}
|
||||
| ^^^^^^^^^ unsatisfied trait bound
|
||||
LL | impl std::marker::ConstParamTy_ for CantParam {}
|
||||
| ^^^^^^^^^ unsatisfied trait bound
|
||||
|
|
||||
help: the trait `StructuralPartialEq` is not implemented for `CantParam`
|
||||
--> $DIR/const_param_ty_impl_no_structural_eq.rs:8:1
|
||||
|
|
||||
LL | struct CantParam(ImplementsConstParamTy);
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
note: required by a bound in `UnsizedConstParamTy`
|
||||
note: required by a bound in `ConstParamTy_`
|
||||
--> $SRC_DIR/core/src/marker.rs:LL:COL
|
||||
|
||||
error[E0277]: the trait bound `CantParamDerive: Eq` is not satisfied
|
||||
--> $DIR/const_param_ty_impl_no_structural_eq.rs:14:10
|
||||
|
|
||||
LL | #[derive(std::marker::UnsizedConstParamTy)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `CantParamDerive`
|
||||
LL | #[derive(std::marker::ConstParamTy)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `CantParamDerive`
|
||||
|
|
||||
note: required by a bound in `UnsizedConstParamTy`
|
||||
note: required by a bound in `ConstParamTy_`
|
||||
--> $SRC_DIR/core/src/marker.rs:LL:COL
|
||||
help: consider annotating `CantParamDerive` with `#[derive(Eq)]`
|
||||
|
|
||||
|
|
@ -43,15 +43,15 @@ LL | struct CantParamDerive(ImplementsConstParamTy);
|
|||
error[E0277]: the type `CantParamDerive` does not `#[derive(PartialEq)]`
|
||||
--> $DIR/const_param_ty_impl_no_structural_eq.rs:14:10
|
||||
|
|
||||
LL | #[derive(std::marker::UnsizedConstParamTy)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
|
||||
LL | #[derive(std::marker::ConstParamTy)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
|
||||
|
|
||||
help: the trait `StructuralPartialEq` is not implemented for `CantParamDerive`
|
||||
--> $DIR/const_param_ty_impl_no_structural_eq.rs:17:1
|
||||
|
|
||||
LL | struct CantParamDerive(ImplementsConstParamTy);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: required by a bound in `UnsizedConstParamTy`
|
||||
note: required by a bound in `ConstParamTy_`
|
||||
--> $SRC_DIR/core/src/marker.rs:LL:COL
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ impl PartialEq for Union {
|
|||
}
|
||||
impl Eq for Union {}
|
||||
|
||||
impl std::marker::UnsizedConstParamTy for Union {}
|
||||
impl std::marker::ConstParamTy_ for Union {}
|
||||
//~^ ERROR the trait `ConstParamTy` may not be implemented for this type
|
||||
|
||||
#[derive(std::marker::UnsizedConstParamTy)]
|
||||
#[derive(std::marker::ConstParamTy)]
|
||||
//~^ ERROR this trait cannot be derived for unions
|
||||
union UnionDerive {
|
||||
a: u8,
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
error: this trait cannot be derived for unions
|
||||
--> $DIR/const_param_ty_impl_union.rs:18:10
|
||||
|
|
||||
LL | #[derive(std::marker::UnsizedConstParamTy)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #[derive(std::marker::ConstParamTy)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: the trait `ConstParamTy` may not be implemented for this type
|
||||
--> $DIR/const_param_ty_impl_union.rs:15:43
|
||||
--> $DIR/const_param_ty_impl_union.rs:15:37
|
||||
|
|
||||
LL | impl std::marker::UnsizedConstParamTy for Union {}
|
||||
| ^^^^^ type is not a structure or enumeration
|
||||
LL | impl std::marker::ConstParamTy_ for Union {}
|
||||
| ^^^^^ type is not a structure or enumeration
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -5,17 +5,14 @@ use std::marker::ConstParamTy;
|
|||
|
||||
#[derive(ConstParamTy)]
|
||||
//~^ ERROR the trait `ConstParamTy_` cannot be implemented for this ty
|
||||
//~| ERROR the trait `ConstParamTy_` cannot be implemented for this ty
|
||||
struct Foo([*const u8; 1]);
|
||||
|
||||
#[derive(ConstParamTy)]
|
||||
//~^ ERROR the trait `ConstParamTy_` cannot be implemented for this ty
|
||||
//~| ERROR the trait `ConstParamTy_` cannot be implemented for this ty
|
||||
struct Foo2([*mut u8; 1]);
|
||||
|
||||
#[derive(ConstParamTy)]
|
||||
//~^ ERROR the trait `ConstParamTy_` cannot be implemented for this ty
|
||||
//~| ERROR the trait `ConstParamTy_` cannot be implemented for this ty
|
||||
struct Foo3([fn(); 1]);
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -3,91 +3,46 @@ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type
|
|||
|
|
||||
LL | #[derive(ConstParamTy)]
|
||||
| ^^^^^^^^^^^^
|
||||
...
|
||||
LL |
|
||||
LL | struct Foo([*const u8; 1]);
|
||||
| -------------- this field does not implement `ConstParamTy_`
|
||||
|
|
||||
note: the `ConstParamTy_` impl for `[*const u8; 1]` requires that `*const u8: ConstParamTy_`
|
||||
--> $DIR/nested_bad_const_param_ty.rs:9:12
|
||||
--> $DIR/nested_bad_const_param_ty.rs:8:12
|
||||
|
|
||||
LL | struct Foo([*const u8; 1]);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type
|
||||
--> $DIR/nested_bad_const_param_ty.rs:11:10
|
||||
--> $DIR/nested_bad_const_param_ty.rs:10:10
|
||||
|
|
||||
LL | #[derive(ConstParamTy)]
|
||||
| ^^^^^^^^^^^^
|
||||
...
|
||||
LL |
|
||||
LL | struct Foo2([*mut u8; 1]);
|
||||
| ------------ this field does not implement `ConstParamTy_`
|
||||
|
|
||||
note: the `ConstParamTy_` impl for `[*mut u8; 1]` requires that `*mut u8: ConstParamTy_`
|
||||
--> $DIR/nested_bad_const_param_ty.rs:14:13
|
||||
--> $DIR/nested_bad_const_param_ty.rs:12:13
|
||||
|
|
||||
LL | struct Foo2([*mut u8; 1]);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type
|
||||
--> $DIR/nested_bad_const_param_ty.rs:16:10
|
||||
--> $DIR/nested_bad_const_param_ty.rs:14:10
|
||||
|
|
||||
LL | #[derive(ConstParamTy)]
|
||||
| ^^^^^^^^^^^^
|
||||
...
|
||||
LL |
|
||||
LL | struct Foo3([fn(); 1]);
|
||||
| --------- this field does not implement `ConstParamTy_`
|
||||
|
|
||||
note: the `ConstParamTy_` impl for `[fn(); 1]` requires that `fn(): ConstParamTy_`
|
||||
--> $DIR/nested_bad_const_param_ty.rs:19:13
|
||||
--> $DIR/nested_bad_const_param_ty.rs:16:13
|
||||
|
|
||||
LL | struct Foo3([fn(); 1]);
|
||||
| ^^^^^^^^^
|
||||
|
||||
error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type
|
||||
--> $DIR/nested_bad_const_param_ty.rs:6:10
|
||||
|
|
||||
LL | #[derive(ConstParamTy)]
|
||||
| ^^^^^^^^^^^^
|
||||
...
|
||||
LL | struct Foo([*const u8; 1]);
|
||||
| -------------- this field does not implement `ConstParamTy_`
|
||||
|
|
||||
note: the `ConstParamTy_` impl for `[*const u8; 1]` requires that `*const u8: UnsizedConstParamTy`
|
||||
--> $DIR/nested_bad_const_param_ty.rs:9:12
|
||||
|
|
||||
LL | struct Foo([*const u8; 1]);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type
|
||||
--> $DIR/nested_bad_const_param_ty.rs:11:10
|
||||
|
|
||||
LL | #[derive(ConstParamTy)]
|
||||
| ^^^^^^^^^^^^
|
||||
...
|
||||
LL | struct Foo2([*mut u8; 1]);
|
||||
| ------------ this field does not implement `ConstParamTy_`
|
||||
|
|
||||
note: the `ConstParamTy_` impl for `[*mut u8; 1]` requires that `*mut u8: UnsizedConstParamTy`
|
||||
--> $DIR/nested_bad_const_param_ty.rs:14:13
|
||||
|
|
||||
LL | struct Foo2([*mut u8; 1]);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type
|
||||
--> $DIR/nested_bad_const_param_ty.rs:16:10
|
||||
|
|
||||
LL | #[derive(ConstParamTy)]
|
||||
| ^^^^^^^^^^^^
|
||||
...
|
||||
LL | struct Foo3([fn(); 1]);
|
||||
| --------- this field does not implement `ConstParamTy_`
|
||||
|
|
||||
note: the `ConstParamTy_` impl for `[fn(); 1]` requires that `fn(): UnsizedConstParamTy`
|
||||
--> $DIR/nested_bad_const_param_ty.rs:19:13
|
||||
|
|
||||
LL | struct Foo3([fn(); 1]);
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0204`.
|
||||
|
|
|
|||
|
|
@ -9,11 +9,13 @@ help: you might be missing a const parameter
|
|||
LL | impl<const bar: /* Type */> Wrapper<{ bar() }> {
|
||||
| +++++++++++++++++++++++
|
||||
|
||||
error[E0741]: using function pointers as const generic parameters is forbidden
|
||||
error: using function pointers as const generic parameters is forbidden
|
||||
--> $DIR/non_valtreeable_const_arg-2.rs:8:25
|
||||
|
|
||||
LL | struct Wrapper<const F: fn()>;
|
||||
| ^^^^
|
||||
|
|
||||
= note: the only supported types are integers, `bool`, and `char`
|
||||
|
||||
error[E0599]: the function or associated item `call` exists for struct `Wrapper<function>`, but its trait bounds were not satisfied
|
||||
--> $DIR/non_valtreeable_const_arg-2.rs:17:26
|
||||
|
|
@ -35,5 +37,5 @@ note: the trait `Fn` must be implemented
|
|||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0425, E0599, E0741.
|
||||
Some errors have detailed explanations: E0425, E0599.
|
||||
For more information about an error, try `rustc --explain E0425`.
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
#![feature(adt_const_params, unsized_const_params)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::marker::UnsizedConstParamTy;
|
||||
use std::marker::ConstParamTy_;
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl UnsizedConstParamTy for &'static Foo {}
|
||||
impl ConstParamTy_ for &'static Foo {}
|
||||
//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type
|
||||
--> $DIR/reference_pointee_is_const_param-1.rs:8:30
|
||||
--> $DIR/reference_pointee_is_const_param-1.rs:8:24
|
||||
|
|
||||
LL | impl UnsizedConstParamTy for &'static Foo {}
|
||||
| ^^^^^^^^^^^^ this field does not implement `ConstParamTy_`
|
||||
LL | impl ConstParamTy_ for &'static Foo {}
|
||||
| ^^^^^^^^^^^^ this field does not implement `ConstParamTy_`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@
|
|||
|
||||
// Regression test for #119299
|
||||
|
||||
use std::marker::UnsizedConstParamTy;
|
||||
use std::marker::ConstParamTy_;
|
||||
|
||||
#[derive(Eq, PartialEq)]
|
||||
struct ConstStrU(*const u8, usize);
|
||||
|
||||
impl UnsizedConstParamTy for &'static ConstStrU {}
|
||||
impl ConstParamTy_ for &'static ConstStrU {}
|
||||
//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type
|
||||
|
||||
impl ConstStrU {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type
|
||||
--> $DIR/reference_pointee_is_const_param-2.rs:11:30
|
||||
--> $DIR/reference_pointee_is_const_param-2.rs:11:24
|
||||
|
|
||||
LL | impl UnsizedConstParamTy for &'static ConstStrU {}
|
||||
| ^^^^^^^^^^^^^^^^^^ this field does not implement `ConstParamTy_`
|
||||
LL | impl ConstParamTy_ for &'static ConstStrU {}
|
||||
| ^^^^^^^^^^^^^^^^^^ this field does not implement `ConstParamTy_`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
#![feature(adt_const_params, unsized_const_params)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::marker::UnsizedConstParamTy;
|
||||
use std::marker::ConstParamTy_;
|
||||
|
||||
trait Trait {}
|
||||
|
||||
impl UnsizedConstParamTy for dyn Trait {}
|
||||
impl ConstParamTy_ for dyn Trait {}
|
||||
//~^ ERROR: the trait `ConstParamTy` may not be implemented for this type
|
||||
|
||||
fn foo<const N: dyn Trait>() {}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error: the trait `ConstParamTy` may not be implemented for this type
|
||||
--> $DIR/trait_objects_as_a_const_generic.rs:8:30
|
||||
--> $DIR/trait_objects_as_a_const_generic.rs:8:24
|
||||
|
|
||||
LL | impl UnsizedConstParamTy for dyn Trait {}
|
||||
| ^^^^^^^^^ type is not a structure or enumeration
|
||||
LL | impl ConstParamTy_ for dyn Trait {}
|
||||
| ^^^^^^^^^ type is not a structure or enumeration
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,10 @@ struct A([u8]);
|
|||
struct B(&'static [u8]);
|
||||
|
||||
#[derive(ConstParamTy, Eq, PartialEq)]
|
||||
//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type
|
||||
struct C(unsized_const_param::Foo);
|
||||
|
||||
#[derive(std::marker::ConstParamTy, Eq, PartialEq)]
|
||||
//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type
|
||||
struct D(unsized_const_param::GenericNotUnsizedParam<&'static [u8]>);
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,12 @@ LL | #[derive(ConstParamTy, Eq, PartialEq)]
|
|||
LL |
|
||||
LL | struct A([u8]);
|
||||
| ---- this field does not implement `ConstParamTy_`
|
||||
|
|
||||
note: the `ConstParamTy_` impl for `[u8]` requires that `unstable feature: `unsized_const_params``
|
||||
--> $DIR/unsized_field-1.rs:10:10
|
||||
|
|
||||
LL | struct A([u8]);
|
||||
| ^^^^
|
||||
|
||||
error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type
|
||||
--> $DIR/unsized_field-1.rs:12:10
|
||||
|
|
@ -15,15 +21,27 @@ LL | #[derive(ConstParamTy, Eq, PartialEq)]
|
|||
LL |
|
||||
LL | struct B(&'static [u8]);
|
||||
| ------------- this field does not implement `ConstParamTy_`
|
||||
|
|
||||
note: the `ConstParamTy_` impl for `&'static [u8]` requires that `unstable feature: `unsized_const_params``
|
||||
--> $DIR/unsized_field-1.rs:14:10
|
||||
|
|
||||
LL | struct B(&'static [u8]);
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type
|
||||
--> $DIR/unsized_field-1.rs:16:10
|
||||
--> $DIR/unsized_field-1.rs:19:10
|
||||
|
|
||||
LL | #[derive(ConstParamTy, Eq, PartialEq)]
|
||||
| ^^^^^^^^^^^^
|
||||
LL | #[derive(std::marker::ConstParamTy, Eq, PartialEq)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL |
|
||||
LL | struct C(unsized_const_param::Foo);
|
||||
| ------------------------ this field does not implement `ConstParamTy_`
|
||||
LL | struct D(unsized_const_param::GenericNotUnsizedParam<&'static [u8]>);
|
||||
| ---------------------------------------------------------- this field does not implement `ConstParamTy_`
|
||||
|
|
||||
note: the `ConstParamTy_` impl for `GenericNotUnsizedParam<&'static [u8]>` requires that `unstable feature: `unsized_const_params``
|
||||
--> $DIR/unsized_field-1.rs:21:10
|
||||
|
|
||||
LL | struct D(unsized_const_param::GenericNotUnsizedParam<&'static [u8]>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue