1

I am sorry, but I am so lost that I'm not sure how to frame the question. If you have a suggestion for a better title, please let me know.

I researched type ascription, and found that it is the ability to annotate an expression with the type we want it to have.

I defined the following trait and function. From my limited understanding, I am specifying the type to be u16:

//  src/range.rs

pub struct Range {
    pub min: u16,
    pub max: u16,
    pub current: u16
}

impl Range {
    pub fn new(min: u16, max: u16, current: u16) -> Self {
        Range{ min, max, current }
    }

Next, I wanted to test new() inside my integration_tests:

//  tests/integration_tests.rs

use confine::range::Range;

#[test]
fn new_confine() {
    assert_eq!(Range{min: 1, max: 6, cursor: 1}, Range::new(min: 1, max: 6, cursor: 1));

Why is the compiler confused by the type when I specifically defined the struct to be u16? I tried explicitly writing 1u16 too.

I am receiving the following error:

error: expected type, found `1`
 --> tests/integration_test.rs:5:70
  |
5 |     assert_eq!(Confine{min: 1, max: 6, cursor: 1}, Confine::new(min: 1, max: 6, cursor: 1));
  |                                                                    - ^ expected type
  |                                                                    |
  |                                                                    tried to parse a type due to this type ascription
  |

Connor Cantrell
  • 119
  • 1
  • 11

1 Answers1

1

This is the main difference between initializing a struct and calling a function in Rust. When initializing a struct, the fields are named (assuming the struct has named fields), but named arguments are currently unsupported for functions.

To call Confine::new, simply leave out the min:, max: and cursor:.

assert_eq!(
    Range {min: 1, max: 6, cursor: 1},
    Range::new(1, 6, 1)
);

Now to explain the error. The arguments of a function are comma-separated lists of expressions, so (e.g.) min: 1 is parsed as an expression. This goes fine until the :. An expression containing : (in that position, at least) has to be type ascription (which is unstable, but still implemented in the grammar). That implies that the rest of min: 1 has to be a type, so 1 is parsed as a type. This clearly goes wrong since 1 is an integer, not a type.

None of this has anything to do with the actual types of the arguments. Just having (1, 6, 1) as above will be enough to infer that they're u16.


By the way, this distinction between structs and functions can be exploited to give something like named parameters. Instead of taking the arguments individually, the function takes a struct as its only argument. Then when calling the function, you initialize a struct using its named fields and pass that to the function. There are more sophisticated things you can do in this direction, but that's the basics.

SCappella
  • 9,534
  • 1
  • 26
  • 35