rust/compiler/rustc_middle/src/ty
Matthias Krüger 99bafad6c2
Rollup merge of #120354 - lukas-code:metadata-normalize, r=lcnr
improve normalization of `Pointee::Metadata`

This PR makes it so that `<Wrapper<Tail> as Pointee>::Metadata` is normalized to `<Tail as Pointee>::Metadata` if we don't know `Wrapper<Tail>: Sized`. With that, the trait solver can prove projection predicates like `<Wrapper<Tail> as Pointee>::Metadata == <Tail as Pointee>::Metadata`, which makes it possible to use the metadata APIs to cast between the tail and the wrapper:

```rust
#![feature(ptr_metadata)]

use std::ptr::{self, Pointee};

fn cast_same_meta<T: ?Sized, U: ?Sized>(ptr: *const T) -> *const U
where
    T: Pointee<Metadata = <U as Pointee>::Metadata>,
{
    let (thin, meta) = ptr.to_raw_parts();
    ptr::from_raw_parts(thin, meta)
}

struct Wrapper<T: ?Sized>(T);

fn cast_to_wrapper<T: ?Sized>(ptr: *const T) -> *const Wrapper<T> {
    cast_same_meta(ptr)
}
```

Previously, this failed to compile:

```
error[E0271]: type mismatch resolving `<Wrapper<T> as Pointee>::Metadata == <T as Pointee>::Metadata`
  --> src/lib.rs:16:5
   |
15 | fn cast_to_wrapper<T: ?Sized>(ptr: *const T) -> *const Wrapper<T> {
   |                    - found this type parameter
16 |     cast_same_meta(ptr)
   |     ^^^^^^^^^^^^^^ expected `Wrapper<T>`, found type parameter `T`
   |
   = note: expected associated type `<Wrapper<T> as Pointee>::Metadata`
              found associated type `<T as Pointee>::Metadata`
   = note: an associated type was expected, but a different one was found
```

