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:
bors 2025-02-25 02:24:40 +00:00
commit f5729cfed3
135 changed files with 1454 additions and 2924 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -36,10 +36,7 @@ mod intrinsics {
#[rustc_nounwind]
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
pub fn abort() -> ! {
loop {}
}
pub fn abort() -> !;
}
/*

View file

@ -36,10 +36,7 @@ mod intrinsics {
#[rustc_nounwind]
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
pub fn abort() -> ! {
loop {}
}
pub fn abort() -> !;
}
/*

View file

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

View file

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

View file

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

View file

@ -49,10 +49,7 @@ mod intrinsics {
#[rustc_nounwind]
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
pub fn abort() -> ! {
loop {}
}
pub fn abort() -> !;
}
mod libc {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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.*"]`.

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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, &[]),

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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

View 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

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

View file

@ -290,9 +290,14 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE");
`xsavec`
`xsaveopt`
`xsaves`
`za128rs`
`za64rs`
`zaamo`
`zabha`
`zacas`
`zalrsc`
`zama16b`
`zawrs`
`zba`
`zbb`
`zbc`

View file

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

View file

@ -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() {}

View file

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

View file

@ -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() {}

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

View file

@ -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() {}

View file

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

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

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

View file

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

View file

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

View file

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

View file

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

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

View file

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

View file

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

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

View file

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

View file

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

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

View file

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

View file

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

View file

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

View file

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

View file

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

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

View file

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

View file

@ -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() {}

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

View file

@ -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() {}

View file

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

View file

@ -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() {}

View file

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

View file

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

View file

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

View file

@ -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() {}

View file

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

View file

@ -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() {}

View file

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

View file

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

View file

@ -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() {}

View file

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

View file

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