Semantics of *mut _

I've seen ptr as *mut _ being used, but I can't find semantics of the underscore in this context explicitly defined anywhere.

I expected it to be mentioned in Casting Between Types section of the book, but there was nothing. Am I looking at the wrong place or is it not yet documented?

1 Like

_ in type position is just "the type hole". It means "there's a type here, but I can't be bothered to tell you what it is; you figure it out". It causes the compiler to infer the type in that position.

It's not explicitly defined there because it's not specifically part of *mut or casting; it's just a thing in the type system. In that particular context, it's casting from *const u8 to *mut _, so the _ is u8.

The underscore is called a "type placeholder", and it is mentioned very briefly in the book, but I cannot remember where :frowning: Basically, it's used when you want Rust to figure out the type, but syntax demands it. So in this example, it could be as *mut u8, but instead, decided to let Rust figure out that u8 is there.

Syntax Index is usually the first place to go to learn about syntax, but it only covers _ in patterns, apparently!

Thanks! It makes it a bit more clear now. Should I file an issue on GitHub about adding this section to the book?

Also, a question about inference then. For example, if I call a function some_function(foo as *mut _), where foo is *const i8 and function header is fn some_function(arg: *mut u8), should I always expect it to infer _ from the function header (that is, in this case it would be u8 and not i8)?

In that case, it should fail to compile because those two types don't unify. blah blah blah

Normally I would say "yes", but the existing book isn't being worked on, as I'm working on its replacement instead.

1 Like

@DanielKeep what about this code (it's nonsensical, but it compiles and runs on nightly):

fn test(arg: *mut u8) {
    unsafe {
        println!("{}", *arg);
    }
}

fn main() {
    let x: i8 = 10;
    let y: *const i8 = &x as *const i8;
    test(y as *mut _);
}

@steveklabnik glad to hear about the new book! At least I brought this thing up, maybe you'll get a chance to mention it in the new resource :slight_smile:

Well, there you go. I assume it prioritises the result type in an as, which makes sense.

1 Like