Add proper name mangling for pattern types

This commit is contained in:
Oli Scherer 2025-06-11 11:32:57 +00:00 committed by Oli Scherer
parent f6092f224d
commit 739e89980f
3 changed files with 36 additions and 10 deletions

View file

@ -262,15 +262,16 @@ impl<'tcx> V0SymbolMangler<'tcx> {
fn print_pat(&mut self, pat: ty::Pattern<'tcx>) -> Result<(), std::fmt::Error> {
Ok(match *pat {
ty::PatternKind::Range { start, end } => {
let consts = [start, end];
for ct in consts {
Ty::new_array_with_const_len(self.tcx, self.tcx.types.unit, ct).print(self)?;
}
self.push("R");
self.print_const(start)?;
self.print_const(end)?;
}
ty::PatternKind::Or(patterns) => {
self.push("O");
for pat in patterns {
self.print_pat(pat)?;
}
self.push("E");
}
})
}
@ -498,12 +499,9 @@ impl<'tcx> Printer<'tcx> for V0SymbolMangler<'tcx> {
}
ty::Pat(ty, pat) => {
// HACK: Represent as tuple until we have something better.
// HACK: constants are used in arrays, even if the types don't match.
self.push("T");
self.push("W");
ty.print(self)?;
self.print_pat(pat)?;
self.push("E");
}
ty::Array(ty, len) => {

View file

@ -710,6 +710,7 @@ A *placeholder* may occur in circumstances where a type or const value is not re
[mut-ptr-type]: #mut-ptr-type
[fn-type]: #fn-type
[dyn-trait-type]: #dyn-trait-type
[pattern-type]: #pattern-type
> type → \
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *[basic-type]* \
@ -722,6 +723,7 @@ A *placeholder* may occur in circumstances where a type or const value is not re
> &nbsp;&nbsp; | *[mut-ptr-type]* \
> &nbsp;&nbsp; | *[fn-type]* \
> &nbsp;&nbsp; | *[dyn-trait-type]* \
> &nbsp;&nbsp; | *[pattern-type]* \
> &nbsp;&nbsp; | *[path]* \
> &nbsp;&nbsp; | *[backref]*
@ -830,6 +832,23 @@ Remaining primitives are encoded as a crate production, e.g. `C4f128`.
[fn-sig]: #fn-sig
[abi]: #abi
* `W` — A [pattern-type][pattern-tpye] `u32 is 0..100`.
> <span id="pattern-type">pattern-type</span>`W` *[pattern-kind]*
>
> <span id="pattern-kind">pattern-kind</span> → \
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *[range-pattern-kind]* \
> &nbsp;&nbsp; *[or-pattern-kind]*
>
> <span id="range-pattern-kind">range-pattern-kind</span>`R` *[const]* *[const]*
>
> <span id="or-pattern-kind">or-pattern-kind</span>`O` *[pattern-kind]* `E`
While or patterns can be nested in theory, in practice this does not happen and they are instead flattened.
Range patterns have a start and end constant that are both included in the range.
The end must be larger than the start (there can be no wraparound). To emulate wraparound,
you need to use an or pattern of the two ranges to the upper limit and from the lower limit.
* `D` — A [trait object][reference-trait-object] `dyn Trait<Assoc=X> + Send + 'a`.
> <span id="dyn-trait-type">dyn-trait-type</span>`D` *[dyn-bounds]* *[lifetime]*
@ -1139,6 +1158,7 @@ The following is a summary of all of the productions of the symbol grammar.
> &nbsp;&nbsp; | *[mut-ptr-type]* \
> &nbsp;&nbsp; | *[fn-type]* \
> &nbsp;&nbsp; | *[dyn-trait-type]* \
> &nbsp;&nbsp; | *[pattern-type]* \
> &nbsp;&nbsp; | *[path]* \
> &nbsp;&nbsp; | *[backref]*
>
@ -1152,6 +1172,14 @@ The following is a summary of all of the productions of the symbol grammar.
> [mut-ptr-type] → `O` *[type]* \
> [fn-type] → `F` *[fn-sig]* \
> [dyn-trait-type] → `D` *[dyn-bounds]* *[lifetime]*
> [pattern-type] → `W` *[pattern-kind]*
>
> [pattern-kind] → \
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *[range-pattern-kind]* \
> &nbsp;&nbsp; *[or-pattern-kind]*
>
> [range-pattern-kind] -> `R` *[const]* *[const]* \
> [or-pattern-kind] -> `O` *[pattern-kind]* `E` \
>
> [namespace] → *[lower]* | *[upper]*
>

View file

@ -16,7 +16,7 @@ pub fn bar() {
// CHECK: call pattern_type_symbols::foo::<u32>
// CHECK: call void @_RINvC[[CRATE_IDENT:[a-zA-Z0-9]{12}]]_20pattern_type_symbols3foomEB2_
foo::<u32>();
// CHECK: call pattern_type_symbols::foo::<(u32, [(); 0], [(); 999999999])>
// CHECK: call void @_RINvC[[CRATE_IDENT]]_20pattern_type_symbols3fooTmAum0_Aum3b9ac9ff_EEB2_
// CHECK: call pattern_type_symbols::foo::<u32 is 0..=999999999>
// CHECK: call void @_RINvC[[CRATE_IDENT]]_20pattern_type_symbols3fooWmRm0_m3b9ac9ff_EB2_
foo::<NanoU32>();
}