Allow qualified paths in struct construction (both expressions and patterns) by rylev · Pull Request #80080 · rust-lang/rust (original) (raw)

@Mark-Simulacrum thanks!

The question at hand is should qualified paths type aliases be useable in patterns and expressions for both struct-structs and tuple-structs. This question can be further broken down to: should they be parseable but not pass analysis, not even parseable, or fully useable?

For example, should this code which does not compile in master be made to compile (or at the very least parse)?

fn main() { let ::AssociatedType { a } = ::AssociatedType { a: 0 }; let ::AssociatedType(a) = ::AssociatedType(0); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This is the only thing that currently parses let s = StructStruct { a : 0 }; match s { ::AssociatedType { a } => a, };

let s = TupleStruct(0);
match s {
   <WithTupleStruct as Trait>::AssociatedType(a) => a,
};

}

struct StructStruct { a: usize }

struct TupleStruct(usize);

trait Trait { type AssociatedType; }

struct WithStructStruct;

impl Trait for WithStructStruct { type AssociatedType = StructStruct; }

struct WithTupleStruct;

impl Trait for WithTupleStruct { type AssociatedType = TupleStruct; }

playground link

Currently in master only tuple structs in expression position parse - though they are not allowed past analysis (rustc_resolve prevents them from being used). Everything else fails to even parse:

let _ = ::AssociatedType(0); // ^ parses but does not compile

It is important to note that the use of struct-structs (but not tuple-structs) with qualified paths is allowed if that struct-struct is referred to behind an alias. For example, the following compiles already:

type Alias = ::AssociatedType; let alias = Alias { a: 0 } ; match alias { Alias { a } => a, };

This PR allows the full use of qualified paths in struct-struct patterns and expressions and the parsing of tuple-structs in patterns. Tuple-structs are still not allowed past analysis in both expression and pattern position but this seems wrong (and was an oversight) and should be made consistent with whatever direction we decide to go with struct-structs.

Reasoning

The reason I decided to work on this was due to the need for this in generated code where the generated code knew the trait in question but not the specific associated type. Because of the nature of the associated type it was possible to construct that type but not to name it. To work around this, the alias trick above was used.

This seems like a strange inconsistency that should be resolved. Although it's not often useful, being able to refer to types through qualified paths can be useful in limited circumstances and it does seem natural and unsurprising.