Auto merge of #137573 - compiler-errors:rollup-noq9yhp, r=compiler-errors
Rollup of 11 pull requests Successful merges: - #136522 (Remove `feature(dyn_compatible_for_dispatch)` from the compiler) - #137289 (Consolidate and improve error messaging for `CoerceUnsized` and `DispatchFromDyn`) - #137321 (Correct doc about `temp_dir()` behavior on Android) - #137417 (rustc_target: Add more RISC-V atomic-related features) - #137489 (remove `#[rustc_intrinsic_must_be_overridde]`) - #137530 (DWARF mixed versions with LTO on MIPS) - #137543 (std: Fix another new symlink test on Windows) - #137548 (Pass correct `TypingEnv` to `InlineAsmCtxt`) - #137550 (Don't immediately panic if dropck fails without returning errors) - #137552 (Update books) - #137556 (rename simd_shuffle_generic → simd_shuffle_const_generic) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
f5729cfed3
135 changed files with 1454 additions and 2924 deletions
|
@ -4,7 +4,6 @@ use rustc_index::interval::IntervalSet;
|
|||
use rustc_infer::infer::canonical::QueryRegionConstraints;
|
||||
use rustc_infer::infer::outlives::for_liveness;
|
||||
use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, HasLocalDecls, Local, Location};
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::traits::query::DropckOutlivesResult;
|
||||
use rustc_middle::ty::relate::Relate;
|
||||
use rustc_middle::ty::{Ty, TyCtxt, TypeVisitable, TypeVisitableExt};
|
||||
|
@ -12,7 +11,7 @@ use rustc_mir_dataflow::ResultsCursor;
|
|||
use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
|
||||
use rustc_mir_dataflow::move_paths::{HasMoveData, MoveData, MovePathIndex};
|
||||
use rustc_mir_dataflow::points::{DenseLocationMap, PointIndex};
|
||||
use rustc_span::{DUMMY_SP, Span};
|
||||
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
use rustc_trait_selection::traits::query::dropck_outlives;
|
||||
|
@ -608,7 +607,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
|
|||
Ok(TypeOpOutput { output, constraints, .. }) => {
|
||||
DropData { dropck_result: output, region_constraint_data: constraints }
|
||||
}
|
||||
Err(_) => {
|
||||
Err(ErrorGuaranteed { .. }) => {
|
||||
// We don't run dropck on HIR, and dropck looks inside fields of
|
||||
// types, so there's no guarantee that it succeeds. We also
|
||||
// can't rely on the the `ErrorGuaranteed` from `fully_perform` here
|
||||
|
@ -631,10 +630,10 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
|
|||
}
|
||||
};
|
||||
|
||||
// Could have no errors if a type lowering error, say, caused the query
|
||||
// to fail.
|
||||
if !errors.is_empty() {
|
||||
typeck.infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
} else {
|
||||
span_bug!(span, "Rerunning drop data query produced no error.");
|
||||
}
|
||||
});
|
||||
DropData { dropck_result: Default::default(), region_constraint_data: None }
|
||||
|
|
|
@ -620,70 +620,31 @@ pub union MaybeUninit<T> {
|
|||
|
||||
pub mod intrinsics {
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
pub fn abort() -> !;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn size_of<T>() -> usize {
|
||||
loop {}
|
||||
}
|
||||
pub fn size_of<T>() -> usize;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub unsafe fn size_of_val<T: ?::Sized>(_val: *const T) -> usize {
|
||||
loop {}
|
||||
}
|
||||
pub unsafe fn size_of_val<T: ?::Sized>(_val: *const T) -> usize;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn min_align_of<T>() -> usize {
|
||||
loop {}
|
||||
}
|
||||
pub fn min_align_of<T>() -> usize;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub unsafe fn min_align_of_val<T: ?::Sized>(_val: *const T) -> usize {
|
||||
loop {}
|
||||
}
|
||||
pub unsafe fn min_align_of_val<T: ?::Sized>(_val: *const T) -> usize;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub unsafe fn copy<T>(_src: *const T, _dst: *mut T, _count: usize) {
|
||||
loop {}
|
||||
}
|
||||
pub unsafe fn copy<T>(_src: *const T, _dst: *mut T, _count: usize);
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub unsafe fn transmute<T, U>(_e: T) -> U {
|
||||
loop {}
|
||||
}
|
||||
pub unsafe fn transmute<T, U>(_e: T) -> U;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub unsafe fn ctlz_nonzero<T>(_x: T) -> u32 {
|
||||
loop {}
|
||||
}
|
||||
pub unsafe fn ctlz_nonzero<T>(_x: T) -> u32;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn needs_drop<T: ?::Sized>() -> bool {
|
||||
loop {}
|
||||
}
|
||||
pub fn needs_drop<T: ?::Sized>() -> bool;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn bitreverse<T>(_x: T) -> T {
|
||||
loop {}
|
||||
}
|
||||
pub fn bitreverse<T>(_x: T) -> T;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn bswap<T>(_x: T) -> T {
|
||||
loop {}
|
||||
}
|
||||
pub fn bswap<T>(_x: T) -> T;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub unsafe fn write_bytes<T>(_dst: *mut T, _val: u8, _count: usize) {
|
||||
loop {}
|
||||
}
|
||||
pub unsafe fn write_bytes<T>(_dst: *mut T, _val: u8, _count: usize);
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub unsafe fn unreachable() -> ! {
|
||||
loop {}
|
||||
}
|
||||
pub unsafe fn unreachable() -> !;
|
||||
}
|
||||
|
||||
pub mod libc {
|
||||
|
|
|
@ -116,8 +116,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
|||
});
|
||||
}
|
||||
|
||||
// simd_shuffle_generic<T, U, const I: &[u32]>(x: T, y: T) -> U
|
||||
sym::simd_shuffle_generic => {
|
||||
// simd_shuffle_const_generic<T, U, const I: &[u32]>(x: T, y: T) -> U
|
||||
sym::simd_shuffle_const_generic => {
|
||||
let [x, y] = args else {
|
||||
bug!("wrong number of args for intrinsic {intrinsic}");
|
||||
};
|
||||
|
|
|
@ -591,70 +591,31 @@ pub union MaybeUninit<T> {
|
|||
|
||||
pub mod intrinsics {
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
pub fn abort() -> !;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn size_of<T>() -> usize {
|
||||
loop {}
|
||||
}
|
||||
pub fn size_of<T>() -> usize;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub unsafe fn size_of_val<T: ?::Sized>(_val: *const T) -> usize {
|
||||
loop {}
|
||||
}
|
||||
pub unsafe fn size_of_val<T: ?::Sized>(_val: *const T) -> usize;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn min_align_of<T>() -> usize {
|
||||
loop {}
|
||||
}
|
||||
pub fn min_align_of<T>() -> usize;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub unsafe fn min_align_of_val<T: ?::Sized>(_val: *const T) -> usize {
|
||||
loop {}
|
||||
}
|
||||
pub unsafe fn min_align_of_val<T: ?::Sized>(_val: *const T) -> usize;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub unsafe fn copy<T>(_src: *const T, _dst: *mut T, _count: usize) {
|
||||
loop {}
|
||||
}
|
||||
pub unsafe fn copy<T>(_src: *const T, _dst: *mut T, _count: usize);
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub unsafe fn transmute<T, U>(_e: T) -> U {
|
||||
loop {}
|
||||
}
|
||||
pub unsafe fn transmute<T, U>(_e: T) -> U;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub unsafe fn ctlz_nonzero<T>(_x: T) -> u32 {
|
||||
loop {}
|
||||
}
|
||||
pub unsafe fn ctlz_nonzero<T>(_x: T) -> u32;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn needs_drop<T: ?::Sized>() -> bool {
|
||||
loop {}
|
||||
}
|
||||
pub fn needs_drop<T: ?::Sized>() -> bool;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn bitreverse<T>(_x: T) -> T {
|
||||
loop {}
|
||||
}
|
||||
pub fn bitreverse<T>(_x: T) -> T;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn bswap<T>(_x: T) -> T {
|
||||
loop {}
|
||||
}
|
||||
pub fn bswap<T>(_x: T) -> T;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub unsafe fn write_bytes<T>(_dst: *mut T, _val: u8, _count: usize) {
|
||||
loop {}
|
||||
}
|
||||
pub unsafe fn write_bytes<T>(_dst: *mut T, _val: u8, _count: usize);
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub unsafe fn unreachable() -> ! {
|
||||
loop {}
|
||||
}
|
||||
pub unsafe fn unreachable() -> !;
|
||||
}
|
||||
|
||||
pub mod libc {
|
||||
|
|
|
@ -36,10 +36,7 @@ mod intrinsics {
|
|||
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
pub fn abort() -> !;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -36,10 +36,7 @@ mod intrinsics {
|
|||
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
pub fn abort() -> !;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -59,10 +59,7 @@ mod libc {
|
|||
mod intrinsics {
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
pub fn abort() -> !;
|
||||
}
|
||||
|
||||
#[lang = "panic"]
|
||||
|
|
|
@ -61,10 +61,7 @@ mod libc {
|
|||
mod intrinsics {
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
pub fn abort() -> !;
|
||||
}
|
||||
|
||||
#[lang = "panic"]
|
||||
|
|
|
@ -67,10 +67,7 @@ mod libc {
|
|||
mod intrinsics {
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
pub fn abort() -> !;
|
||||
}
|
||||
|
||||
#[lang = "panic"]
|
||||
|
|
|
@ -49,10 +49,7 @@ mod intrinsics {
|
|||
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
pub fn abort() -> !;
|
||||
}
|
||||
|
||||
mod libc {
|
||||
|
|
|
@ -1329,7 +1329,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
|||
));
|
||||
}
|
||||
|
||||
if name == sym::simd_shuffle_generic {
|
||||
if name == sym::simd_shuffle_const_generic {
|
||||
let idx = fn_args[2].expect_const().to_value().valtree.unwrap_branch();
|
||||
let n = idx.len() as u64;
|
||||
|
||||
|
|
|
@ -281,6 +281,8 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
|
|||
("riscv32" | "riscv64", "zaamo") if get_version().0 < 19 => None,
|
||||
("riscv32" | "riscv64", "zabha") if get_version().0 < 19 => None,
|
||||
("riscv32" | "riscv64", "zalrsc") if get_version().0 < 19 => None,
|
||||
("riscv32" | "riscv64", "zama16b") if get_version().0 < 19 => None,
|
||||
("riscv32" | "riscv64", "zacas") if get_version().0 < 20 => None,
|
||||
// Enable the evex512 target feature if an avx512 target feature is enabled.
|
||||
("x86", s) if s.starts_with("avx512") => {
|
||||
Some(LLVMFeature::with_dependency(s, TargetFeatureFoldStrength::EnableOnly("evex512")))
|
||||
|
|
|
@ -7,12 +7,8 @@ Erroneous code example:
|
|||
#![allow(internal_features)]
|
||||
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
fn size_of<T, U>() -> usize // error: intrinsic has wrong number
|
||||
fn size_of<T, U>() -> usize; // error: intrinsic has wrong number
|
||||
// of type parameters
|
||||
{
|
||||
loop {}
|
||||
}
|
||||
```
|
||||
|
||||
Please check that you provided the right number of type parameters
|
||||
|
@ -24,9 +20,5 @@ Example:
|
|||
#![allow(internal_features)]
|
||||
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
fn size_of<T>() -> usize // ok!
|
||||
{
|
||||
loop {}
|
||||
}
|
||||
fn size_of<T>() -> usize; // ok!
|
||||
```
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
`CoerceUnsized` was implemented on a struct which does not contain a field with
|
||||
an unsized type.
|
||||
`CoerceUnsized` or `DispatchFromDyn` was implemented on a struct which does not
|
||||
contain a field that is being unsized.
|
||||
|
||||
Example of erroneous code:
|
||||
|
||||
|
@ -11,47 +11,20 @@ struct Foo<T: ?Sized> {
|
|||
a: i32,
|
||||
}
|
||||
|
||||
// error: Struct `Foo` has no unsized fields that need `CoerceUnsized`.
|
||||
// error: Struct `Foo` has no unsized fields that need to be coerced.
|
||||
impl<T, U> CoerceUnsized<Foo<U>> for Foo<T>
|
||||
where T: CoerceUnsized<U> {}
|
||||
```
|
||||
|
||||
An [unsized type][1] is any type where the compiler does not know the length or
|
||||
alignment of at compile time. Any struct containing an unsized type is also
|
||||
unsized.
|
||||
`CoerceUnsized` is used to coerce structs that have a field that can be unsized,
|
||||
like a custom `MyBox<T>` being unsized to `MyBox<dyn Trait>`. `DispatchFromDyn`
|
||||
is used to dispatch from `MyBox<dyn Trait>` to `MyBox<Self>` in a dyn-compatible
|
||||
trait.
|
||||
|
||||
[1]: https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait
|
||||
If the struct doesn't have any fields of unsized types then there is no
|
||||
meaningful way to implement `CoerceUnsized` or `DispatchFromDyn`, since
|
||||
there is no coercion taking place.
|
||||
|
||||
`CoerceUnsized` is used to coerce one struct containing an unsized type
|
||||
into another struct containing a different unsized type. If the struct
|
||||
doesn't have any fields of unsized types then you don't need explicit
|
||||
coercion to get the types you want. To fix this you can either
|
||||
not try to implement `CoerceUnsized` or you can add a field that is
|
||||
unsized to the struct.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
#![feature(coerce_unsized)]
|
||||
use std::ops::CoerceUnsized;
|
||||
|
||||
// We don't need to impl `CoerceUnsized` here.
|
||||
struct Foo {
|
||||
a: i32,
|
||||
}
|
||||
|
||||
// We add the unsized type field to the struct.
|
||||
struct Bar<T: ?Sized> {
|
||||
a: i32,
|
||||
b: T,
|
||||
}
|
||||
|
||||
// The struct has an unsized field so we can implement
|
||||
// `CoerceUnsized` for it.
|
||||
impl<T, U> CoerceUnsized<Bar<U>> for Bar<T>
|
||||
where T: CoerceUnsized<U> {}
|
||||
```
|
||||
|
||||
Note that `CoerceUnsized` is mainly used by smart pointers like `Box`, `Rc`
|
||||
and `Arc` to be able to mark that they can coerce unsized types that they
|
||||
are pointing at.
|
||||
Note that `CoerceUnsized` and `DispatchFromDyn` is mainly used by smart pointers
|
||||
like `Box`, `Rc` and `Arc` to be able to mark that they can coerce unsized types
|
||||
that they are pointing at.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
`CoerceUnsized` was implemented on a struct which contains more than one field
|
||||
with an unsized type.
|
||||
`CoerceUnsized` or `DispatchFromDyn` was implemented on a struct which contains
|
||||
more than one field that is being unsized.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
|
@ -17,39 +17,14 @@ struct Foo<T: ?Sized, U: ?Sized> {
|
|||
impl<T, U> CoerceUnsized<Foo<U, T>> for Foo<T, U> {}
|
||||
```
|
||||
|
||||
A struct with more than one field containing an unsized type cannot implement
|
||||
`CoerceUnsized`. This only occurs when you are trying to coerce one of the
|
||||
types in your struct to another type in the struct. In this case we try to
|
||||
impl `CoerceUnsized` from `T` to `U` which are both types that the struct
|
||||
takes. An [unsized type][1] is any type that the compiler doesn't know the
|
||||
length or alignment of at compile time. Any struct containing an unsized type
|
||||
is also unsized.
|
||||
`CoerceUnsized` is used to coerce structs that have a field that can be unsized,
|
||||
like a custom `MyBox<T>` being unsized to `MyBox<dyn Trait>`. `DispatchFromDyn`
|
||||
is used to dispatch from `MyBox<dyn Trait>` to `MyBox<Self>` in a dyn-compatible
|
||||
trait.
|
||||
|
||||
`CoerceUnsized` only allows for coercion from a structure with a single
|
||||
unsized type field to another struct with a single unsized type field.
|
||||
In fact Rust only allows for a struct to have one unsized type in a struct
|
||||
and that unsized type must be the last field in the struct. So having two
|
||||
unsized types in a single struct is not allowed by the compiler. To fix this
|
||||
use only one field containing an unsized type in the struct and then use
|
||||
multiple structs to manage each unsized type field you need.
|
||||
If the struct has multiple fields that must be unsized, then the compiler has no
|
||||
way to generate a valid implementation of `CoerceUnsized` or `DispatchFromDyn`.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
#![feature(coerce_unsized)]
|
||||
use std::ops::CoerceUnsized;
|
||||
|
||||
struct Foo<T: ?Sized> {
|
||||
a: i32,
|
||||
b: T,
|
||||
}
|
||||
|
||||
impl <T, U> CoerceUnsized<Foo<U>> for Foo<T>
|
||||
where T: CoerceUnsized<U> {}
|
||||
|
||||
fn coerce_foo<T: CoerceUnsized<U>, U>(t: T) -> Foo<U> {
|
||||
Foo { a: 12i32, b: t } // we use coercion to get the `Foo<U>` type we need
|
||||
}
|
||||
```
|
||||
|
||||
[1]: https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait
|
||||
Note that `CoerceUnsized` and `DispatchFromDyn` is mainly used by smart pointers
|
||||
like `Box`, `Rc` and `Arc` to be able to mark that they can coerce unsized types
|
||||
that they are pointing at.
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
`CoerceUnsized` was implemented on something that isn't a struct.
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
`CoerceUnsized` or `DispatchFromDyn` was implemented between two types that
|
||||
are not structs.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0376
|
||||
```compile_fail,E0377
|
||||
#![feature(coerce_unsized)]
|
||||
use std::ops::CoerceUnsized;
|
||||
|
||||
|
@ -14,33 +17,4 @@ struct Foo<T: ?Sized> {
|
|||
impl<T, U> CoerceUnsized<U> for Foo<T> {}
|
||||
```
|
||||
|
||||
`CoerceUnsized` can only be implemented for a struct. Unsized types are
|
||||
already able to be coerced without an implementation of `CoerceUnsized`
|
||||
whereas a struct containing an unsized type needs to know the unsized type
|
||||
field it's containing is able to be coerced. An [unsized type][1]
|
||||
is any type that the compiler doesn't know the length or alignment of at
|
||||
compile time. Any struct containing an unsized type is also unsized.
|
||||
|
||||
[1]: https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait
|
||||
|
||||
The `CoerceUnsized` trait takes a struct type. Make sure the type you are
|
||||
providing to `CoerceUnsized` is a struct with only the last field containing an
|
||||
unsized type.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
#![feature(coerce_unsized)]
|
||||
use std::ops::CoerceUnsized;
|
||||
|
||||
struct Foo<T> {
|
||||
a: T,
|
||||
}
|
||||
|
||||
// The `Foo<U>` is a struct so `CoerceUnsized` can be implemented
|
||||
impl<T, U> CoerceUnsized<Foo<U>> for Foo<T> where T: CoerceUnsized<U> {}
|
||||
```
|
||||
|
||||
Note that in Rust, structs can only contain an unsized type if the field
|
||||
containing the unsized type is the last and only unsized type field in the
|
||||
struct.
|
||||
`CoerceUnsized` or `DispatchFromDyn` can only be implemented between structs.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
The trait `CoerceUnsized` may only be implemented for a coercion between
|
||||
structures with the same definition.
|
||||
`CoerceUnsized` or `DispatchFromDyn` may only be implemented between structs
|
||||
of the same type.
|
||||
|
||||
Example of erroneous code:
|
||||
|
||||
|
@ -20,10 +20,15 @@ pub struct Bar<T: ?Sized> {
|
|||
impl<T, U> CoerceUnsized<Bar<U>> for Foo<T> where T: CoerceUnsized<U> {}
|
||||
```
|
||||
|
||||
When attempting to implement `CoerceUnsized`, the `impl` signature must look
|
||||
like: `impl CoerceUnsized<Type<U>> for Type<T> where T: CoerceUnsized<U>`;
|
||||
the *implementer* and *`CoerceUnsized` type parameter* must be the same
|
||||
type. In this example, `Bar` and `Foo` (even though structurally identical)
|
||||
are *not* the same type and are rejected. Learn more about the `CoerceUnsized`
|
||||
trait and DST coercion in
|
||||
[the `CoerceUnsized` docs](../std/ops/trait.CoerceUnsized.html).
|
||||
`CoerceUnsized` is used to coerce structs that have a field that can be unsized,
|
||||
like a custom `MyBox<T>` being unsized to `MyBox<dyn Trait>`. `DispatchFromDyn`
|
||||
is used to dispatch from `MyBox<dyn Trait>` to `MyBox<Self>` in a dyn-compatible
|
||||
trait.
|
||||
|
||||
The compiler cannot support coercions between structs of different types, so
|
||||
a valid implementation of `CoerceUnsized` or `DispatchFromDyn` should be
|
||||
implemented between the same struct with different generic parameters.
|
||||
|
||||
Note that `CoerceUnsized` and `DispatchFromDyn` is mainly used by smart pointers
|
||||
like `Box`, `Rc` and `Arc` to be able to mark that they can coerce unsized types
|
||||
that they are pointing at.
|
||||
|
|
|
@ -1005,10 +1005,6 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
rustc_intrinsic, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, intrinsics,
|
||||
"the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items",
|
||||
),
|
||||
gated!(
|
||||
rustc_intrinsic_must_be_overridden, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, intrinsics,
|
||||
"the `#[rustc_intrinsic_must_be_overridden]` attribute is used to declare intrinsics without real bodies",
|
||||
),
|
||||
rustc_attr!(
|
||||
rustc_no_mir_inline, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes,
|
||||
"#[rustc_no_mir_inline] prevents the MIR inliner from inlining a function while not affecting codegen"
|
||||
|
|
|
@ -100,6 +100,15 @@ declare_features! (
|
|||
Some("renamed to `doc_notable_trait`")),
|
||||
/// Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238).
|
||||
(removed, dropck_parametricity, "1.38.0", Some(28498), None),
|
||||
/// Allows making `dyn Trait` well-formed even if `Trait` is not dyn compatible[^1].
|
||||
/// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and
|
||||
/// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden.
|
||||
///
|
||||
/// Renamed from `object_safe_for_dispatch`.
|
||||
///
|
||||
/// [^1]: Formerly known as "object safe".
|
||||
(removed, dyn_compatible_for_dispatch, "1.83.0", Some(43561),
|
||||
Some("removed, not used heavily and represented additional complexity in dyn compatibility")),
|
||||
/// Uses generic effect parameters for ~const bounds
|
||||
(removed, effects, "1.84.0", Some(102090),
|
||||
Some("removed, redundant with `#![feature(const_trait_impl)]`")),
|
||||
|
|
|
@ -270,14 +270,6 @@ declare_features! (
|
|||
(unstable, doc_notable_trait, "1.52.0", Some(45040)),
|
||||
/// Allows using the `may_dangle` attribute (RFC 1327).
|
||||
(unstable, dropck_eyepatch, "1.10.0", Some(34761)),
|
||||
/// Allows making `dyn Trait` well-formed even if `Trait` is not dyn compatible[^1].
|
||||
/// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and
|
||||
/// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden.
|
||||
///
|
||||
/// Renamed from `object_safe_for_dispatch`.
|
||||
///
|
||||
/// [^1]: Formerly known as "object safe".
|
||||
(unstable, dyn_compatible_for_dispatch, "1.83.0", Some(43561)),
|
||||
/// Allows using the `#[fundamental]` attribute.
|
||||
(unstable, fundamental, "1.0.0", Some(29635)),
|
||||
/// Allows using `#[link_name="llvm.*"]`.
|
||||
|
|
|
@ -85,6 +85,10 @@ hir_analysis_cmse_output_stack_spill =
|
|||
.note1 = functions with the `{$abi}` ABI must pass their result via the available return registers
|
||||
.note2 = the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||
|
||||
hir_analysis_coerce_multi = implementing `{$trait_name}` does not allow multiple fields to be coerced
|
||||
.note = the trait `{$trait_name}` may only be implemented when a single field is being coerced
|
||||
.label = these fields must be coerced for `{$trait_name}` to be valid
|
||||
|
||||
hir_analysis_coerce_pointee_no_field = `CoercePointee` can only be derived on `struct`s with at least one field
|
||||
|
||||
hir_analysis_coerce_pointee_no_user_validity_assertion = asserting applicability of `derive(CoercePointee)` on a target data is forbidden
|
||||
|
@ -95,12 +99,12 @@ hir_analysis_coerce_pointee_not_struct = `derive(CoercePointee)` is only applica
|
|||
|
||||
hir_analysis_coerce_pointee_not_transparent = `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout
|
||||
|
||||
hir_analysis_coerce_unsized_field_validity = for `{$ty}` to have a valid implementation of `{$trait_name}`, it must be possible to coerce the field of type `{$field_ty}`
|
||||
.label = `{$field_ty}` must be a pointer, reference, or smart pointer that is allowed to be unsized
|
||||
|
||||
hir_analysis_coerce_unsized_may = the trait `{$trait_name}` may only be implemented for a coercion between structures
|
||||
|
||||
hir_analysis_coerce_unsized_multi = implementing the trait `CoerceUnsized` requires multiple coercions
|
||||
.note = `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced
|
||||
.coercions_note = currently, {$number} fields need coercions: {$coercions}
|
||||
.label = requires multiple coercions
|
||||
hir_analysis_coerce_zero = implementing `{$trait_name}` requires a field to be coerced
|
||||
|
||||
hir_analysis_coercion_between_struct_same_note = expected coercion between the same definition; expected `{$source_path}`, found `{$target_path}`
|
||||
|
||||
|
@ -139,10 +143,6 @@ hir_analysis_cross_crate_traits = cross-crate traits with a default impl, like `
|
|||
hir_analysis_cross_crate_traits_defined = cross-crate traits with a default impl, like `{$traits}`, can only be implemented for a struct/enum type defined in the current crate
|
||||
.label = can't implement cross-crate trait for type in another crate
|
||||
|
||||
hir_analysis_dispatch_from_dyn_multi = implementing the `DispatchFromDyn` trait requires multiple coercions
|
||||
.note = the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced
|
||||
.coercions_note = currently, {$number} fields need coercions: {$coercions}
|
||||
|
||||
hir_analysis_dispatch_from_dyn_repr = structs implementing `DispatchFromDyn` may not have `#[repr(packed)]` or `#[repr(C)]`
|
||||
|
||||
hir_analysis_dispatch_from_dyn_zst = the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment that don't mention type/const generics, and nothing else
|
||||
|
|
|
@ -699,7 +699,7 @@ pub fn check_intrinsic_type(
|
|||
| sym::simd_reduce_min
|
||||
| sym::simd_reduce_max => (2, 0, vec![param(0)], param(1)),
|
||||
sym::simd_shuffle => (3, 0, vec![param(0), param(0), param(1)], param(2)),
|
||||
sym::simd_shuffle_generic => (2, 1, vec![param(0), param(0)], param(1)),
|
||||
sym::simd_shuffle_const_generic => (2, 1, vec![param(0), param(0)], param(1)),
|
||||
|
||||
other => {
|
||||
tcx.dcx().emit_err(UnrecognizedIntrinsicFunction { span, name: other });
|
||||
|
|
|
@ -27,20 +27,19 @@ enum NonAsmTypeReason<'tcx> {
|
|||
UnevaluatedSIMDArrayLength(DefId, ty::Const<'tcx>),
|
||||
Invalid(Ty<'tcx>),
|
||||
InvalidElement(DefId, Ty<'tcx>),
|
||||
NotSizedPtr(Ty<'tcx>),
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||
pub fn new(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: LocalDefId,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
get_operand_ty: impl Fn(&hir::Expr<'tcx>) -> Ty<'tcx> + 'a,
|
||||
) -> Self {
|
||||
InlineAsmCtxt {
|
||||
tcx,
|
||||
typing_env: ty::TypingEnv {
|
||||
typing_mode: ty::TypingMode::non_body_analysis(),
|
||||
param_env: ty::ParamEnv::empty(),
|
||||
},
|
||||
typing_env,
|
||||
target_features: tcx.asm_target_features(def_id),
|
||||
expr_ty: Box::new(get_operand_ty),
|
||||
}
|
||||
|
@ -83,7 +82,13 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
|||
ty::Float(FloatTy::F64) => Ok(InlineAsmType::F64),
|
||||
ty::Float(FloatTy::F128) => Ok(InlineAsmType::F128),
|
||||
ty::FnPtr(..) => Ok(asm_ty_isize),
|
||||
ty::RawPtr(ty, _) if self.is_thin_ptr_ty(ty) => Ok(asm_ty_isize),
|
||||
ty::RawPtr(elem_ty, _) => {
|
||||
if self.is_thin_ptr_ty(elem_ty) {
|
||||
Ok(asm_ty_isize)
|
||||
} else {
|
||||
Err(NonAsmTypeReason::NotSizedPtr(ty))
|
||||
}
|
||||
}
|
||||
ty::Adt(adt, args) if adt.repr().simd() => {
|
||||
let fields = &adt.non_enum_variant().fields;
|
||||
let field = &fields[FieldIdx::ZERO];
|
||||
|
@ -189,6 +194,16 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
|||
can be used as arguments for inline assembly",
|
||||
).emit();
|
||||
}
|
||||
NonAsmTypeReason::NotSizedPtr(ty) => {
|
||||
let msg = format!(
|
||||
"cannot use value of unsized pointer type `{ty}` for inline assembly"
|
||||
);
|
||||
self.tcx
|
||||
.dcx()
|
||||
.struct_span_err(expr.span, msg)
|
||||
.with_note("only sized pointers can be used in inline assembly")
|
||||
.emit();
|
||||
}
|
||||
NonAsmTypeReason::InvalidElement(did, ty) => {
|
||||
let msg = format!(
|
||||
"cannot use SIMD vector with element type `{ty}` for inline assembly"
|
||||
|
|
|
@ -17,7 +17,7 @@ use rustc_middle::ty::print::PrintTraitRefExt as _;
|
|||
use rustc_middle::ty::{
|
||||
self, Ty, TyCtxt, TypeVisitableExt, TypingMode, suggest_constraining_type_params,
|
||||
};
|
||||
use rustc_span::{DUMMY_SP, Span};
|
||||
use rustc_span::{DUMMY_SP, Span, sym};
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::traits::misc::{
|
||||
ConstParamTyImplementationError, CopyImplementationError, InfringingFieldsReason,
|
||||
|
@ -195,8 +195,14 @@ fn visit_implementation_of_coerce_unsized(checker: &Checker<'_>) -> Result<(), E
|
|||
// Just compute this for the side-effects, in particular reporting
|
||||
// errors; other parts of the code may demand it for the info of
|
||||
// course.
|
||||
let span = tcx.def_span(impl_did);
|
||||
tcx.at(span).ensure_ok().coerce_unsized_info(impl_did)
|
||||
tcx.ensure_ok().coerce_unsized_info(impl_did)
|
||||
}
|
||||
|
||||
fn is_from_coerce_pointee_derive(tcx: TyCtxt<'_>, span: Span) -> bool {
|
||||
span.ctxt()
|
||||
.outer_expn_data()
|
||||
.macro_def_id
|
||||
.is_some_and(|def_id| tcx.is_diagnostic_item(sym::CoercePointee, def_id))
|
||||
}
|
||||
|
||||
fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
|
||||
|
@ -206,17 +212,29 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
|||
debug!("visit_implementation_of_dispatch_from_dyn: impl_did={:?}", impl_did);
|
||||
|
||||
let span = tcx.def_span(impl_did);
|
||||
let trait_name = "DispatchFromDyn";
|
||||
|
||||
let dispatch_from_dyn_trait = tcx.require_lang_item(LangItem::DispatchFromDyn, Some(span));
|
||||
|
||||
let source = trait_ref.self_ty();
|
||||
assert!(!source.has_escaping_bound_vars());
|
||||
let target = {
|
||||
assert_eq!(trait_ref.def_id, dispatch_from_dyn_trait);
|
||||
|
||||
trait_ref.args.type_at(1)
|
||||
};
|
||||
|
||||
// Check `CoercePointee` impl is WF -- if not, then there's no reason to report
|
||||
// redundant errors for `DispatchFromDyn`. This is best effort, though.
|
||||
let mut res = Ok(());
|
||||
tcx.for_each_relevant_impl(
|
||||
tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)),
|
||||
source,
|
||||
|impl_def_id| {
|
||||
res = res.and(tcx.ensure_ok().coerce_unsized_info(impl_def_id));
|
||||
},
|
||||
);
|
||||
res?;
|
||||
|
||||
debug!("visit_implementation_of_dispatch_from_dyn: {:?} -> {:?}", source, target);
|
||||
|
||||
let param_env = tcx.param_env(impl_did);
|
||||
|
@ -242,26 +260,25 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
|||
if def_a != def_b {
|
||||
let source_path = tcx.def_path_str(def_a.did());
|
||||
let target_path = tcx.def_path_str(def_b.did());
|
||||
|
||||
return Err(tcx.dcx().emit_err(errors::DispatchFromDynCoercion {
|
||||
return Err(tcx.dcx().emit_err(errors::CoerceSameStruct {
|
||||
span,
|
||||
trait_name: "DispatchFromDyn",
|
||||
trait_name,
|
||||
note: true,
|
||||
source_path,
|
||||
target_path,
|
||||
}));
|
||||
}
|
||||
|
||||
let mut res = Ok(());
|
||||
if def_a.repr().c() || def_a.repr().packed() {
|
||||
res = Err(tcx.dcx().emit_err(errors::DispatchFromDynRepr { span }));
|
||||
return Err(tcx.dcx().emit_err(errors::DispatchFromDynRepr { span }));
|
||||
}
|
||||
|
||||
let fields = &def_a.non_enum_variant().fields;
|
||||
|
||||
let mut res = Ok(());
|
||||
let coerced_fields = fields
|
||||
.iter()
|
||||
.filter(|field| {
|
||||
.iter_enumerated()
|
||||
.filter_map(|(i, field)| {
|
||||
// Ignore PhantomData fields
|
||||
let unnormalized_ty = tcx.type_of(field.did).instantiate_identity();
|
||||
if tcx
|
||||
|
@ -272,7 +289,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
|||
.unwrap_or(unnormalized_ty)
|
||||
.is_phantom_data()
|
||||
{
|
||||
return false;
|
||||
return None;
|
||||
}
|
||||
|
||||
let ty_a = field.ty(tcx, args_a);
|
||||
|
@ -290,7 +307,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
|||
&& !ty_a.has_non_region_param()
|
||||
{
|
||||
// ignore 1-ZST fields
|
||||
return false;
|
||||
return None;
|
||||
}
|
||||
|
||||
res = Err(tcx.dcx().emit_err(errors::DispatchFromDynZST {
|
||||
|
@ -299,64 +316,57 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
|||
ty: ty_a,
|
||||
}));
|
||||
|
||||
return false;
|
||||
None
|
||||
} else {
|
||||
Some((i, ty_a, ty_b, tcx.def_span(field.did)))
|
||||
}
|
||||
|
||||
true
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
res?;
|
||||
|
||||
if coerced_fields.is_empty() {
|
||||
res = Err(tcx.dcx().emit_err(errors::DispatchFromDynSingle {
|
||||
return Err(tcx.dcx().emit_err(errors::CoerceNoField {
|
||||
span,
|
||||
trait_name: "DispatchFromDyn",
|
||||
trait_name,
|
||||
note: true,
|
||||
}));
|
||||
} else if coerced_fields.len() > 1 {
|
||||
res = Err(tcx.dcx().emit_err(errors::DispatchFromDynMulti {
|
||||
span,
|
||||
coercions_note: true,
|
||||
number: coerced_fields.len(),
|
||||
coercions: coerced_fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
format!(
|
||||
"`{}` (`{}` to `{}`)",
|
||||
field.name,
|
||||
field.ty(tcx, args_a),
|
||||
field.ty(tcx, args_b),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
}));
|
||||
} else {
|
||||
} else if let &[(_, ty_a, ty_b, field_span)] = &coerced_fields[..] {
|
||||
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
|
||||
for field in coerced_fields {
|
||||
ocx.register_obligation(Obligation::new(
|
||||
tcx,
|
||||
cause.clone(),
|
||||
param_env,
|
||||
ty::TraitRef::new(
|
||||
tcx,
|
||||
dispatch_from_dyn_trait,
|
||||
[field.ty(tcx, args_a), field.ty(tcx, args_b)],
|
||||
),
|
||||
ty::TraitRef::new(tcx, dispatch_from_dyn_trait, [ty_a, ty_b]),
|
||||
));
|
||||
}
|
||||
let errors = ocx.select_all_or_error();
|
||||
if !errors.is_empty() {
|
||||
res = Err(infcx.err_ctxt().report_fulfillment_errors(errors));
|
||||
if is_from_coerce_pointee_derive(tcx, span) {
|
||||
return Err(tcx.dcx().emit_err(errors::CoerceFieldValidity {
|
||||
span,
|
||||
trait_name,
|
||||
ty: trait_ref.self_ty(),
|
||||
field_span,
|
||||
field_ty: ty_a,
|
||||
}));
|
||||
} else {
|
||||
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, resolve all regions.
|
||||
res = res.and(ocx.resolve_regions_and_report_errors(impl_did, param_env, []));
|
||||
ocx.resolve_regions_and_report_errors(impl_did, param_env, [])?;
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
return Err(tcx.dcx().emit_err(errors::CoerceMulti {
|
||||
span,
|
||||
trait_name,
|
||||
number: coerced_fields.len(),
|
||||
fields: coerced_fields.iter().map(|(_, _, _, s)| *s).collect::<Vec<_>>().into(),
|
||||
}));
|
||||
}
|
||||
res
|
||||
}
|
||||
_ => Err(tcx
|
||||
.dcx()
|
||||
.emit_err(errors::CoerceUnsizedMay { span, trait_name: "DispatchFromDyn" })),
|
||||
_ => Err(tcx.dcx().emit_err(errors::CoerceUnsizedNonStruct { span, trait_name })),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -366,13 +376,14 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
|||
) -> Result<CoerceUnsizedInfo, ErrorGuaranteed> {
|
||||
debug!("compute_coerce_unsized_info(impl_did={:?})", impl_did);
|
||||
let span = tcx.def_span(impl_did);
|
||||
let trait_name = "CoerceUnsized";
|
||||
|
||||
let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, Some(span));
|
||||
|
||||
let unsize_trait = tcx.require_lang_item(LangItem::Unsize, Some(span));
|
||||
|
||||
let source = tcx.type_of(impl_did).instantiate_identity();
|
||||
let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().instantiate_identity();
|
||||
|
||||
assert_eq!(trait_ref.def_id, coerce_unsized_trait);
|
||||
let target = trait_ref.args.type_at(1);
|
||||
debug!("visit_implementation_of_coerce_unsized: {:?} -> {:?} (bound)", source, target);
|
||||
|
@ -399,9 +410,9 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
|||
)
|
||||
.emit();
|
||||
}
|
||||
(mt_a.ty, mt_b.ty, unsize_trait, None)
|
||||
(mt_a.ty, mt_b.ty, unsize_trait, None, span)
|
||||
};
|
||||
let (source, target, trait_def_id, kind) = match (source.kind(), target.kind()) {
|
||||
let (source, target, trait_def_id, kind, field_span) = match (source.kind(), target.kind()) {
|
||||
(&ty::Ref(r_a, ty_a, mutbl_a), &ty::Ref(r_b, ty_b, mutbl_b)) => {
|
||||
infcx.sub_regions(infer::RelateObjectBound(span), r_b, r_a);
|
||||
let mt_a = ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a };
|
||||
|
@ -422,9 +433,9 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
|||
if def_a != def_b {
|
||||
let source_path = tcx.def_path_str(def_a.did());
|
||||
let target_path = tcx.def_path_str(def_b.did());
|
||||
return Err(tcx.dcx().emit_err(errors::DispatchFromDynSame {
|
||||
return Err(tcx.dcx().emit_err(errors::CoerceSameStruct {
|
||||
span,
|
||||
trait_name: "CoerceUnsized",
|
||||
trait_name,
|
||||
note: true,
|
||||
source_path,
|
||||
target_path,
|
||||
|
@ -504,14 +515,14 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
|||
|
||||
// Collect up all fields that were significantly changed
|
||||
// i.e., those that contain T in coerce_unsized T -> U
|
||||
Some((i, a, b))
|
||||
Some((i, a, b, tcx.def_span(f.did)))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if diff_fields.is_empty() {
|
||||
return Err(tcx.dcx().emit_err(errors::CoerceUnsizedOneField {
|
||||
return Err(tcx.dcx().emit_err(errors::CoerceNoField {
|
||||
span,
|
||||
trait_name: "CoerceUnsized",
|
||||
trait_name,
|
||||
note: true,
|
||||
}));
|
||||
} else if diff_fields.len() > 1 {
|
||||
|
@ -522,27 +533,21 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
|||
tcx.def_span(impl_did)
|
||||
};
|
||||
|
||||
return Err(tcx.dcx().emit_err(errors::CoerceUnsizedMulti {
|
||||
return Err(tcx.dcx().emit_err(errors::CoerceMulti {
|
||||
span,
|
||||
coercions_note: true,
|
||||
trait_name,
|
||||
number: diff_fields.len(),
|
||||
coercions: diff_fields
|
||||
.iter()
|
||||
.map(|&(i, a, b)| format!("`{}` (`{}` to `{}`)", fields[i].name, a, b))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
fields: diff_fields.iter().map(|(_, _, _, s)| *s).collect::<Vec<_>>().into(),
|
||||
}));
|
||||
}
|
||||
|
||||
let (i, a, b) = diff_fields[0];
|
||||
let (i, a, b, field_span) = diff_fields[0];
|
||||
let kind = ty::adjustment::CustomCoerceUnsized::Struct(i);
|
||||
(a, b, coerce_unsized_trait, Some(kind))
|
||||
(a, b, coerce_unsized_trait, Some(kind), field_span)
|
||||
}
|
||||
|
||||
_ => {
|
||||
return Err(tcx
|
||||
.dcx()
|
||||
.emit_err(errors::DispatchFromDynStruct { span, trait_name: "CoerceUnsized" }));
|
||||
return Err(tcx.dcx().emit_err(errors::CoerceUnsizedNonStruct { span, trait_name }));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -557,12 +562,23 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
|||
);
|
||||
ocx.register_obligation(obligation);
|
||||
let errors = ocx.select_all_or_error();
|
||||
|
||||
if !errors.is_empty() {
|
||||
infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
if is_from_coerce_pointee_derive(tcx, span) {
|
||||
return Err(tcx.dcx().emit_err(errors::CoerceFieldValidity {
|
||||
span,
|
||||
trait_name,
|
||||
ty: trait_ref.self_ty(),
|
||||
field_span,
|
||||
field_ty: source,
|
||||
}));
|
||||
} else {
|
||||
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, resolve all regions.
|
||||
let _ = ocx.resolve_regions_and_report_errors(impl_did, param_env, []);
|
||||
ocx.resolve_regions_and_report_errors(impl_did, param_env, [])?;
|
||||
|
||||
Ok(CoerceUnsizedInfo { custom_kind: kind })
|
||||
}
|
||||
|
|
|
@ -199,11 +199,7 @@ fn check_object_overlap<'tcx>(
|
|||
|
||||
for component_def_id in component_def_ids {
|
||||
if !tcx.is_dyn_compatible(component_def_id) {
|
||||
// Without the 'dyn_compatible_for_dispatch' feature this is an error
|
||||
// which will be reported by wfcheck. Ignore it here.
|
||||
// This is tested by `coherence-impl-trait-for-trait-dyn-compatible.rs`.
|
||||
// With the feature enabled, the trait is not implemented automatically,
|
||||
// so this is valid.
|
||||
// This is a WF error tested by `coherence-impl-trait-for-trait-dyn-compatible.rs`.
|
||||
} else {
|
||||
let mut supertrait_def_ids = elaborate::supertrait_def_ids(tcx, component_def_id);
|
||||
if supertrait_def_ids
|
||||
|
|
|
@ -1164,18 +1164,6 @@ pub(crate) struct InherentTyOutside {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_coerce_unsized_may, code = E0378)]
|
||||
pub(crate) struct DispatchFromDynCoercion<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub trait_name: &'a str,
|
||||
#[note(hir_analysis_coercion_between_struct_same_note)]
|
||||
pub note: bool,
|
||||
pub source_path: String,
|
||||
pub target_path: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_dispatch_from_dyn_repr, code = E0378)]
|
||||
pub(crate) struct DispatchFromDynRepr {
|
||||
|
@ -1293,41 +1281,40 @@ pub(crate) struct DispatchFromDynZST<'a> {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_coerce_unsized_may, code = E0378)]
|
||||
pub(crate) struct DispatchFromDynSingle<'a> {
|
||||
#[diag(hir_analysis_coerce_zero, code = E0374)]
|
||||
pub(crate) struct CoerceNoField {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub trait_name: &'a str,
|
||||
pub trait_name: &'static str,
|
||||
#[note(hir_analysis_coercion_between_struct_single_note)]
|
||||
pub note: bool,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_dispatch_from_dyn_multi, code = E0378)]
|
||||
#[note]
|
||||
pub(crate) struct DispatchFromDynMulti {
|
||||
#[diag(hir_analysis_coerce_multi, code = E0375)]
|
||||
pub(crate) struct CoerceMulti {
|
||||
pub trait_name: &'static str,
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[note(hir_analysis_coercions_note)]
|
||||
pub coercions_note: bool,
|
||||
pub number: usize,
|
||||
pub coercions: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_coerce_unsized_may, code = E0376)]
|
||||
pub(crate) struct DispatchFromDynStruct<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub trait_name: &'a str,
|
||||
#[note]
|
||||
pub fields: MultiSpan,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_coerce_unsized_may, code = E0377)]
|
||||
pub(crate) struct DispatchFromDynSame<'a> {
|
||||
pub(crate) struct CoerceUnsizedNonStruct {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub trait_name: &'a str,
|
||||
pub trait_name: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_coerce_unsized_may, code = E0377)]
|
||||
pub(crate) struct CoerceSameStruct {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub trait_name: &'static str,
|
||||
#[note(hir_analysis_coercion_between_struct_same_note)]
|
||||
pub note: bool,
|
||||
pub source_path: String,
|
||||
|
@ -1335,34 +1322,15 @@ pub(crate) struct DispatchFromDynSame<'a> {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_coerce_unsized_may, code = E0374)]
|
||||
pub(crate) struct CoerceUnsizedOneField<'a> {
|
||||
#[diag(hir_analysis_coerce_unsized_field_validity)]
|
||||
pub(crate) struct CoerceFieldValidity<'tcx> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub trait_name: &'a str,
|
||||
#[note(hir_analysis_coercion_between_struct_single_note)]
|
||||
pub note: bool,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_coerce_unsized_multi, code = E0375)]
|
||||
#[note]
|
||||
pub(crate) struct CoerceUnsizedMulti {
|
||||
#[primary_span]
|
||||
pub ty: Ty<'tcx>,
|
||||
pub trait_name: &'static str,
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[note(hir_analysis_coercions_note)]
|
||||
pub coercions_note: bool,
|
||||
pub number: usize,
|
||||
pub coercions: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_coerce_unsized_may, code = E0378)]
|
||||
pub(crate) struct CoerceUnsizedMay<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub trait_name: &'a str,
|
||||
pub field_span: Span,
|
||||
pub field_ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
|
|
@ -110,7 +110,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
self.tcx.erase_regions(ty)
|
||||
}
|
||||
};
|
||||
InlineAsmCtxt::new(self.tcx, enclosing_id, expr_ty).check_asm(asm);
|
||||
InlineAsmCtxt::new(self.tcx, enclosing_id, self.typing_env(self.param_env), expr_ty)
|
||||
.check_asm(asm);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1755,8 +1755,7 @@ pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::Intrinsi
|
|||
&& (matches!(tcx.fn_sig(def_id).skip_binder().abi(), ExternAbi::RustIntrinsic)
|
||||
|| tcx.has_attr(def_id, sym::rustc_intrinsic))
|
||||
{
|
||||
let must_be_overridden = tcx.has_attr(def_id, sym::rustc_intrinsic_must_be_overridden)
|
||||
|| match tcx.hir_node_by_def_id(def_id) {
|
||||
let must_be_overridden = match tcx.hir_node_by_def_id(def_id) {
|
||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn { has_body, .. }, .. }) => {
|
||||
!has_body
|
||||
}
|
||||
|
|
|
@ -1764,7 +1764,6 @@ symbols! {
|
|||
rustc_insignificant_dtor,
|
||||
rustc_intrinsic,
|
||||
rustc_intrinsic_const_stable_indirect,
|
||||
rustc_intrinsic_must_be_overridden,
|
||||
rustc_layout,
|
||||
rustc_layout_scalar_valid_range_end,
|
||||
rustc_layout_scalar_valid_range_start,
|
||||
|
@ -1916,7 +1915,7 @@ symbols! {
|
|||
simd_shl,
|
||||
simd_shr,
|
||||
simd_shuffle,
|
||||
simd_shuffle_generic,
|
||||
simd_shuffle_const_generic,
|
||||
simd_sub,
|
||||
simd_trunc,
|
||||
simd_with_exposed_provenance,
|
||||
|
|
|
@ -497,9 +497,14 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
|
|||
("relax", Unstable(sym::riscv_target_feature), &[]),
|
||||
("unaligned-scalar-mem", Unstable(sym::riscv_target_feature), &[]),
|
||||
("v", Unstable(sym::riscv_target_feature), &[]),
|
||||
("za128rs", Unstable(sym::riscv_target_feature), &[]),
|
||||
("za64rs", Unstable(sym::riscv_target_feature), &[]),
|
||||
("zaamo", Unstable(sym::riscv_target_feature), &[]),
|
||||
("zabha", Unstable(sym::riscv_target_feature), &["zaamo"]),
|
||||
("zacas", Unstable(sym::riscv_target_feature), &["zaamo"]),
|
||||
("zalrsc", Unstable(sym::riscv_target_feature), &[]),
|
||||
("zama16b", Unstable(sym::riscv_target_feature), &[]),
|
||||
("zawrs", Unstable(sym::riscv_target_feature), &[]),
|
||||
("zba", Stable, &[]),
|
||||
("zbb", Stable, &[]),
|
||||
("zbc", Stable, &[]),
|
||||
|
|
|
@ -538,10 +538,10 @@ fn receiver_for_self_ty<'tcx>(
|
|||
/// a pointer.
|
||||
///
|
||||
/// In practice, we cannot use `dyn Trait` explicitly in the obligation because it would result in
|
||||
/// a new check that `Trait` is dyn-compatible, creating a cycle (until dyn_compatible_for_dispatch
|
||||
/// is stabilized, see tracking issue <https://github.com/rust-lang/rust/issues/43561>).
|
||||
/// Instead, we fudge a little by introducing a new type parameter `U` such that
|
||||
/// a new check that `Trait` is dyn-compatible, creating a cycle.
|
||||
/// Instead, we emulate a placeholder by introducing a new type parameter `U` such that
|
||||
/// `Self: Unsize<U>` and `U: Trait + ?Sized`, and use `U` in place of `dyn Trait`.
|
||||
///
|
||||
/// Written as a chalk-style query:
|
||||
/// ```ignore (not-rust)
|
||||
/// forall (U: Trait + ?Sized) {
|
||||
|
@ -572,8 +572,6 @@ fn receiver_is_dispatchable<'tcx>(
|
|||
|
||||
// the type `U` in the query
|
||||
// use a bogus type parameter to mimic a forall(U) query using u32::MAX for now.
|
||||
// FIXME(mikeyhew) this is a total hack. Once dyn_compatible_for_dispatch is stabilized, we can
|
||||
// replace this with `dyn Trait`
|
||||
let unsized_self_ty: Ty<'tcx> =
|
||||
Ty::new_param(tcx, u32::MAX, rustc_span::sym::RustaceansAreAwesome);
|
||||
|
||||
|
|
|
@ -859,13 +859,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
}
|
||||
|
||||
if let Some(principal) = data.principal() {
|
||||
if !self.infcx.tcx.features().dyn_compatible_for_dispatch() {
|
||||
principal.with_self_ty(self.tcx(), self_ty)
|
||||
} else if self.tcx().is_dyn_compatible(principal.def_id()) {
|
||||
principal.with_self_ty(self.tcx(), self_ty)
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Only auto trait bounds exist.
|
||||
return;
|
||||
|
|
|
@ -904,10 +904,6 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
|
|||
// FIXME(#27579) RFC also considers adding trait
|
||||
// obligations that don't refer to Self and
|
||||
// checking those
|
||||
|
||||
let defer_to_coercion = tcx.features().dyn_compatible_for_dispatch();
|
||||
|
||||
if !defer_to_coercion {
|
||||
if let Some(principal) = data.principal_def_id() {
|
||||
self.out.push(traits::Obligation::with_depth(
|
||||
tcx,
|
||||
|
@ -918,7 +914,6 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
|
|||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Inference variables are the complicated case, since we don't
|
||||
// know what type they are. We do two things:
|
||||
|
|
|
@ -238,11 +238,8 @@ pub struct Box<
|
|||
///
|
||||
/// This is the surface syntax for `box <expr>` expressions.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[unstable(feature = "liballoc_internals", issue = "none")]
|
||||
pub fn box_new<T>(_x: T) -> Box<T> {
|
||||
unreachable!()
|
||||
}
|
||||
pub fn box_new<T>(_x: T) -> Box<T>;
|
||||
|
||||
impl<T> Box<T> {
|
||||
/// Allocates memory on the heap and then places `x` into it.
|
||||
|
|
|
@ -305,25 +305,16 @@ impl<'f> Drop for VaListImpl<'f> {
|
|||
/// Destroy the arglist `ap` after initialization with `va_start` or
|
||||
/// `va_copy`.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
unsafe fn va_end(_ap: &mut VaListImpl<'_>) {
|
||||
unreachable!()
|
||||
}
|
||||
unsafe fn va_end(_ap: &mut VaListImpl<'_>);
|
||||
|
||||
/// Copies the current location of arglist `src` to the arglist `dst`.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
unsafe fn va_copy<'f>(_dest: *mut VaListImpl<'f>, _src: &VaListImpl<'f>) {
|
||||
unreachable!()
|
||||
}
|
||||
unsafe fn va_copy<'f>(_dest: *mut VaListImpl<'f>, _src: &VaListImpl<'f>);
|
||||
|
||||
/// Loads an argument of type `T` from the `va_list` `ap` and increment the
|
||||
/// argument `ap` points to.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
unsafe fn va_arg<T: sealed_trait::VaArgSafe>(_ap: &mut VaListImpl<'_>) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
unsafe fn va_arg<T: sealed_trait::VaArgSafe>(_ap: &mut VaListImpl<'_>) -> T;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -10,11 +10,8 @@
|
|||
///
|
||||
/// `idx` must be in-bounds of the vector.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_insert<T, U>(_x: T, _idx: u32, _val: U) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_insert<T, U>(_x: T, _idx: u32, _val: U) -> T;
|
||||
|
||||
/// Extracts an element from a vector.
|
||||
///
|
||||
|
@ -24,41 +21,29 @@ pub unsafe fn simd_insert<T, U>(_x: T, _idx: u32, _val: U) -> T {
|
|||
///
|
||||
/// `idx` must be in-bounds of the vector.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_extract<T, U>(_x: T, _idx: u32) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_extract<T, U>(_x: T, _idx: u32) -> U;
|
||||
|
||||
/// Adds two simd vectors elementwise.
|
||||
///
|
||||
/// `T` must be a vector of integer or floating point primitive types.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_add<T>(_x: T, _y: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_add<T>(_x: T, _y: T) -> T;
|
||||
|
||||
/// Subtracts `rhs` from `lhs` elementwise.
|
||||
///
|
||||
/// `T` must be a vector of integer or floating point primitive types.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_sub<T>(_lhs: T, _rhs: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_sub<T>(_lhs: T, _rhs: T) -> T;
|
||||
|
||||
/// Multiplies two simd vectors elementwise.
|
||||
///
|
||||
/// `T` must be a vector of integer or floating point primitive types.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_mul<T>(_x: T, _y: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_mul<T>(_x: T, _y: T) -> T;
|
||||
|
||||
/// Divides `lhs` by `rhs` elementwise.
|
||||
///
|
||||
|
@ -68,11 +53,8 @@ pub unsafe fn simd_mul<T>(_x: T, _y: T) -> T {
|
|||
/// For integers, `rhs` must not contain any zero elements.
|
||||
/// Additionally for signed integers, `<int>::MIN / -1` is undefined behavior.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_div<T>(_lhs: T, _rhs: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_div<T>(_lhs: T, _rhs: T) -> T;
|
||||
|
||||
/// Returns remainder of two vectors elementwise.
|
||||
///
|
||||
|
@ -82,11 +64,8 @@ pub unsafe fn simd_div<T>(_lhs: T, _rhs: T) -> T {
|
|||
/// For integers, `rhs` must not contain any zero elements.
|
||||
/// Additionally for signed integers, `<int>::MIN / -1` is undefined behavior.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_rem<T>(_lhs: T, _rhs: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_rem<T>(_lhs: T, _rhs: T) -> T;
|
||||
|
||||
/// Shifts vector left elementwise, with UB on overflow.
|
||||
///
|
||||
|
@ -98,11 +77,8 @@ pub unsafe fn simd_rem<T>(_lhs: T, _rhs: T) -> T {
|
|||
///
|
||||
/// Each element of `rhs` must be less than `<int>::BITS`.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_shl<T>(_lhs: T, _rhs: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_shl<T>(_lhs: T, _rhs: T) -> T;
|
||||
|
||||
/// Shifts vector right elementwise, with UB on overflow.
|
||||
///
|
||||
|
@ -114,41 +90,29 @@ pub unsafe fn simd_shl<T>(_lhs: T, _rhs: T) -> T {
|
|||
///
|
||||
/// Each element of `rhs` must be less than `<int>::BITS`.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_shr<T>(_lhs: T, _rhs: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_shr<T>(_lhs: T, _rhs: T) -> T;
|
||||
|
||||
/// "Ands" vectors elementwise.
|
||||
///
|
||||
/// `T` must be a vector of integer primitive types.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_and<T>(_x: T, _y: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_and<T>(_x: T, _y: T) -> T;
|
||||
|
||||
/// "Ors" vectors elementwise.
|
||||
///
|
||||
/// `T` must be a vector of integer primitive types.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_or<T>(_x: T, _y: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_or<T>(_x: T, _y: T) -> T;
|
||||
|
||||
/// "Exclusive ors" vectors elementwise.
|
||||
///
|
||||
/// `T` must be a vector of integer primitive types.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_xor<T>(_x: T, _y: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_xor<T>(_x: T, _y: T) -> T;
|
||||
|
||||
/// Numerically casts a vector, elementwise.
|
||||
///
|
||||
|
@ -169,11 +133,8 @@ pub unsafe fn simd_xor<T>(_x: T, _y: T) -> T {
|
|||
/// * Not be infinite
|
||||
/// * Be representable in the return type, after truncating off its fractional part
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_cast<T, U>(_x: T) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_cast<T, U>(_x: T) -> U;
|
||||
|
||||
/// Numerically casts a vector, elementwise.
|
||||
///
|
||||
|
@ -187,11 +148,8 @@ pub unsafe fn simd_cast<T, U>(_x: T) -> U {
|
|||
/// When casting integers to floats, the result is rounded.
|
||||
/// Otherwise, truncates or extends the value, maintaining the sign for signed integers.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_as<T, U>(_x: T) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_as<T, U>(_x: T) -> U;
|
||||
|
||||
/// Negates a vector elementwise.
|
||||
///
|
||||
|
@ -199,21 +157,15 @@ pub unsafe fn simd_as<T, U>(_x: T) -> U {
|
|||
///
|
||||
/// Rust panics for `-<int>::Min` due to overflow, but it is not UB with this intrinsic.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_neg<T>(_x: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_neg<T>(_x: T) -> T;
|
||||
|
||||
/// Returns absolute value of a vector, elementwise.
|
||||
///
|
||||
/// `T` must be a vector of floating-point primitive types.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_fabs<T>(_x: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_fabs<T>(_x: T) -> T;
|
||||
|
||||
/// Returns the minimum of two vectors, elementwise.
|
||||
///
|
||||
|
@ -221,11 +173,8 @@ pub unsafe fn simd_fabs<T>(_x: T) -> T {
|
|||
///
|
||||
/// Follows IEEE-754 `minNum` semantics.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_fmin<T>(_x: T, _y: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_fmin<T>(_x: T, _y: T) -> T;
|
||||
|
||||
/// Returns the maximum of two vectors, elementwise.
|
||||
///
|
||||
|
@ -233,11 +182,8 @@ pub unsafe fn simd_fmin<T>(_x: T, _y: T) -> T {
|
|||
///
|
||||
/// Follows IEEE-754 `maxNum` semantics.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_fmax<T>(_x: T, _y: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_fmax<T>(_x: T, _y: T) -> T;
|
||||
|
||||
/// Tests elementwise equality of two vectors.
|
||||
///
|
||||
|
@ -247,11 +193,8 @@ pub unsafe fn simd_fmax<T>(_x: T, _y: T) -> T {
|
|||
///
|
||||
/// Returns `0` for false and `!0` for true.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_eq<T, U>(_x: T, _y: T) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_eq<T, U>(_x: T, _y: T) -> U;
|
||||
|
||||
/// Tests elementwise inequality equality of two vectors.
|
||||
///
|
||||
|
@ -261,11 +204,8 @@ pub unsafe fn simd_eq<T, U>(_x: T, _y: T) -> U {
|
|||
///
|
||||
/// Returns `0` for false and `!0` for true.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_ne<T, U>(_x: T, _y: T) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_ne<T, U>(_x: T, _y: T) -> U;
|
||||
|
||||
/// Tests if `x` is less than `y`, elementwise.
|
||||
///
|
||||
|
@ -275,11 +215,8 @@ pub unsafe fn simd_ne<T, U>(_x: T, _y: T) -> U {
|
|||
///
|
||||
/// Returns `0` for false and `!0` for true.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_lt<T, U>(_x: T, _y: T) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_lt<T, U>(_x: T, _y: T) -> U;
|
||||
|
||||
/// Tests if `x` is less than or equal to `y`, elementwise.
|
||||
///
|
||||
|
@ -289,11 +226,8 @@ pub unsafe fn simd_lt<T, U>(_x: T, _y: T) -> U {
|
|||
///
|
||||
/// Returns `0` for false and `!0` for true.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_le<T, U>(_x: T, _y: T) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_le<T, U>(_x: T, _y: T) -> U;
|
||||
|
||||
/// Tests if `x` is greater than `y`, elementwise.
|
||||
///
|
||||
|
@ -303,11 +237,8 @@ pub unsafe fn simd_le<T, U>(_x: T, _y: T) -> U {
|
|||
///
|
||||
/// Returns `0` for false and `!0` for true.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_gt<T, U>(_x: T, _y: T) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_gt<T, U>(_x: T, _y: T) -> U;
|
||||
|
||||
/// Tests if `x` is greater than or equal to `y`, elementwise.
|
||||
///
|
||||
|
@ -317,11 +248,8 @@ pub unsafe fn simd_gt<T, U>(_x: T, _y: T) -> U {
|
|||
///
|
||||
/// Returns `0` for false and `!0` for true.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_ge<T, U>(_x: T, _y: T) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_ge<T, U>(_x: T, _y: T) -> U;
|
||||
|
||||
/// Shuffles two vectors by const indices.
|
||||
///
|
||||
|
@ -336,11 +264,8 @@ pub unsafe fn simd_ge<T, U>(_x: T, _y: T) -> U {
|
|||
/// is the concatenation of `x` and `y`. It is a compile-time error if `idx[i]` is out-of-bounds
|
||||
/// of `xy`.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_shuffle<T, U, V>(_x: T, _y: T, _idx: U) -> V {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_shuffle<T, U, V>(_x: T, _y: T, _idx: U) -> V;
|
||||
|
||||
/// Reads a vector of pointers.
|
||||
///
|
||||
|
@ -360,11 +285,8 @@ pub unsafe fn simd_shuffle<T, U, V>(_x: T, _y: T, _idx: U) -> V {
|
|||
///
|
||||
/// `mask` must only contain `0` or `!0` values.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_gather<T, U, V>(_val: T, _ptr: U, _mask: V) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_gather<T, U, V>(_val: T, _ptr: U, _mask: V) -> T;
|
||||
|
||||
/// Writes to a vector of pointers.
|
||||
///
|
||||
|
@ -387,11 +309,8 @@ pub unsafe fn simd_gather<T, U, V>(_val: T, _ptr: U, _mask: V) -> T {
|
|||
///
|
||||
/// `mask` must only contain `0` or `!0` values.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_scatter<T, U, V>(_val: T, _ptr: U, _mask: V) {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_scatter<T, U, V>(_val: T, _ptr: U, _mask: V);
|
||||
|
||||
/// Reads a vector of pointers.
|
||||
///
|
||||
|
@ -413,11 +332,8 @@ pub unsafe fn simd_scatter<T, U, V>(_val: T, _ptr: U, _mask: V) {
|
|||
///
|
||||
/// `mask` must only contain `0` or `!0` values.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_masked_load<V, U, T>(_mask: V, _ptr: U, _val: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_masked_load<V, U, T>(_mask: V, _ptr: U, _val: T) -> T;
|
||||
|
||||
/// Writes to a vector of pointers.
|
||||
///
|
||||
|
@ -438,21 +354,15 @@ pub unsafe fn simd_masked_load<V, U, T>(_mask: V, _ptr: U, _val: T) -> T {
|
|||
///
|
||||
/// `mask` must only contain `0` or `!0` values.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_masked_store<V, U, T>(_mask: V, _ptr: U, _val: T) {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_masked_store<V, U, T>(_mask: V, _ptr: U, _val: T);
|
||||
|
||||
/// Adds two simd vectors elementwise, with saturation.
|
||||
///
|
||||
/// `T` must be a vector of integer primitive types.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_saturating_add<T>(_x: T, _y: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_saturating_add<T>(_x: T, _y: T) -> T;
|
||||
|
||||
/// Subtracts two simd vectors elementwise, with saturation.
|
||||
///
|
||||
|
@ -460,11 +370,8 @@ pub unsafe fn simd_saturating_add<T>(_x: T, _y: T) -> T {
|
|||
///
|
||||
/// Subtract `rhs` from `lhs`.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_saturating_sub<T>(_lhs: T, _rhs: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_saturating_sub<T>(_lhs: T, _rhs: T) -> T;
|
||||
|
||||
/// Adds elements within a vector from left to right.
|
||||
///
|
||||
|
@ -474,11 +381,8 @@ pub unsafe fn simd_saturating_sub<T>(_lhs: T, _rhs: T) -> T {
|
|||
///
|
||||
/// Starting with the value `y`, add the elements of `x` and accumulate.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_reduce_add_ordered<T, U>(_x: T, _y: U) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_reduce_add_ordered<T, U>(_x: T, _y: U) -> U;
|
||||
|
||||
/// Adds elements within a vector in arbitrary order. May also be re-associated with
|
||||
/// unordered additions on the inputs/outputs.
|
||||
|
@ -487,11 +391,8 @@ pub unsafe fn simd_reduce_add_ordered<T, U>(_x: T, _y: U) -> U {
|
|||
///
|
||||
/// `U` must be the element type of `T`.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_reduce_add_unordered<T, U>(_x: T) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_reduce_add_unordered<T, U>(_x: T) -> U;
|
||||
|
||||
/// Multiplies elements within a vector from left to right.
|
||||
///
|
||||
|
@ -501,11 +402,8 @@ pub unsafe fn simd_reduce_add_unordered<T, U>(_x: T) -> U {
|
|||
///
|
||||
/// Starting with the value `y`, multiply the elements of `x` and accumulate.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_reduce_mul_ordered<T, U>(_x: T, _y: U) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_reduce_mul_ordered<T, U>(_x: T, _y: U) -> U;
|
||||
|
||||
/// Multiplies elements within a vector in arbitrary order. May also be re-associated with
|
||||
/// unordered additions on the inputs/outputs.
|
||||
|
@ -514,11 +412,8 @@ pub unsafe fn simd_reduce_mul_ordered<T, U>(_x: T, _y: U) -> U {
|
|||
///
|
||||
/// `U` must be the element type of `T`.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_reduce_mul_unordered<T, U>(_x: T) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_reduce_mul_unordered<T, U>(_x: T) -> U;
|
||||
|
||||
/// Checks if all mask values are true.
|
||||
///
|
||||
|
@ -527,11 +422,8 @@ pub unsafe fn simd_reduce_mul_unordered<T, U>(_x: T) -> U {
|
|||
/// # Safety
|
||||
/// `x` must contain only `0` or `!0`.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_reduce_all<T>(_x: T) -> bool {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_reduce_all<T>(_x: T) -> bool;
|
||||
|
||||
/// Checks if any mask value is true.
|
||||
///
|
||||
|
@ -540,11 +432,8 @@ pub unsafe fn simd_reduce_all<T>(_x: T) -> bool {
|
|||
/// # Safety
|
||||
/// `x` must contain only `0` or `!0`.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_reduce_any<T>(_x: T) -> bool {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_reduce_any<T>(_x: T) -> bool;
|
||||
|
||||
/// Returns the maximum element of a vector.
|
||||
///
|
||||
|
@ -554,11 +443,8 @@ pub unsafe fn simd_reduce_any<T>(_x: T) -> bool {
|
|||
///
|
||||
/// For floating-point values, uses IEEE-754 `maxNum`.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_reduce_max<T, U>(_x: T) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_reduce_max<T, U>(_x: T) -> U;
|
||||
|
||||
/// Returns the minimum element of a vector.
|
||||
///
|
||||
|
@ -568,11 +454,8 @@ pub unsafe fn simd_reduce_max<T, U>(_x: T) -> U {
|
|||
///
|
||||
/// For floating-point values, uses IEEE-754 `minNum`.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_reduce_min<T, U>(_x: T) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_reduce_min<T, U>(_x: T) -> U;
|
||||
|
||||
/// Logical "ands" all elements together.
|
||||
///
|
||||
|
@ -580,11 +463,8 @@ pub unsafe fn simd_reduce_min<T, U>(_x: T) -> U {
|
|||
///
|
||||
/// `U` must be the element type of `T`.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_reduce_and<T, U>(_x: T) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_reduce_and<T, U>(_x: T) -> U;
|
||||
|
||||
/// Logical "ors" all elements together.
|
||||
///
|
||||
|
@ -592,11 +472,8 @@ pub unsafe fn simd_reduce_and<T, U>(_x: T) -> U {
|
|||
///
|
||||
/// `U` must be the element type of `T`.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_reduce_or<T, U>(_x: T) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_reduce_or<T, U>(_x: T) -> U;
|
||||
|
||||
/// Logical "exclusive ors" all elements together.
|
||||
///
|
||||
|
@ -604,11 +481,8 @@ pub unsafe fn simd_reduce_or<T, U>(_x: T) -> U {
|
|||
///
|
||||
/// `U` must be the element type of `T`.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_reduce_xor<T, U>(_x: T) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_reduce_xor<T, U>(_x: T) -> U;
|
||||
|
||||
/// Truncates an integer vector to a bitmask.
|
||||
///
|
||||
|
@ -644,11 +518,8 @@ pub unsafe fn simd_reduce_xor<T, U>(_x: T) -> U {
|
|||
/// # Safety
|
||||
/// `x` must contain only `0` and `!0`.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_bitmask<T, U>(_x: T) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_bitmask<T, U>(_x: T) -> U;
|
||||
|
||||
/// Selects elements from a mask.
|
||||
///
|
||||
|
@ -663,11 +534,8 @@ pub unsafe fn simd_bitmask<T, U>(_x: T) -> U {
|
|||
/// # Safety
|
||||
/// `mask` must only contain `0` and `!0`.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_select<M, T>(_mask: M, _if_true: T, _if_false: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_select<M, T>(_mask: M, _if_true: T, _if_false: T) -> T;
|
||||
|
||||
/// Selects elements from a bitmask.
|
||||
///
|
||||
|
@ -684,11 +552,8 @@ pub unsafe fn simd_select<M, T>(_mask: M, _if_true: T, _if_false: T) -> T {
|
|||
/// # Safety
|
||||
/// Padding bits must be all zero.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_select_bitmask<M, T>(_m: M, _yes: T, _no: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_select_bitmask<M, T>(_m: M, _yes: T, _no: T) -> T;
|
||||
|
||||
/// Calculates the offset from a pointer vector elementwise, potentially
|
||||
/// wrapping.
|
||||
|
@ -699,21 +564,15 @@ pub unsafe fn simd_select_bitmask<M, T>(_m: M, _yes: T, _no: T) -> T {
|
|||
///
|
||||
/// Operates as if by `<ptr>::wrapping_offset`.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_arith_offset<T, U>(_ptr: T, _offset: U) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_arith_offset<T, U>(_ptr: T, _offset: U) -> T;
|
||||
|
||||
/// Casts a vector of pointers.
|
||||
///
|
||||
/// `T` and `U` must be vectors of pointers with the same number of elements.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_cast_ptr<T, U>(_ptr: T) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_cast_ptr<T, U>(_ptr: T) -> U;
|
||||
|
||||
/// Exposes a vector of pointers as a vector of addresses.
|
||||
///
|
||||
|
@ -721,11 +580,8 @@ pub unsafe fn simd_cast_ptr<T, U>(_ptr: T) -> U {
|
|||
///
|
||||
/// `U` must be a vector of `usize` with the same length as `T`.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_expose_provenance<T, U>(_ptr: T) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_expose_provenance<T, U>(_ptr: T) -> U;
|
||||
|
||||
/// Creates a vector of pointers from a vector of addresses.
|
||||
///
|
||||
|
@ -733,123 +589,87 @@ pub unsafe fn simd_expose_provenance<T, U>(_ptr: T) -> U {
|
|||
///
|
||||
/// `U` must be a vector of pointers, with the same length as `T`.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_with_exposed_provenance<T, U>(_addr: T) -> U {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_with_exposed_provenance<T, U>(_addr: T) -> U;
|
||||
|
||||
/// Swaps bytes of each element.
|
||||
///
|
||||
/// `T` must be a vector of integers.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_bswap<T>(_x: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_bswap<T>(_x: T) -> T;
|
||||
|
||||
/// Reverses bits of each element.
|
||||
///
|
||||
/// `T` must be a vector of integers.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_bitreverse<T>(_x: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_bitreverse<T>(_x: T) -> T;
|
||||
|
||||
/// Counts the leading zeros of each element.
|
||||
///
|
||||
/// `T` must be a vector of integers.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_ctlz<T>(_x: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_ctlz<T>(_x: T) -> T;
|
||||
|
||||
/// Counts the number of ones in each element.
|
||||
///
|
||||
/// `T` must be a vector of integers.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_ctpop<T>(_x: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_ctpop<T>(_x: T) -> T;
|
||||
|
||||
/// Counts the trailing zeros of each element.
|
||||
///
|
||||
/// `T` must be a vector of integers.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_cttz<T>(_x: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_cttz<T>(_x: T) -> T;
|
||||
|
||||
/// Rounds up each element to the next highest integer-valued float.
|
||||
///
|
||||
/// `T` must be a vector of floats.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_ceil<T>(_x: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_ceil<T>(_x: T) -> T;
|
||||
|
||||
/// Rounds down each element to the next lowest integer-valued float.
|
||||
///
|
||||
/// `T` must be a vector of floats.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_floor<T>(_x: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_floor<T>(_x: T) -> T;
|
||||
|
||||
/// Rounds each element to the closest integer-valued float.
|
||||
/// Ties are resolved by rounding away from 0.
|
||||
///
|
||||
/// `T` must be a vector of floats.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_round<T>(_x: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_round<T>(_x: T) -> T;
|
||||
|
||||
/// Returns the integer part of each element as an integer-valued float.
|
||||
/// In other words, non-integer values are truncated towards zero.
|
||||
///
|
||||
/// `T` must be a vector of floats.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_trunc<T>(_x: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_trunc<T>(_x: T) -> T;
|
||||
|
||||
/// Takes the square root of each element.
|
||||
///
|
||||
/// `T` must be a vector of floats.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_fsqrt<T>(_x: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_fsqrt<T>(_x: T) -> T;
|
||||
|
||||
/// Computes `(x*y) + z` for each element, but without any intermediate rounding.
|
||||
///
|
||||
/// `T` must be a vector of floats.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_fma<T>(_x: T, _y: T, _z: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_fma<T>(_x: T, _y: T, _z: T) -> T;
|
||||
|
||||
/// Computes `(x*y) + z` for each element, non-deterministically executing either
|
||||
/// a fused multiply-add or two operations with rounding of the intermediate result.
|
||||
|
@ -863,78 +683,54 @@ pub unsafe fn simd_fma<T>(_x: T, _y: T, _z: T) -> T {
|
|||
///
|
||||
/// `T` must be a vector of floats.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_relaxed_fma<T>(_x: T, _y: T, _z: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_relaxed_fma<T>(_x: T, _y: T, _z: T) -> T;
|
||||
|
||||
// Computes the sine of each element.
|
||||
///
|
||||
/// `T` must be a vector of floats.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_fsin<T>(_a: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_fsin<T>(_a: T) -> T;
|
||||
|
||||
// Computes the cosine of each element.
|
||||
///
|
||||
/// `T` must be a vector of floats.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_fcos<T>(_a: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_fcos<T>(_a: T) -> T;
|
||||
|
||||
// Computes the exponential function of each element.
|
||||
///
|
||||
/// `T` must be a vector of floats.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_fexp<T>(_a: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_fexp<T>(_a: T) -> T;
|
||||
|
||||
// Computes 2 raised to the power of each element.
|
||||
///
|
||||
/// `T` must be a vector of floats.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_fexp2<T>(_a: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_fexp2<T>(_a: T) -> T;
|
||||
|
||||
// Computes the base 10 logarithm of each element.
|
||||
///
|
||||
/// `T` must be a vector of floats.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_flog10<T>(_a: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_flog10<T>(_a: T) -> T;
|
||||
|
||||
// Computes the base 2 logarithm of each element.
|
||||
///
|
||||
/// `T` must be a vector of floats.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_flog2<T>(_a: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_flog2<T>(_a: T) -> T;
|
||||
|
||||
// Computes the natural logarithm of each element.
|
||||
///
|
||||
/// `T` must be a vector of floats.
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_flog<T>(_a: T) -> T {
|
||||
unreachable!()
|
||||
}
|
||||
pub unsafe fn simd_flog<T>(_a: T) -> T;
|
||||
|
|
|
@ -1302,6 +1302,7 @@ pub trait FnPtr: Copy + Clone {
|
|||
/// ```
|
||||
#[rustc_builtin_macro(CoercePointee, attributes(pointee))]
|
||||
#[allow_internal_unstable(dispatch_from_dyn, coerce_unsized, unsize, coerce_pointee_validated)]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "CoercePointee")]
|
||||
#[unstable(feature = "derive_coerce_pointee", issue = "123430")]
|
||||
pub macro CoercePointee($item:item) {
|
||||
/* compiler built-in */
|
||||
|
|
|
@ -668,7 +668,9 @@ pub fn home_dir() -> Option<PathBuf> {
|
|||
/// On Unix, returns the value of the `TMPDIR` environment variable if it is
|
||||
/// set, otherwise the value is OS-specific:
|
||||
/// - On Android, there is no global temporary folder (it is usually allocated
|
||||
/// per-app), it returns `/data/local/tmp`.
|
||||
/// per-app), it will return the application's cache dir if the program runs
|
||||
/// in application's namespace and system version is Android 13 (or above), or
|
||||
/// `/data/local/tmp` otherwise.
|
||||
/// - On Darwin-based OSes (macOS, iOS, etc) it returns the directory provided
|
||||
/// by `confstr(_CS_DARWIN_USER_TEMP_DIR, ...)`, as recommended by [Apple's
|
||||
/// security guidelines][appledoc].
|
||||
|
|
|
@ -1962,6 +1962,10 @@ fn test_rename_directory_to_non_empty_directory() {
|
|||
#[test]
|
||||
fn test_rename_symlink() {
|
||||
let tmpdir = tmpdir();
|
||||
if !got_symlink_permission(&tmpdir) {
|
||||
return;
|
||||
};
|
||||
|
||||
let original = tmpdir.join("original");
|
||||
let dest = tmpdir.join("dest");
|
||||
let not_exist = Path::new("does not exist");
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit d4d2c18cbd20876b2130a546e790446a8444cb32
|
||||
Subproject commit 4a01a9182496f807aaa5f72d93a25ce18bcbe105
|
|
@ -1 +1 @@
|
|||
Subproject commit 8dbdda7cae4fa030f09f8f5b63994d4d1dde74b9
|
||||
Subproject commit daa4b763cd848f986813b5cf8069e1649f7147af
|
|
@ -1 +1 @@
|
|||
Subproject commit 336f75835a6c0514852cc65aba9a698b699b13c8
|
||||
Subproject commit 8f5c7322b65d079aa5b242eb10d89a98e12471e1
|
|
@ -1 +1 @@
|
|||
Subproject commit 6195dbd70fc6f0980c314b4d23875ac570d8253a
|
||||
Subproject commit 615b4cec60c269cfc105d511c93287620032d5b0
|
|
@ -62,13 +62,19 @@ These must be implemented by all backends.
|
|||
|
||||
### `#[rustc_intrinsic]` declarations
|
||||
|
||||
These are written like intrinsics with fallback bodies, but the body is irrelevant.
|
||||
Use `loop {}` for the body or call the intrinsic recursively and add
|
||||
`#[rustc_intrinsic_must_be_overridden]` to the function to ensure that backends don't
|
||||
invoke the body.
|
||||
These are written without a body:
|
||||
```rust
|
||||
#![feature(intrinsics)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
#[rustc_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
```
|
||||
|
||||
### Legacy extern ABI based intrinsics
|
||||
|
||||
*This style is deprecated, always prefer the above form.*
|
||||
|
||||
These are imported as if they were FFI functions, with the special
|
||||
`rust-intrinsic` ABI. For example, if one was in a freestanding
|
||||
context, but wished to be able to `transmute` between types, and
|
||||
|
|
|
@ -633,7 +633,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.write_immediate(*val, &dest)?;
|
||||
}
|
||||
}
|
||||
"shuffle_generic" => {
|
||||
"shuffle_const_generic" => {
|
||||
let [left, right] = check_arg_count(args)?;
|
||||
let (left, left_len) = this.project_to_simd(left)?;
|
||||
let (right, right_len) = this.project_to_simd(right)?;
|
||||
|
@ -657,7 +657,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.read_immediate(&this.project_index(&right, right_idx)?)?
|
||||
} else {
|
||||
throw_ub_format!(
|
||||
"`simd_shuffle_generic` index {src_index} is out-of-bounds for 2 vectors with length {dest_len}"
|
||||
"`simd_shuffle_const_generic` index {src_index} is out-of-bounds for 2 vectors with length {dest_len}"
|
||||
);
|
||||
};
|
||||
this.write_immediate(*val, &dest)?;
|
||||
|
|
|
@ -16,7 +16,7 @@ use std::simd::prelude::*;
|
|||
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub unsafe fn simd_shuffle_generic<T, U, const IDX: &'static [u32]>(_x: T, _y: T) -> U;
|
||||
pub unsafe fn simd_shuffle_const_generic<T, U, const IDX: &'static [u32]>(_x: T, _y: T) -> U;
|
||||
|
||||
fn simd_ops_f32() {
|
||||
let a = f32x4::splat(10.0);
|
||||
|
@ -619,13 +619,13 @@ fn simd_intrinsics() {
|
|||
simd_select(i8x4::from_array([0, -1, -1, 0]), b, a),
|
||||
i32x4::from_array([10, 2, 10, 10])
|
||||
);
|
||||
assert_eq!(simd_shuffle_generic::<_, i32x4, { &[3, 1, 0, 2] }>(a, b), a,);
|
||||
assert_eq!(simd_shuffle_const_generic::<_, i32x4, { &[3, 1, 0, 2] }>(a, b), a,);
|
||||
assert_eq!(
|
||||
simd_shuffle::<_, _, i32x4>(a, b, const { u32x4::from_array([3u32, 1, 0, 2]) }),
|
||||
a,
|
||||
);
|
||||
assert_eq!(
|
||||
simd_shuffle_generic::<_, i32x4, { &[7, 5, 4, 6] }>(a, b),
|
||||
simd_shuffle_const_generic::<_, i32x4, { &[7, 5, 4, 6] }>(a, b),
|
||||
i32x4::from_array([4, 2, 1, 10]),
|
||||
);
|
||||
assert_eq!(
|
||||
|
|
|
@ -3827,7 +3827,6 @@ ui/suggestions/issue-103646.rs
|
|||
ui/suggestions/issue-104086-suggest-let.rs
|
||||
ui/suggestions/issue-104287.rs
|
||||
ui/suggestions/issue-104327.rs
|
||||
ui/suggestions/issue-104328.rs
|
||||
ui/suggestions/issue-104961.rs
|
||||
ui/suggestions/issue-105226.rs
|
||||
ui/suggestions/issue-105494.rs
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// This test ensures that if LTO occurs between crates with different DWARF versions, we
|
||||
// will choose the highest DWARF version for the final binary. This matches Clang's behavior.
|
||||
// Note: `.2byte` directive is used on MIPS.
|
||||
|
||||
//@ only-linux
|
||||
//@ aux-build:dwarf-mixed-versions-lto-aux.rs
|
||||
|
@ -14,6 +15,6 @@ fn main() {
|
|||
}
|
||||
|
||||
// CHECK: .section .debug_info
|
||||
// CHECK-NOT: {{\.(short|hword)}} 2
|
||||
// CHECK-NOT: {{\.(short|hword)}} 4
|
||||
// CHECK: {{\.(short|hword)}} 5
|
||||
// CHECK-NOT: {{\.(short|hword|2byte)}} 2
|
||||
// CHECK-NOT: {{\.(short|hword|2byte)}} 4
|
||||
// CHECK: {{\.(short|hword|2byte)}} 5
|
||||
|
|
|
@ -51,10 +51,7 @@ enum Ordering {
|
|||
}
|
||||
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
fn three_way_compare<T: Copy>(lhs: T, rhs: T) -> Ordering {
|
||||
loop {}
|
||||
}
|
||||
fn three_way_compare<T: Copy>(lhs: T, rhs: T) -> Ordering;
|
||||
|
||||
// ^^^^^ core
|
||||
|
||||
|
|
|
@ -9,19 +9,13 @@
|
|||
#[stable(since="1.0.0", feature="rust1")]
|
||||
#[rustc_const_stable(feature = "const_transmute", since = "1.56.0")]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub const unsafe fn transmute<T, U>(_: T) -> U {
|
||||
loop {}
|
||||
}
|
||||
pub const unsafe fn transmute<T, U>(_: T) -> U;
|
||||
|
||||
//@ has 'foo/fn.unreachable.html'
|
||||
//@ has - '//pre[@class="rust item-decl"]' 'pub unsafe fn unreachable() -> !'
|
||||
#[stable(since="1.0.0", feature="rust1")]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub unsafe fn unreachable() -> ! {
|
||||
loop {}
|
||||
}
|
||||
pub unsafe fn unreachable() -> !;
|
||||
|
||||
extern "C" {
|
||||
//@ has 'foo/fn.needs_drop.html'
|
||||
|
|
|
@ -11,14 +11,8 @@ trait Sized {}
|
|||
//@ has 'foo/fn.abort.html'
|
||||
//@ has - '//pre[@class="rust item-decl"]' 'pub fn abort() -> !'
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
pub fn abort() -> !;
|
||||
//@ has 'foo/fn.unreachable.html'
|
||||
//@ has - '//pre[@class="rust item-decl"]' 'pub unsafe fn unreachable() -> !'
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub unsafe fn unreachable() -> ! {
|
||||
loop {}
|
||||
}
|
||||
pub unsafe fn unreachable() -> !;
|
||||
|
|
|
@ -51,13 +51,11 @@ fn test_intrinsics() -> ControlFlow<()> {
|
|||
|
||||
/// This check is unfortunately tight to the implementation of intrinsics.
|
||||
///
|
||||
/// We want to ensure that StableMIR can handle intrinsics with and without fallback body.
|
||||
/// We want to ensure that StableMIR can handle intrinsics with and without fallback body:
|
||||
/// for intrinsics without a body, obviously we cannot expose anything.
|
||||
///
|
||||
/// If by any chance this test breaks because you changed how an intrinsic is implemented, please
|
||||
/// update the test to invoke a different intrinsic.
|
||||
///
|
||||
/// In StableMIR, we only expose intrinsic body if they are not marked with
|
||||
/// `rustc_intrinsic_must_be_overridden`.
|
||||
fn check_instance(instance: &Instance) {
|
||||
assert_eq!(instance.kind, InstanceKind::Intrinsic);
|
||||
let name = instance.intrinsic_name().unwrap();
|
||||
|
|
19
tests/ui/asm/conditionally-sized-ptr-fail.rs
Normal file
19
tests/ui/asm/conditionally-sized-ptr-fail.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
//@ needs-asm-support
|
||||
|
||||
use std::arch::asm;
|
||||
|
||||
fn _f<T: ?Sized>(p: *mut T) {
|
||||
unsafe {
|
||||
asm!("/* {} */", in(reg) p);
|
||||
//~^ ERROR cannot use value of unsized pointer type `*mut T` for inline assembly
|
||||
}
|
||||
}
|
||||
|
||||
fn _g(p: *mut [u8]) {
|
||||
unsafe {
|
||||
asm!("/* {} */", in(reg) p);
|
||||
//~^ ERROR cannot use value of unsized pointer type `*mut [u8]` for inline assembly
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
18
tests/ui/asm/conditionally-sized-ptr-fail.stderr
Normal file
18
tests/ui/asm/conditionally-sized-ptr-fail.stderr
Normal file
|
@ -0,0 +1,18 @@
|
|||
error: cannot use value of unsized pointer type `*mut T` for inline assembly
|
||||
--> $DIR/conditionally-sized-ptr-fail.rs:7:34
|
||||
|
|
||||
LL | asm!("/* {} */", in(reg) p);
|
||||
| ^
|
||||
|
|
||||
= note: only sized pointers can be used in inline assembly
|
||||
|
||||
error: cannot use value of unsized pointer type `*mut [u8]` for inline assembly
|
||||
--> $DIR/conditionally-sized-ptr-fail.rs:14:34
|
||||
|
|
||||
LL | asm!("/* {} */", in(reg) p);
|
||||
| ^
|
||||
|
|
||||
= note: only sized pointers can be used in inline assembly
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
12
tests/ui/asm/conditionally-sized-ptr.rs
Normal file
12
tests/ui/asm/conditionally-sized-ptr.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
//@ check-pass
|
||||
//@ needs-asm-support
|
||||
|
||||
use std::arch::asm;
|
||||
|
||||
fn _f<T>(p: *mut T) {
|
||||
unsafe {
|
||||
asm!("/* {} */", in(reg) p);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -290,9 +290,14 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE");
|
|||
`xsavec`
|
||||
`xsaveopt`
|
||||
`xsaves`
|
||||
`za128rs`
|
||||
`za64rs`
|
||||
`zaamo`
|
||||
`zabha`
|
||||
`zacas`
|
||||
`zalrsc`
|
||||
`zama16b`
|
||||
`zawrs`
|
||||
`zba`
|
||||
`zbb`
|
||||
`zbc`
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
error[E0375]: implementing the trait `CoerceUnsized` requires multiple coercions
|
||||
error[E0375]: implementing `CoerceUnsized` does not allow multiple fields to be coerced
|
||||
--> $DIR/issue-26905.rs:16:40
|
||||
|
|
||||
LL | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<MyRc<U>> for MyRc<T>{ }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ requires multiple coercions
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced
|
||||
= note: currently, 2 fields need coercions: `_ptr` (`*const T` to `*const U`), `_boo` (`NotPhantomData<T>` to `NotPhantomData<U>`)
|
||||
note: the trait `CoerceUnsized` may only be implemented when a single field is being coerced
|
||||
--> $DIR/issue-26905.rs:12:5
|
||||
|
|
||||
LL | _ptr: *const T,
|
||||
| ^^^^^^^^^^^^^^
|
||||
LL | _boo: NotPhantomData<T>,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
// Check that unsafe trait object do not implement themselves
|
||||
// automatically
|
||||
|
||||
#![feature(dyn_compatible_for_dispatch)]
|
||||
|
||||
trait Trait: Sized {
|
||||
fn call(&self);
|
||||
}
|
||||
|
||||
fn takes_t<S: Trait>(s: S) {
|
||||
s.call();
|
||||
}
|
||||
|
||||
fn takes_t_obj(t: &dyn Trait) {
|
||||
takes_t(t); //~ ERROR E0277
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -1,22 +0,0 @@
|
|||
error[E0277]: the trait bound `&dyn Trait: Trait` is not satisfied
|
||||
--> $DIR/coherence-unsafe-trait-object-impl.rs:15:13
|
||||
|
|
||||
LL | takes_t(t);
|
||||
| ------- ^ the trait `Trait` is not implemented for `&dyn Trait`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
help: this trait has no implementations, consider adding one
|
||||
--> $DIR/coherence-unsafe-trait-object-impl.rs:6:1
|
||||
|
|
||||
LL | trait Trait: Sized {
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
note: required by a bound in `takes_t`
|
||||
--> $DIR/coherence-unsafe-trait-object-impl.rs:10:15
|
||||
|
|
||||
LL | fn takes_t<S: Trait>(s: S) {
|
||||
| ^^^^^ required by this bound in `takes_t`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
|
@ -1,10 +1,7 @@
|
|||
//@ check-pass
|
||||
|
||||
// Regression test for #128176. Previously we would call `type_of` on the `1` anon const
|
||||
// before the anon const had been lowered and had the `type_of` fed with a result.
|
||||
|
||||
#![feature(generic_const_exprs)]
|
||||
#![feature(dyn_compatible_for_dispatch)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait X {
|
||||
|
@ -13,6 +10,7 @@ trait X {
|
|||
|
||||
const _: () = {
|
||||
fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {}
|
||||
//~^ ERROR the trait `X` is not dyn compatible
|
||||
};
|
||||
|
||||
fn main() {}
|
||||
|
|
19
tests/ui/const-generics/issues/cg-in-dyn-issue-128176.stderr
Normal file
19
tests/ui/const-generics/issues/cg-in-dyn-issue-128176.stderr
Normal file
|
@ -0,0 +1,19 @@
|
|||
error[E0038]: the trait `X` is not dyn compatible
|
||||
--> $DIR/cg-in-dyn-issue-128176.rs:12:24
|
||||
|
|
||||
LL | fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^ `X` 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>
|
||||
--> $DIR/cg-in-dyn-issue-128176.rs:8:10
|
||||
|
|
||||
LL | trait X {
|
||||
| - this trait is not dyn compatible...
|
||||
LL | type Y<const N: i16>;
|
||||
| ^ ...because it contains the generic associated type `Y`
|
||||
= help: consider moving `Y` to another trait
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
|
@ -142,4 +142,27 @@ struct TryToWipeRepr<'a, #[pointee] T: ?Sized> {
|
|||
ptr: &'a T,
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(CoercePointee)]
|
||||
//~^ ERROR for `RcWithId<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `Rc<(i32, Box<T>)>`
|
||||
struct RcWithId<T: ?Sized> {
|
||||
inner: std::rc::Rc<(i32, Box<T>)>,
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(CoercePointee)]
|
||||
//~^ ERROR implementing `CoerceUnsized` does not allow multiple fields to be coerced
|
||||
struct MoreThanOneField<T: ?Sized> {
|
||||
//~^ ERROR transparent struct needs at most one field with non-trivial size or alignment, but has 2
|
||||
inner1: Box<T>,
|
||||
inner2: Box<T>,
|
||||
}
|
||||
|
||||
struct NotCoercePointeeData<T: ?Sized>(T);
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(CoercePointee)]
|
||||
//~^ ERROR for `UsingNonCoercePointeeData<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `NotCoercePointeeData<T>`
|
||||
struct UsingNonCoercePointeeData<T: ?Sized>(NotCoercePointeeData<T>);
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -118,7 +118,55 @@ error[E0802]: `derive(CoercePointee)` is only applicable to `struct` with `repr(
|
|||
LL | struct TryToWipeRepr<'a, #[pointee] T: ?Sized> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 17 previous errors
|
||||
error: for `RcWithId<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `Rc<(i32, Box<T>)>`
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:146:10
|
||||
|
|
||||
LL | #[derive(CoercePointee)]
|
||||
| ^^^^^^^^^^^^^
|
||||
...
|
||||
LL | inner: std::rc::Rc<(i32, Box<T>)>,
|
||||
| --------------------------------- `Rc<(i32, Box<T>)>` must be a pointer, reference, or smart pointer that is allowed to be unsized
|
||||
|
|
||||
= note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
Some errors have detailed explanations: E0392, E0802.
|
||||
For more information about an error, try `rustc --explain E0392`.
|
||||
error[E0375]: implementing `CoerceUnsized` does not allow multiple fields to be coerced
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:153:10
|
||||
|
|
||||
LL | #[derive(CoercePointee)]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
note: the trait `CoerceUnsized` may only be implemented when a single field is being coerced
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:157:5
|
||||
|
|
||||
LL | inner1: Box<T>,
|
||||
| ^^^^^^^^^^^^^^
|
||||
LL | inner2: Box<T>,
|
||||
| ^^^^^^^^^^^^^^
|
||||
= note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: for `UsingNonCoercePointeeData<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `NotCoercePointeeData<T>`
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:164:10
|
||||
|
|
||||
LL | #[derive(CoercePointee)]
|
||||
| ^^^^^^^^^^^^^
|
||||
LL |
|
||||
LL | struct UsingNonCoercePointeeData<T: ?Sized>(NotCoercePointeeData<T>);
|
||||
| ----------------------- `NotCoercePointeeData<T>` must be a pointer, reference, or smart pointer that is allowed to be unsized
|
||||
|
|
||||
= note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0690]: transparent struct needs at most one field with non-trivial size or alignment, but has 2
|
||||
--> $DIR/deriving-coerce-pointee-neg.rs:155:1
|
||||
|
|
||||
LL | struct MoreThanOneField<T: ?Sized> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs at most one field with non-trivial size or alignment, but has 2
|
||||
LL |
|
||||
LL | inner1: Box<T>,
|
||||
| -------------- this field has non-zero size or requires alignment
|
||||
LL | inner2: Box<T>,
|
||||
| -------------- this field has non-zero size or requires alignment
|
||||
|
||||
error: aborting due to 21 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0375, E0392, E0690, E0802.
|
||||
For more information about an error, try `rustc --explain E0375`.
|
||||
|
|
14
tests/ui/dropck/dropck-after-failed-type-lowering.rs
Normal file
14
tests/ui/dropck/dropck-after-failed-type-lowering.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Regression test for #137329
|
||||
|
||||
trait B {
|
||||
type C<'a>;
|
||||
fn d<E>() -> F<E> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
struct F<G> {
|
||||
h: Option<<G as B>::C>,
|
||||
//~^ ERROR missing generics for associated type `B::C`
|
||||
}
|
||||
|
||||
fn main() {}
|
19
tests/ui/dropck/dropck-after-failed-type-lowering.stderr
Normal file
19
tests/ui/dropck/dropck-after-failed-type-lowering.stderr
Normal file
|
@ -0,0 +1,19 @@
|
|||
error[E0107]: missing generics for associated type `B::C`
|
||||
--> $DIR/dropck-after-failed-type-lowering.rs:10:25
|
||||
|
|
||||
LL | h: Option<<G as B>::C>,
|
||||
| ^ expected 1 lifetime argument
|
||||
|
|
||||
note: associated type defined here, with 1 lifetime parameter: `'a`
|
||||
--> $DIR/dropck-after-failed-type-lowering.rs:4:10
|
||||
|
|
||||
LL | type C<'a>;
|
||||
| ^ --
|
||||
help: add missing lifetime argument
|
||||
|
|
||||
LL | h: Option<<G as B>::C<'a>>,
|
||||
| ++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0107`.
|
|
@ -1,20 +0,0 @@
|
|||
error[E0038]: the trait `Bar` is not dyn compatible
|
||||
--> $DIR/associated-consts.rs:14:5
|
||||
|
|
||||
LL | t
|
||||
| ^ `Bar` 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>
|
||||
--> $DIR/associated-consts.rs:9:11
|
||||
|
|
||||
LL | trait Bar {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | const X: usize;
|
||||
| ^ ...because it contains this associated `const`
|
||||
= help: consider moving `X` to another trait
|
||||
= note: required for the cast from `&T` to `&dyn Bar`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
|
@ -1,16 +1,12 @@
|
|||
// Check that we correctly prevent users from making trait objects
|
||||
// from traits with associated consts.
|
||||
//
|
||||
//@ revisions: curr dyn_compatible_for_dispatch
|
||||
|
||||
#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))]
|
||||
|
||||
trait Bar {
|
||||
const X: usize;
|
||||
}
|
||||
|
||||
fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
|
||||
//[curr]~^ ERROR E0038
|
||||
//~^ ERROR E0038
|
||||
t
|
||||
//~^ ERROR E0038
|
||||
}
|
||||
|
|
|
@ -1,35 +1,34 @@
|
|||
error[E0038]: the trait `Bar` is not dyn compatible
|
||||
--> $DIR/generics.rs:20:5
|
||||
--> $DIR/associated-consts.rs:8:31
|
||||
|
|
||||
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
|
||||
| ^^^^^^^ `Bar` 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>
|
||||
--> $DIR/associated-consts.rs:5:11
|
||||
|
|
||||
LL | trait Bar {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | const X: usize;
|
||||
| ^ ...because it contains this associated `const`
|
||||
= help: consider moving `X` to another trait
|
||||
|
||||
error[E0038]: the trait `Bar` is not dyn compatible
|
||||
--> $DIR/associated-consts.rs:10:5
|
||||
|
|
||||
LL | t
|
||||
| ^ `Bar` 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>
|
||||
--> $DIR/generics.rs:10:8
|
||||
--> $DIR/associated-consts.rs:5:11
|
||||
|
|
||||
LL | trait Bar {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn bar<T>(&self, t: T);
|
||||
| ^^^ ...because method `bar` has generic type parameters
|
||||
= help: consider moving `bar` to another trait
|
||||
= note: required for the cast from `&T` to `&dyn Bar`
|
||||
|
||||
error[E0038]: the trait `Bar` is not dyn compatible
|
||||
--> $DIR/generics.rs:27:5
|
||||
|
|
||||
LL | t as &dyn Bar
|
||||
| ^ `Bar` 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>
|
||||
--> $DIR/generics.rs:10:8
|
||||
|
|
||||
LL | trait Bar {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn bar<T>(&self, t: T);
|
||||
| ^^^ ...because method `bar` has generic type parameters
|
||||
= help: consider moving `bar` to another trait
|
||||
LL | const X: usize;
|
||||
| ^ ...because it contains this associated `const`
|
||||
= help: consider moving `X` to another trait
|
||||
= note: required for the cast from `&T` to `&dyn Bar`
|
||||
|
||||
error: aborting due to 2 previous errors
|
|
@ -1,9 +1,6 @@
|
|||
// Check that we correctly prevent users from making trait objects
|
||||
// from traits with generic methods, unless `where Self : Sized` is
|
||||
// present.
|
||||
//@ revisions: curr dyn_compatible_for_dispatch
|
||||
|
||||
#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))]
|
||||
|
||||
|
||||
trait Bar {
|
||||
|
@ -16,18 +13,16 @@ trait Quux {
|
|||
}
|
||||
|
||||
fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
|
||||
//[curr]~^ ERROR E0038
|
||||
//~^ ERROR E0038
|
||||
t
|
||||
//[dyn_compatible_for_dispatch]~^ ERROR E0038
|
||||
//[curr]~^^ ERROR E0038
|
||||
//~^ ERROR E0038
|
||||
}
|
||||
|
||||
fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar {
|
||||
//[curr]~^ ERROR E0038
|
||||
//~^ ERROR E0038
|
||||
t as &dyn Bar
|
||||
//[dyn_compatible_for_dispatch]~^ ERROR E0038
|
||||
//[curr]~^^ ERROR E0038
|
||||
//[curr]~| ERROR E0038
|
||||
//~^ ERROR E0038
|
||||
//~| ERROR E0038
|
||||
}
|
||||
|
||||
fn make_quux<T:Quux>(t: &T) -> &dyn Quux {
|
||||
|
|
85
tests/ui/dyn-compatibility/generics.stderr
Normal file
85
tests/ui/dyn-compatibility/generics.stderr
Normal file
|
@ -0,0 +1,85 @@
|
|||
error[E0038]: the trait `Bar` is not dyn compatible
|
||||
--> $DIR/generics.rs:15:31
|
||||
|
|
||||
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
|
||||
| ^^^^^^^ `Bar` 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>
|
||||
--> $DIR/generics.rs:7:8
|
||||
|
|
||||
LL | trait Bar {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn bar<T>(&self, t: T);
|
||||
| ^^^ ...because method `bar` has generic type parameters
|
||||
= help: consider moving `bar` to another trait
|
||||
|
||||
error[E0038]: the trait `Bar` is not dyn compatible
|
||||
--> $DIR/generics.rs:21:40
|
||||
|
|
||||
LL | fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar {
|
||||
| ^^^^^^^ `Bar` 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>
|
||||
--> $DIR/generics.rs:7:8
|
||||
|
|
||||
LL | trait Bar {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn bar<T>(&self, t: T);
|
||||
| ^^^ ...because method `bar` has generic type parameters
|
||||
= help: consider moving `bar` to another trait
|
||||
|
||||
error[E0038]: the trait `Bar` is not dyn compatible
|
||||
--> $DIR/generics.rs:17:5
|
||||
|
|
||||
LL | t
|
||||
| ^ `Bar` 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>
|
||||
--> $DIR/generics.rs:7:8
|
||||
|
|
||||
LL | trait Bar {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn bar<T>(&self, t: T);
|
||||
| ^^^ ...because method `bar` has generic type parameters
|
||||
= help: consider moving `bar` to another trait
|
||||
= note: required for the cast from `&T` to `&dyn Bar`
|
||||
|
||||
error[E0038]: the trait `Bar` is not dyn compatible
|
||||
--> $DIR/generics.rs:23:10
|
||||
|
|
||||
LL | t as &dyn Bar
|
||||
| ^^^^^^^^ `Bar` 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>
|
||||
--> $DIR/generics.rs:7:8
|
||||
|
|
||||
LL | trait Bar {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn bar<T>(&self, t: T);
|
||||
| ^^^ ...because method `bar` has generic type parameters
|
||||
= help: consider moving `bar` to another trait
|
||||
|
||||
error[E0038]: the trait `Bar` is not dyn compatible
|
||||
--> $DIR/generics.rs:23:5
|
||||
|
|
||||
LL | t as &dyn Bar
|
||||
| ^ `Bar` 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>
|
||||
--> $DIR/generics.rs:7:8
|
||||
|
|
||||
LL | trait Bar {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn bar<T>(&self, t: T);
|
||||
| ^^^ ...because method `bar` has generic type parameters
|
||||
= help: consider moving `bar` to another trait
|
||||
= note: required for the cast from `&T` to `&dyn Bar`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
|
@ -1,12 +1,12 @@
|
|||
error[E0038]: the trait `Bar` is not dyn compatible
|
||||
--> $DIR/mentions-Self.rs:22:31
|
||||
--> $DIR/mentions-Self.rs:18:31
|
||||
|
|
||||
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
|
||||
| ^^^^^^^ `Bar` 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>
|
||||
--> $DIR/mentions-Self.rs:11:22
|
||||
--> $DIR/mentions-Self.rs:7:22
|
||||
|
|
||||
LL | trait Bar {
|
||||
| --- this trait is not dyn compatible...
|
||||
|
@ -15,14 +15,14 @@ LL | fn bar(&self, x: &Self);
|
|||
= help: consider moving `bar` to another trait
|
||||
|
||||
error[E0038]: the trait `Baz` is not dyn compatible
|
||||
--> $DIR/mentions-Self.rs:28:31
|
||||
--> $DIR/mentions-Self.rs:24:31
|
||||
|
|
||||
LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
|
||||
| ^^^^^^^ `Baz` 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>
|
||||
--> $DIR/mentions-Self.rs:15:22
|
||||
--> $DIR/mentions-Self.rs:11:22
|
||||
|
|
||||
LL | trait Baz {
|
||||
| --- this trait is not dyn compatible...
|
||||
|
@ -31,14 +31,14 @@ LL | fn baz(&self) -> Self;
|
|||
= help: consider moving `baz` to another trait
|
||||
|
||||
error[E0038]: the trait `Bar` is not dyn compatible
|
||||
--> $DIR/mentions-Self.rs:24:5
|
||||
--> $DIR/mentions-Self.rs:20:5
|
||||
|
|
||||
LL | t
|
||||
| ^ `Bar` 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>
|
||||
--> $DIR/mentions-Self.rs:11:22
|
||||
--> $DIR/mentions-Self.rs:7:22
|
||||
|
|
||||
LL | trait Bar {
|
||||
| --- this trait is not dyn compatible...
|
||||
|
@ -48,14 +48,14 @@ LL | fn bar(&self, x: &Self);
|
|||
= note: required for the cast from `&T` to `&dyn Bar`
|
||||
|
||||
error[E0038]: the trait `Baz` is not dyn compatible
|
||||
--> $DIR/mentions-Self.rs:30:5
|
||||
--> $DIR/mentions-Self.rs:26:5
|
||||
|
|
||||
LL | t
|
||||
| ^ `Baz` 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>
|
||||
--> $DIR/mentions-Self.rs:15:22
|
||||
--> $DIR/mentions-Self.rs:11:22
|
||||
|
|
||||
LL | trait Baz {
|
||||
| --- this trait is not dyn compatible...
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
// Check that we correctly prevent users from making trait objects
|
||||
// form traits that make use of `Self` in an argument or return
|
||||
// position, unless `where Self : Sized` is present..
|
||||
//
|
||||
//@ revisions: curr dyn_compatible_for_dispatch
|
||||
|
||||
#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))]
|
||||
|
||||
|
||||
trait Bar {
|
||||
|
@ -20,13 +16,13 @@ trait Quux {
|
|||
}
|
||||
|
||||
fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
|
||||
//[curr]~^ ERROR E0038
|
||||
//~^ ERROR E0038
|
||||
t
|
||||
//~^ ERROR E0038
|
||||
}
|
||||
|
||||
fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
|
||||
//[curr]~^ ERROR E0038
|
||||
//~^ ERROR E0038
|
||||
t
|
||||
//~^ ERROR E0038
|
||||
}
|
||||
|
|
69
tests/ui/dyn-compatibility/mentions-Self.stderr
Normal file
69
tests/ui/dyn-compatibility/mentions-Self.stderr
Normal file
|
@ -0,0 +1,69 @@
|
|||
error[E0038]: the trait `Bar` is not dyn compatible
|
||||
--> $DIR/mentions-Self.rs:18:31
|
||||
|
|
||||
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
|
||||
| ^^^^^^^ `Bar` 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>
|
||||
--> $DIR/mentions-Self.rs:7:22
|
||||
|
|
||||
LL | trait Bar {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn bar(&self, x: &Self);
|
||||
| ^^^^^ ...because method `bar` references the `Self` type in this parameter
|
||||
= help: consider moving `bar` to another trait
|
||||
|
||||
error[E0038]: the trait `Baz` is not dyn compatible
|
||||
--> $DIR/mentions-Self.rs:24:31
|
||||
|
|
||||
LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
|
||||
| ^^^^^^^ `Baz` 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>
|
||||
--> $DIR/mentions-Self.rs:11:22
|
||||
|
|
||||
LL | trait Baz {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn baz(&self) -> Self;
|
||||
| ^^^^ ...because method `baz` references the `Self` type in its return type
|
||||
= help: consider moving `baz` to another trait
|
||||
|
||||
error[E0038]: the trait `Bar` is not dyn compatible
|
||||
--> $DIR/mentions-Self.rs:20:5
|
||||
|
|
||||
LL | t
|
||||
| ^ `Bar` 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>
|
||||
--> $DIR/mentions-Self.rs:7:22
|
||||
|
|
||||
LL | trait Bar {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn bar(&self, x: &Self);
|
||||
| ^^^^^ ...because method `bar` references the `Self` type in this parameter
|
||||
= help: consider moving `bar` to another trait
|
||||
= note: required for the cast from `&T` to `&dyn Bar`
|
||||
|
||||
error[E0038]: the trait `Baz` is not dyn compatible
|
||||
--> $DIR/mentions-Self.rs:26:5
|
||||
|
|
||||
LL | t
|
||||
| ^ `Baz` 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>
|
||||
--> $DIR/mentions-Self.rs:11:22
|
||||
|
|
||||
LL | trait Baz {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn baz(&self) -> Self;
|
||||
| ^^^^ ...because method `baz` references the `Self` type in its return type
|
||||
= help: consider moving `baz` to another trait
|
||||
= note: required for the cast from `&T` to `&dyn Baz`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
|
@ -1,28 +0,0 @@
|
|||
error[E0038]: the trait `Foo` is not dyn compatible
|
||||
--> $DIR/no-static.rs:22:27
|
||||
|
|
||||
LL | let b: Box<dyn Foo> = Box::new(Bar);
|
||||
| ^^^^^^^^^^^^^ `Foo` 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>
|
||||
--> $DIR/no-static.rs:9:8
|
||||
|
|
||||
LL | trait Foo {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn foo() {}
|
||||
| ^^^ ...because associated function `foo` has no `self` parameter
|
||||
= help: only type `Bar` implements `Foo`; consider using it directly instead.
|
||||
= note: required for the cast from `Box<Bar>` to `Box<dyn Foo>`
|
||||
help: consider turning `foo` into a method by giving it a `&self` argument
|
||||
|
|
||||
LL | fn foo(&self) {}
|
||||
| +++++
|
||||
help: alternatively, consider constraining `foo` so it does not apply to trait objects
|
||||
|
|
||||
LL | fn foo() where Self: Sized {}
|
||||
| +++++++++++++++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
|
@ -1,16 +1,12 @@
|
|||
// Check that we correctly prevent users from making trait objects
|
||||
// from traits with static methods.
|
||||
//
|
||||
//@ revisions: curr dyn_compatible_for_dispatch
|
||||
|
||||
#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))]
|
||||
|
||||
trait Foo {
|
||||
fn foo() {}
|
||||
}
|
||||
|
||||
fn diverges() -> Box<dyn Foo> {
|
||||
//[curr]~^ ERROR E0038
|
||||
//~^ ERROR E0038
|
||||
loop { }
|
||||
}
|
||||
|
||||
|
@ -21,5 +17,5 @@ impl Foo for Bar {}
|
|||
fn main() {
|
||||
let b: Box<dyn Foo> = Box::new(Bar);
|
||||
//~^ ERROR E0038
|
||||
//[curr]~| ERROR E0038
|
||||
//~| ERROR E0038
|
||||
}
|
||||
|
|
76
tests/ui/dyn-compatibility/no-static.stderr
Normal file
76
tests/ui/dyn-compatibility/no-static.stderr
Normal file
|
@ -0,0 +1,76 @@
|
|||
error[E0038]: the trait `Foo` is not dyn compatible
|
||||
--> $DIR/no-static.rs:8:22
|
||||
|
|
||||
LL | fn diverges() -> Box<dyn Foo> {
|
||||
| ^^^^^^^ `Foo` 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>
|
||||
--> $DIR/no-static.rs:5:8
|
||||
|
|
||||
LL | trait Foo {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn foo() {}
|
||||
| ^^^ ...because associated function `foo` has no `self` parameter
|
||||
= help: only type `Bar` implements `Foo`; consider using it directly instead.
|
||||
help: consider turning `foo` into a method by giving it a `&self` argument
|
||||
|
|
||||
LL | fn foo(&self) {}
|
||||
| +++++
|
||||
help: alternatively, consider constraining `foo` so it does not apply to trait objects
|
||||
|
|
||||
LL | fn foo() where Self: Sized {}
|
||||
| +++++++++++++++++
|
||||
|
||||
error[E0038]: the trait `Foo` is not dyn compatible
|
||||
--> $DIR/no-static.rs:18:12
|
||||
|
|
||||
LL | let b: Box<dyn Foo> = Box::new(Bar);
|
||||
| ^^^^^^^^^^^^ `Foo` 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>
|
||||
--> $DIR/no-static.rs:5:8
|
||||
|
|
||||
LL | trait Foo {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn foo() {}
|
||||
| ^^^ ...because associated function `foo` has no `self` parameter
|
||||
= help: only type `Bar` implements `Foo`; consider using it directly instead.
|
||||
help: consider turning `foo` into a method by giving it a `&self` argument
|
||||
|
|
||||
LL | fn foo(&self) {}
|
||||
| +++++
|
||||
help: alternatively, consider constraining `foo` so it does not apply to trait objects
|
||||
|
|
||||
LL | fn foo() where Self: Sized {}
|
||||
| +++++++++++++++++
|
||||
|
||||
error[E0038]: the trait `Foo` is not dyn compatible
|
||||
--> $DIR/no-static.rs:18:27
|
||||
|
|
||||
LL | let b: Box<dyn Foo> = Box::new(Bar);
|
||||
| ^^^^^^^^^^^^^ `Foo` 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>
|
||||
--> $DIR/no-static.rs:5:8
|
||||
|
|
||||
LL | trait Foo {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn foo() {}
|
||||
| ^^^ ...because associated function `foo` has no `self` parameter
|
||||
= help: only type `Bar` implements `Foo`; consider using it directly instead.
|
||||
= note: required for the cast from `Box<Bar>` to `Box<dyn Foo>`
|
||||
help: consider turning `foo` into a method by giving it a `&self` argument
|
||||
|
|
||||
LL | fn foo(&self) {}
|
||||
| +++++
|
||||
help: alternatively, consider constraining `foo` so it does not apply to trait objects
|
||||
|
|
||||
LL | fn foo() where Self: Sized {}
|
||||
| +++++++++++++++++
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
|
@ -1,19 +0,0 @@
|
|||
error[E0038]: the trait `Bar` is not dyn compatible
|
||||
--> $DIR/sized-2.rs:16:5
|
||||
|
|
||||
LL | t
|
||||
| ^ `Bar` 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>
|
||||
--> $DIR/sized-2.rs:9:18
|
||||
|
|
||||
LL | trait Bar
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | where Self : Sized
|
||||
| ^^^^^ ...because it requires `Self: Sized`
|
||||
= note: required for the cast from `&T` to `&dyn Bar`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
|
@ -1,9 +1,5 @@
|
|||
// Check that we correctly prevent users from making trait objects
|
||||
// from traits where `Self : Sized`.
|
||||
//
|
||||
//@ revisions: curr dyn_compatible_for_dispatch
|
||||
|
||||
#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))]
|
||||
|
||||
trait Bar
|
||||
where Self : Sized
|
||||
|
@ -12,7 +8,7 @@ trait Bar
|
|||
}
|
||||
|
||||
fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
|
||||
//[curr]~^ ERROR E0038
|
||||
//~^ ERROR E0038
|
||||
t
|
||||
//~^ ERROR E0038
|
||||
}
|
||||
|
|
|
@ -1,37 +1,34 @@
|
|||
error[E0038]: the trait `Bar` is not dyn compatible
|
||||
--> $DIR/mentions-Self.rs:24:5
|
||||
--> $DIR/sized-2.rs:10:31
|
||||
|
|
||||
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
|
||||
| ^^^^^^^ `Bar` 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>
|
||||
--> $DIR/sized-2.rs:5:18
|
||||
|
|
||||
LL | trait Bar
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | where Self : Sized
|
||||
| ^^^^^ ...because it requires `Self: Sized`
|
||||
|
||||
error[E0038]: the trait `Bar` is not dyn compatible
|
||||
--> $DIR/sized-2.rs:12:5
|
||||
|
|
||||
LL | t
|
||||
| ^ `Bar` 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>
|
||||
--> $DIR/mentions-Self.rs:11:22
|
||||
--> $DIR/sized-2.rs:5:18
|
||||
|
|
||||
LL | trait Bar {
|
||||
LL | trait Bar
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn bar(&self, x: &Self);
|
||||
| ^^^^^ ...because method `bar` references the `Self` type in this parameter
|
||||
= help: consider moving `bar` to another trait
|
||||
LL | where Self : Sized
|
||||
| ^^^^^ ...because it requires `Self: Sized`
|
||||
= note: required for the cast from `&T` to `&dyn Bar`
|
||||
|
||||
error[E0038]: the trait `Baz` is not dyn compatible
|
||||
--> $DIR/mentions-Self.rs:30:5
|
||||
|
|
||||
LL | t
|
||||
| ^ `Baz` 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>
|
||||
--> $DIR/mentions-Self.rs:15:22
|
||||
|
|
||||
LL | trait Baz {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn baz(&self) -> Self;
|
||||
| ^^^^ ...because method `baz` references the `Self` type in its return type
|
||||
= help: consider moving `baz` to another trait
|
||||
= note: required for the cast from `&T` to `&dyn Baz`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
|
@ -1,19 +0,0 @@
|
|||
error[E0038]: the trait `Bar` is not dyn compatible
|
||||
--> $DIR/sized.rs:14:5
|
||||
|
|
||||
LL | t
|
||||
| ^ `Bar` 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>
|
||||
--> $DIR/sized.rs:8:12
|
||||
|
|
||||
LL | trait Bar: Sized {
|
||||
| --- ^^^^^ ...because it requires `Self: Sized`
|
||||
| |
|
||||
| this trait is not dyn compatible...
|
||||
= note: required for the cast from `&T` to `&dyn Bar`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
|
@ -1,16 +1,12 @@
|
|||
// Check that we correctly prevent users from making trait objects
|
||||
// from traits where `Self : Sized`.
|
||||
//
|
||||
//@ revisions: curr dyn_compatible_for_dispatch
|
||||
|
||||
#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))]
|
||||
|
||||
trait Bar: Sized {
|
||||
fn bar<T>(&self, t: T);
|
||||
}
|
||||
|
||||
fn make_bar<T: Bar>(t: &T) -> &dyn Bar {
|
||||
//[curr]~^ ERROR E0038
|
||||
//~^ ERROR E0038
|
||||
t
|
||||
//~^ ERROR E0038
|
||||
}
|
||||
|
|
34
tests/ui/dyn-compatibility/sized.stderr
Normal file
34
tests/ui/dyn-compatibility/sized.stderr
Normal file
|
@ -0,0 +1,34 @@
|
|||
error[E0038]: the trait `Bar` is not dyn compatible
|
||||
--> $DIR/sized.rs:8:32
|
||||
|
|
||||
LL | fn make_bar<T: Bar>(t: &T) -> &dyn Bar {
|
||||
| ^^^^^^^ `Bar` 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>
|
||||
--> $DIR/sized.rs:4:12
|
||||
|
|
||||
LL | trait Bar: Sized {
|
||||
| --- ^^^^^ ...because it requires `Self: Sized`
|
||||
| |
|
||||
| this trait is not dyn compatible...
|
||||
|
||||
error[E0038]: the trait `Bar` is not dyn compatible
|
||||
--> $DIR/sized.rs:10:5
|
||||
|
|
||||
LL | t
|
||||
| ^ `Bar` 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>
|
||||
--> $DIR/sized.rs:4:12
|
||||
|
|
||||
LL | trait Bar: Sized {
|
||||
| --- ^^^^^ ...because it requires `Self: Sized`
|
||||
| |
|
||||
| this trait is not dyn compatible...
|
||||
= note: required for the cast from `&T` to `&dyn Bar`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
|
@ -1,27 +0,0 @@
|
|||
error[E0038]: the trait `Qux` is not dyn compatible
|
||||
--> $DIR/taint-const-eval.rs:11:33
|
||||
|
|
||||
LL | static FOO: &(dyn Qux + Sync) = "desc";
|
||||
| ^^^^^^ `Qux` 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>
|
||||
--> $DIR/taint-const-eval.rs:8:8
|
||||
|
|
||||
LL | trait Qux {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn bar();
|
||||
| ^^^ ...because associated function `bar` has no `self` parameter
|
||||
= note: required for the cast from `&'static str` to `&'static (dyn Qux + Sync + 'static)`
|
||||
help: consider turning `bar` into a method by giving it a `&self` argument
|
||||
|
|
||||
LL | fn bar(&self);
|
||||
| +++++
|
||||
help: alternatively, consider constraining `bar` so it does not apply to trait objects
|
||||
|
|
||||
LL | fn bar() where Self: Sized;
|
||||
| +++++++++++++++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
|
@ -1,16 +1,12 @@
|
|||
// Test that we do not attempt to create dyn-incompatible trait objects in const eval.
|
||||
|
||||
//@ revisions: curr dyn_compatible_for_dispatch
|
||||
|
||||
#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))]
|
||||
|
||||
trait Qux {
|
||||
fn bar();
|
||||
}
|
||||
|
||||
static FOO: &(dyn Qux + Sync) = "desc";
|
||||
//~^ the trait `Qux` is not dyn compatible
|
||||
//[curr]~| the trait `Qux` is not dyn compatible
|
||||
//[curr]~| the trait `Qux` is not dyn compatible
|
||||
//~| the trait `Qux` is not dyn compatible
|
||||
//~| the trait `Qux` is not dyn compatible
|
||||
|
||||
fn main() {}
|
||||
|
|
74
tests/ui/dyn-compatibility/taint-const-eval.stderr
Normal file
74
tests/ui/dyn-compatibility/taint-const-eval.stderr
Normal file
|
@ -0,0 +1,74 @@
|
|||
error[E0038]: the trait `Qux` is not dyn compatible
|
||||
--> $DIR/taint-const-eval.rs:7:15
|
||||
|
|
||||
LL | static FOO: &(dyn Qux + Sync) = "desc";
|
||||
| ^^^^^^^^^^^^^^ `Qux` 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>
|
||||
--> $DIR/taint-const-eval.rs:4:8
|
||||
|
|
||||
LL | trait Qux {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn bar();
|
||||
| ^^^ ...because associated function `bar` has no `self` parameter
|
||||
help: consider turning `bar` into a method by giving it a `&self` argument
|
||||
|
|
||||
LL | fn bar(&self);
|
||||
| +++++
|
||||
help: alternatively, consider constraining `bar` so it does not apply to trait objects
|
||||
|
|
||||
LL | fn bar() where Self: Sized;
|
||||
| +++++++++++++++++
|
||||
|
||||
error[E0038]: the trait `Qux` is not dyn compatible
|
||||
--> $DIR/taint-const-eval.rs:7:33
|
||||
|
|
||||
LL | static FOO: &(dyn Qux + Sync) = "desc";
|
||||
| ^^^^^^ `Qux` 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>
|
||||
--> $DIR/taint-const-eval.rs:4:8
|
||||
|
|
||||
LL | trait Qux {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn bar();
|
||||
| ^^^ ...because associated function `bar` has no `self` parameter
|
||||
= note: required for the cast from `&'static str` to `&'static (dyn Qux + Sync + 'static)`
|
||||
help: consider turning `bar` into a method by giving it a `&self` argument
|
||||
|
|
||||
LL | fn bar(&self);
|
||||
| +++++
|
||||
help: alternatively, consider constraining `bar` so it does not apply to trait objects
|
||||
|
|
||||
LL | fn bar() where Self: Sized;
|
||||
| +++++++++++++++++
|
||||
|
||||
error[E0038]: the trait `Qux` is not dyn compatible
|
||||
--> $DIR/taint-const-eval.rs:7:15
|
||||
|
|
||||
LL | static FOO: &(dyn Qux + Sync) = "desc";
|
||||
| ^^^^^^^^^^^^^^ `Qux` 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>
|
||||
--> $DIR/taint-const-eval.rs:4:8
|
||||
|
|
||||
LL | trait Qux {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn bar();
|
||||
| ^^^ ...because associated function `bar` has no `self` parameter
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
help: consider turning `bar` into a method by giving it a `&self` argument
|
||||
|
|
||||
LL | fn bar(&self);
|
||||
| +++++
|
||||
help: alternatively, consider constraining `bar` so it does not apply to trait objects
|
||||
|
|
||||
LL | fn bar() where Self: Sized;
|
||||
| +++++++++++++++++
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
|
@ -1,10 +1,7 @@
|
|||
#![feature(intrinsics)]
|
||||
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
fn size_of<T, U>() -> usize {
|
||||
//~^ ERROR E0094
|
||||
loop {}
|
||||
}
|
||||
fn size_of<T, U>() -> usize;
|
||||
//~^ ERROR E0094
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
error[E0094]: intrinsic has wrong number of type parameters: found 2, expected 1
|
||||
--> $DIR/E0094.rs:5:11
|
||||
--> $DIR/E0094.rs:4:11
|
||||
|
|
||||
LL | fn size_of<T, U>() -> usize {
|
||||
LL | fn size_of<T, U>() -> usize;
|
||||
| ^^^^^^ expected 1 type parameter
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
|
|
@ -2,10 +2,7 @@
|
|||
#![feature(rustc_attrs)]
|
||||
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
fn size_of<T>() {
|
||||
//~^ ERROR E0308
|
||||
loop {}
|
||||
}
|
||||
fn size_of<T>();
|
||||
//~^ ERROR E0308
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
error[E0308]: intrinsic has wrong type
|
||||
--> $DIR/E0308.rs:6:16
|
||||
--> $DIR/E0308.rs:5:16
|
||||
|
|
||||
LL | fn size_of<T>() {
|
||||
LL | fn size_of<T>();
|
||||
| ^ expected `usize`, found `()`
|
||||
|
|
||||
= note: expected signature `fn() -> usize`
|
||||
|
|
|
@ -6,7 +6,7 @@ LL | struct Foo<T: ?Sized> {
|
|||
|
|
||||
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
||||
|
||||
error[E0374]: the trait `CoerceUnsized` may only be implemented for a coercion between structures
|
||||
error[E0374]: implementing `CoerceUnsized` requires a field to be coerced
|
||||
--> $DIR/E0374.rs:8:1
|
||||
|
|
||||
LL | / impl<T, U> CoerceUnsized<Foo<U>> for Foo<T>
|
||||
|
|
|
@ -23,14 +23,19 @@ help: the `Box` type always has a statically known size and allocates its conten
|
|||
LL | b: Box<T>,
|
||||
| ++++ +
|
||||
|
||||
error[E0375]: implementing the trait `CoerceUnsized` requires multiple coercions
|
||||
error[E0375]: implementing `CoerceUnsized` does not allow multiple fields to be coerced
|
||||
--> $DIR/E0375.rs:10:12
|
||||
|
|
||||
LL | impl<T, U> CoerceUnsized<Foo<U, T>> for Foo<T, U> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ requires multiple coercions
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced
|
||||
= note: currently, 2 fields need coercions: `b` (`T` to `U`), `c` (`U` to `T`)
|
||||
note: the trait `CoerceUnsized` may only be implemented when a single field is being coerced
|
||||
--> $DIR/E0375.rs:6:5
|
||||
|
|
||||
LL | b: T,
|
||||
| ^^^^
|
||||
LL | c: U,
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
#![feature(coerce_unsized)]
|
||||
use std::ops::CoerceUnsized;
|
||||
|
||||
struct Foo<T: ?Sized> {
|
||||
a: T,
|
||||
}
|
||||
|
||||
impl<T, U> CoerceUnsized<U> for Foo<T> {} //~ ERROR E0376
|
||||
|
||||
fn main() {}
|
|
@ -1,9 +0,0 @@
|
|||
error[E0376]: the trait `CoerceUnsized` may only be implemented for a coercion between structures
|
||||
--> $DIR/E0376.rs:8:1
|
||||
|
|
||||
LL | impl<T, U> CoerceUnsized<U> for Foo<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0376`.
|
|
@ -1,41 +0,0 @@
|
|||
// Test that the use of the dyn-incompatible trait objects
|
||||
// are gated by the `dyn_compatible_for_dispatch` feature gate.
|
||||
|
||||
trait DynIncompatible1: Sized {}
|
||||
|
||||
trait DynIncompatible2 {
|
||||
fn static_fn() {}
|
||||
}
|
||||
|
||||
trait DynIncompatible3 {
|
||||
fn foo<T>(&self);
|
||||
}
|
||||
|
||||
trait DynIncompatible4 {
|
||||
fn foo(&self, s: &Self);
|
||||
}
|
||||
|
||||
fn takes_dyn_incompatible_ref<T>(obj: &dyn DynIncompatible1) {
|
||||
//~^ ERROR E0038
|
||||
}
|
||||
|
||||
fn return_dyn_incompatible_ref() -> &'static dyn DynIncompatible2 {
|
||||
//~^ ERROR E0038
|
||||
loop {}
|
||||
}
|
||||
|
||||
fn takes_dyn_incompatible_box(obj: Box<dyn DynIncompatible3>) {
|
||||
//~^ ERROR E0038
|
||||
}
|
||||
|
||||
fn return_dyn_incompatible_rc() -> std::rc::Rc<dyn DynIncompatible4> {
|
||||
//~^ ERROR E0038
|
||||
loop {}
|
||||
}
|
||||
|
||||
trait Trait {}
|
||||
|
||||
impl Trait for dyn DynIncompatible1 {}
|
||||
//~^ ERROR E0038
|
||||
|
||||
fn main() {}
|
|
@ -1,88 +0,0 @@
|
|||
error[E0038]: the trait `DynIncompatible1` is not dyn compatible
|
||||
--> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:18:40
|
||||
|
|
||||
LL | fn takes_dyn_incompatible_ref<T>(obj: &dyn DynIncompatible1) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible1` 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>
|
||||
--> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:4:25
|
||||
|
|
||||
LL | trait DynIncompatible1: Sized {}
|
||||
| ---------------- ^^^^^ ...because it requires `Self: Sized`
|
||||
| |
|
||||
| this trait is not dyn compatible...
|
||||
|
||||
error[E0038]: the trait `DynIncompatible2` is not dyn compatible
|
||||
--> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:22:46
|
||||
|
|
||||
LL | fn return_dyn_incompatible_ref() -> &'static dyn DynIncompatible2 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible2` 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>
|
||||
--> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:7:8
|
||||
|
|
||||
LL | trait DynIncompatible2 {
|
||||
| ---------------- this trait is not dyn compatible...
|
||||
LL | fn static_fn() {}
|
||||
| ^^^^^^^^^ ...because associated function `static_fn` has no `self` parameter
|
||||
help: consider turning `static_fn` into a method by giving it a `&self` argument
|
||||
|
|
||||
LL | fn static_fn(&self) {}
|
||||
| +++++
|
||||
help: alternatively, consider constraining `static_fn` so it does not apply to trait objects
|
||||
|
|
||||
LL | fn static_fn() where Self: Sized {}
|
||||
| +++++++++++++++++
|
||||
|
||||
error[E0038]: the trait `DynIncompatible3` is not dyn compatible
|
||||
--> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:27:40
|
||||
|
|
||||
LL | fn takes_dyn_incompatible_box(obj: Box<dyn DynIncompatible3>) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible3` 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>
|
||||
--> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:11:8
|
||||
|
|
||||
LL | trait DynIncompatible3 {
|
||||
| ---------------- this trait is not dyn compatible...
|
||||
LL | fn foo<T>(&self);
|
||||
| ^^^ ...because method `foo` has generic type parameters
|
||||
= help: consider moving `foo` to another trait
|
||||
|
||||
error[E0038]: the trait `DynIncompatible4` is not dyn compatible
|
||||
--> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:31:48
|
||||
|
|
||||
LL | fn return_dyn_incompatible_rc() -> std::rc::Rc<dyn DynIncompatible4> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible4` 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>
|
||||
--> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:15:22
|
||||
|
|
||||
LL | trait DynIncompatible4 {
|
||||
| ---------------- this trait is not dyn compatible...
|
||||
LL | fn foo(&self, s: &Self);
|
||||
| ^^^^^ ...because method `foo` references the `Self` type in this parameter
|
||||
= help: consider moving `foo` to another trait
|
||||
|
||||
error[E0038]: the trait `DynIncompatible1` is not dyn compatible
|
||||
--> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:38:16
|
||||
|
|
||||
LL | impl Trait for dyn DynIncompatible1 {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible1` 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>
|
||||
--> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:4:25
|
||||
|
|
||||
LL | trait DynIncompatible1: Sized {}
|
||||
| ---------------- ^^^^^ ...because it requires `Self: Sized`
|
||||
| |
|
||||
| this trait is not dyn compatible...
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
|
@ -1,5 +1,5 @@
|
|||
//! Check that `vtable_size` gets overridden by llvm backend even if there is no
|
||||
//! `rustc_intrinsic_must_be_overridden` attribute on this usage.
|
||||
//! Check that `vtable_size` gets overridden by llvm backend even if there is a
|
||||
//! fallback body.
|
||||
#![feature(intrinsics)]
|
||||
//@run-pass
|
||||
|
||||
|
|
|
@ -8,9 +8,10 @@ use std::{
|
|||
struct WrapperWithExtraField<T>(T, i32);
|
||||
|
||||
impl<T, U> DispatchFromDyn<WrapperWithExtraField<U>> for WrapperWithExtraField<T>
|
||||
//~^ ERROR [E0378]
|
||||
where
|
||||
T: DispatchFromDyn<U>,
|
||||
{} //~^^^ ERROR [E0378]
|
||||
{}
|
||||
|
||||
|
||||
struct MultiplePointers<T: ?Sized>{
|
||||
|
@ -19,9 +20,10 @@ struct MultiplePointers<T: ?Sized>{
|
|||
}
|
||||
|
||||
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<MultiplePointers<U>> for MultiplePointers<T>
|
||||
//~^ implementing `DispatchFromDyn` does not allow multiple fields to be coerced
|
||||
where
|
||||
T: Unsize<U>,
|
||||
{} //~^^^ ERROR [E0378]
|
||||
{}
|
||||
|
||||
|
||||
struct NothingToCoerce<T: ?Sized> {
|
||||
|
@ -29,23 +31,25 @@ struct NothingToCoerce<T: ?Sized> {
|
|||
}
|
||||
|
||||
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NothingToCoerce<T>> for NothingToCoerce<U> {}
|
||||
//~^ ERROR [E0378]
|
||||
//~^ ERROR implementing `DispatchFromDyn` requires a field to be coerced
|
||||
|
||||
#[repr(C)]
|
||||
struct HasReprC<T: ?Sized>(Box<T>);
|
||||
|
||||
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<HasReprC<U>> for HasReprC<T>
|
||||
//~^ ERROR [E0378]
|
||||
where
|
||||
T: Unsize<U>,
|
||||
{} //~^^^ ERROR [E0378]
|
||||
{}
|
||||
|
||||
#[repr(align(64))]
|
||||
struct OverAlignedZst;
|
||||
struct OverAligned<T: ?Sized>(Box<T>, OverAlignedZst);
|
||||
|
||||
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<OverAligned<U>> for OverAligned<T>
|
||||
//~^ ERROR [E0378]
|
||||
where
|
||||
T: Unsize<U>,
|
||||
{} //~^^^ ERROR [E0378]
|
||||
{}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -2,25 +2,32 @@ error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs co
|
|||
--> $DIR/invalid_dispatch_from_dyn_impls.rs:10:1
|
||||
|
|
||||
LL | / impl<T, U> DispatchFromDyn<WrapperWithExtraField<U>> for WrapperWithExtraField<T>
|
||||
LL | |
|
||||
LL | | where
|
||||
LL | | T: DispatchFromDyn<U>,
|
||||
| |__________________________^
|
||||
|
|
||||
= note: extra field `1` of type `i32` is not allowed
|
||||
|
||||
error[E0378]: implementing the `DispatchFromDyn` trait requires multiple coercions
|
||||
--> $DIR/invalid_dispatch_from_dyn_impls.rs:21:1
|
||||
error[E0375]: implementing `DispatchFromDyn` does not allow multiple fields to be coerced
|
||||
--> $DIR/invalid_dispatch_from_dyn_impls.rs:22:1
|
||||
|
|
||||
LL | / impl<T: ?Sized, U: ?Sized> DispatchFromDyn<MultiplePointers<U>> for MultiplePointers<T>
|
||||
LL | |
|
||||
LL | | where
|
||||
LL | | T: Unsize<U>,
|
||||
| |_________________^
|
||||
|
|
||||
= note: the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced
|
||||
= note: currently, 2 fields need coercions: `ptr1` (`*const T` to `*const U`), `ptr2` (`*const T` to `*const U`)
|
||||
note: the trait `DispatchFromDyn` may only be implemented when a single field is being coerced
|
||||
--> $DIR/invalid_dispatch_from_dyn_impls.rs:18:5
|
||||
|
|
||||
LL | ptr1: *const T,
|
||||
| ^^^^^^^^^^^^^^
|
||||
LL | ptr2: *const T,
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures
|
||||
--> $DIR/invalid_dispatch_from_dyn_impls.rs:31:1
|
||||
error[E0374]: implementing `DispatchFromDyn` requires a field to be coerced
|
||||
--> $DIR/invalid_dispatch_from_dyn_impls.rs:33:1
|
||||
|
|
||||
LL | impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NothingToCoerce<T>> for NothingToCoerce<U> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -28,17 +35,19 @@ LL | impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NothingToCoerce<T>> for NothingT
|
|||
= note: expected a single field to be coerced, none found
|
||||
|
||||
error[E0378]: structs implementing `DispatchFromDyn` may not have `#[repr(packed)]` or `#[repr(C)]`
|
||||
--> $DIR/invalid_dispatch_from_dyn_impls.rs:37:1
|
||||
--> $DIR/invalid_dispatch_from_dyn_impls.rs:39:1
|
||||
|
|
||||
LL | / impl<T: ?Sized, U: ?Sized> DispatchFromDyn<HasReprC<U>> for HasReprC<T>
|
||||
LL | |
|
||||
LL | | where
|
||||
LL | | T: Unsize<U>,
|
||||
| |_________________^
|
||||
|
||||
error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment that don't mention type/const generics, and nothing else
|
||||
--> $DIR/invalid_dispatch_from_dyn_impls.rs:46:1
|
||||
--> $DIR/invalid_dispatch_from_dyn_impls.rs:49:1
|
||||
|
|
||||
LL | / impl<T: ?Sized, U: ?Sized> DispatchFromDyn<OverAligned<U>> for OverAligned<T>
|
||||
LL | |
|
||||
LL | | where
|
||||
LL | | T: Unsize<U>,
|
||||
| |_____________________^
|
||||
|
@ -47,4 +56,5 @@ LL | | T: Unsize<U>,
|
|||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0378`.
|
||||
Some errors have detailed explanations: E0374, E0375, E0378.
|
||||
For more information about an error, try `rustc --explain E0374`.
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
// Test that Copy bounds inherited by trait are checked.
|
||||
//
|
||||
//@ revisions: curr dyn_compatible_for_dispatch
|
||||
|
||||
#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))]
|
||||
|
||||
|
||||
use std::any::Any;
|
||||
|
@ -18,17 +14,15 @@ fn take_param<T:Foo>(foo: &T) { }
|
|||
|
||||
fn a() {
|
||||
let x: Box<_> = Box::new(3);
|
||||
take_param(&x); //[curr]~ ERROR E0277
|
||||
//[dyn_compatible_for_dispatch]~^ ERROR E0277
|
||||
take_param(&x); //~ ERROR E0277
|
||||
}
|
||||
|
||||
fn b() {
|
||||
let x: Box<_> = Box::new(3);
|
||||
let y = &x;
|
||||
let z = &x as &dyn Foo;
|
||||
//[curr]~^ ERROR E0038
|
||||
//[curr]~| ERROR E0038
|
||||
//[dyn_compatible_for_dispatch]~^^^ ERROR E0038
|
||||
//~^ ERROR E0038
|
||||
//~| ERROR E0038
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
|
|
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