Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing unsizing coercions for raw slice pointers #74679

Open
RalfJung opened this issue Jul 23, 2020 · 3 comments
Open

Missing unsizing coercions for raw slice pointers #74679

RalfJung opened this issue Jul 23, 2020 · 3 comments
Labels
A-coercions Area: implicit and explicit `expr as Type` coercions C-bug Category: This is a bug.

Comments

@RalfJung
Copy link
Member

With #73986 having landed, one would expect something like this to work:

#![feature(raw_ref_op)]
#![feature(slice_ptr_get)]

struct S {
    keys: [i32; 2],
}

unsafe fn get_last(s: *const S) -> i32 {
    let keys = &raw const (*s).keys;
    *keys.get_unchecked(1)
}

fn main() {
    let s = S { keys: [24, 42] };
    let p = &raw const s;
    assert_eq!(unsafe { get_last(p) }, 42);
}

However, this fails saying

error[E0599]: no method named `get_unchecked` found for raw pointer `*const [i32; 2]` in the current scope
  --> src/main.rs:11:11
   |
11 |     *keys.get_unchecked(1)
   |           ^^^^^^^^^^^^^ method not found in `*const [i32; 2]`
   |
   = note: try using `<*const T>::as_ref()` to get a reference to the type behind the pointer: https://doc.rust-lang.org/std/primitive.pointer.html#method.as_ref
   = note: using `<*const T>::as_ref()` on a pointer which is unaligned or points to invalid or uninitialized memory is undefined behavior

One has to add a *const [_] type annotation to force an unsizing coercion for this to work.

@RalfJung
Copy link
Member Author

Thanks to @ssomers for finding this problem!

@jonas-schievink jonas-schievink added A-coercions Area: implicit and explicit `expr as Type` coercions C-bug Category: This is a bug. labels Jul 23, 2020
@b-naber
Copy link
Contributor

b-naber commented Jan 15, 2021

@RalfJung The reason this currently doesn't work is that the compiler doesn't identify *const [T] as a supertype of *const [T;n]. This happens here, get_unchecked is actually considered as a candidate, but rejected because of the type relation.

I'm not sure how we should handle this, seems unlikely that this type relation should hold, but hasn't been implemented yet. If so should this call even work? Or would it be enough if we output an error suggestion for a coercion in this case?

@RalfJung
Copy link
Member Author

Without this coercion, raw-ptr-as-self is unergonomic in yet another way. That's why I think the coercion should happen, at least in method receiver position.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-coercions Area: implicit and explicit `expr as Type` coercions C-bug Category: This is a bug.
Projects
None yet
3 participants