(Yes, you can already do this with `as` casts. But using functions is so much  *safer* , because you can't change the metadata on accident.)

---

This PR essentially changes the built-in impls of `Pointee` from this:

```rust
// before

impl Pointee for u8 {
    type Metadata = ();
}

impl Pointee for [u8] {
    type Metadata = usize;
}

// ...

impl Pointee for Wrapper<u8> {
    type Metadata = ();
}

impl Pointee for Wrapper<[u8]> {
    type Metadata = usize;
}

// ...

// This impl is only selected if `T` is a type parameter or unnormalizable projection or opaque type.
fallback impl<T: ?Sized> Pointee for Wrapper<T>
where
    Wrapper<T>: Sized
{
    type Metadata = ();
}

// This impl is only selected if `T` is a type parameter or unnormalizable projection or opaque type.
fallback impl<T /*: Sized */> Pointee for T {
    type Metadata = ();
}
```

to this:

```rust
// after

impl Pointee for u8 {
    type Metadata = ();
}

impl Pointee for [u8] {
    type Metadata = usize;
}

// ...

impl<T: ?Sized> Pointee for Wrapper<T> {
    // in the old solver this will instead project to the "deep" tail directly,
    // e.g. `Wrapper<Wrapper<T>>::Metadata = T::Metadata`
    type Metadata = <T as Pointee>::Metadata;
}

// ...

// This impl is only selected if `T` is a type parameter or unnormalizable projection or opaque type.
fallback impl<T /*: Sized */> Pointee for T {
    type Metadata = ();
}
```
2024-02-09 19:21:16 +01:00
..
consts Rollup merge of #116284 - RalfJung:no-nan-match, r=cjgillot 2024-02-05 11:07:26 +01:00
context Don't leak the function that is called on drop 2023-05-23 14:53:36 +00:00
inhabitedness Reveal empty opaques in depth 2023-12-23 14:59:12 +01:00
print address review comments and add more tests 2024-02-07 20:58:05 +01:00
_match.rs Remove dead args from functions 2024-02-02 22:47:26 +00:00
abstract_const.rs Remove more unused Lift impls. 2023-09-18 09:37:10 +10:00
adjustment.rs Remove unused Lift derives. 2023-09-18 09:37:10 +10:00
adt.rs Update to bitflags 2 in the compiler 2023-12-30 18:17:28 +01:00
assoc.rs use visibility to check unused imports and delete some stmts 2023-10-22 21:27:46 +08:00
binding.rs Remove more unused Lift impls. 2023-09-18 09:37:10 +10:00
cast.rs Remove mir::CastKind::Misc 2022-10-06 15:32:41 +03:00
closure.rs is_coroutine -> is_coroutine_or_closure 2023-12-30 15:24:15 +00:00
codec.rs ctfe interpreter: extend provenance so that it can track whether a pointer is immutable 2023-12-07 17:46:36 +01:00
consts.rs Move predicate, region, and const stuff into their own modules in middle 2024-01-30 16:10:19 +00:00
context.rs Rollup merge of #120707 - compiler-errors:suitable-region, r=nnethercote 2024-02-06 22:45:43 +01:00
diagnostics.rs make effect infer variables suggestable in diagnostics 2024-02-04 11:30:59 +08:00
erase_regions.rs rename ReLateBound to ReBound 2023-11-13 14:13:54 +00:00
error.rs Add CoroutineClosure to TyKind, AggregateKind, UpvarArgs 2024-02-06 02:22:58 +00:00
fast_reject.rs Add CoroutineClosure to TyKind, AggregateKind, UpvarArgs 2024-02-06 02:22:58 +00:00
flags.rs More comments, final tweaks 2024-02-06 02:22:58 +00:00
fold.rs rename bound region instantiation 2023-11-17 09:29:48 +00:00
generic_args.rs Add CoroutineClosure to TyKind, AggregateKind, UpvarArgs 2024-02-06 02:22:58 +00:00
generics.rs rename to verbose-internals 2023-12-19 13:35:37 -05:00
impls_ty.rs ctfe interpreter: extend provenance so that it can track whether a pointer is immutable 2023-12-07 17:46:36 +01:00
instance.rs Record coroutine kind in generics 2024-02-07 16:18:31 +00:00
layout.rs Add CoroutineClosure to TyKind, AggregateKind, UpvarArgs 2024-02-06 02:22:58 +00:00
list.rs Remove redundant type parameter 2023-10-23 16:02:05 -04:00
mod.rs Fix drop shim for AsyncFnOnce closure, AsyncFnMut shim for AsyncFn closure 2024-02-06 02:22:58 +00:00
normalize_erasing_regions.rs rename bound region instantiation 2023-11-17 09:29:48 +00:00
opaque_types.rs Rename consuming chaining methods on DiagnosticBuilder. 2024-01-10 07:40:00 +11:00
parameterized.rs Make iteration order of collect_return_position_impl_trait_in_trait_tys query stable 2024-01-04 13:48:57 +01:00
predicate.rs Move predicate, region, and const stuff into their own modules in middle 2024-01-30 16:10:19 +00:00
region.rs Move predicate, region, and const stuff into their own modules in middle 2024-01-30 16:10:19 +00:00
relate.rs Add CoroutineClosure to TyKind, AggregateKind, UpvarArgs 2024-02-06 02:22:58 +00:00
rvalue_scopes.rs Enable potential_query_instability lint in rustc_hir_typeck. 2023-07-14 10:10:14 +02:00
structural_impls.rs Add CoroutineClosure to TyKind, AggregateKind, UpvarArgs 2024-02-06 02:22:58 +00:00
sty.rs Rollup merge of #120354 - lukas-code:metadata-normalize, r=lcnr 2024-02-09 19:21:16 +01:00
trait_def.rs Make crate_inherent_impls fallible and stop using track_errors for it 2024-01-17 10:02:29 +00:00
typeck_results.rs Split StableCompare trait out of StableOrd trait. 2024-01-04 13:32:42 +01:00
util.rs Add CoroutineClosure to TyKind, AggregateKind, UpvarArgs 2024-02-06 02:22:58 +00:00
visit.rs Tweak error counting. 2024-01-22 10:14:01 +11:00
vtable.rs make it more clear which functions create fresh AllocId 2023-09-14 07:27:31 +02:00
walk.rs Add CoroutineClosure to TyKind, AggregateKind, UpvarArgs 2024-02-06 02:22:58 +00:00