-
Notifications
You must be signed in to change notification settings - Fork 12.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #112216 - est31:offset_of_deep_tuple, r=petrochenkov
Support float-like tuple indices in offset_of!() Supports invocations like `offset_of!((((), ()), ()), 0.0)`. This `0.0` gets tokenized as float literal, so it has to be broken up again. The code that did the breaking up was returning a finished `Expr`, while we need a `Ident`, so this PR splits up the `parse_expr_tuple_field_access_float` function into: * a function that breaks up the float literal (similar to `TokenKind::break_two_token_op`, but we do access the parser during this splitting operation, so we keep it as an inherent function on the parser) * and a function that constructs an `Expr` from it The former we can then re-use in `offset_of` parsing. The edge cases especially involving whitespaces are tricky so this adds a bunch of new tests as well. fixes #112204
- Loading branch information
Showing
4 changed files
with
390 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// run-pass | ||
// Test for issue #112204 -- make sure this goes through the entire compilation pipeline, | ||
// similar to why `offset-of-unsized.rs` is also build-pass | ||
|
||
#![feature(offset_of)] | ||
#![feature(builtin_syntax)] | ||
|
||
use std::mem::offset_of; | ||
|
||
type ComplexTup = ((u8, (u8, (u8, u16), u8)), (u8, u32, u16)); | ||
|
||
fn main() { | ||
println!("{}", offset_of!(((u8, u8), u8), 0)); | ||
println!("{}", offset_of!(((u8, u8), u8), 1)); | ||
println!("{}", offset_of!(((u8, (u8, u8)), (u8, u8, u8)), 0.1.0)); | ||
|
||
// Complex case: do all combinations of spacings because the spacing determines what gets | ||
// sent to the lexer. | ||
println!("{}", offset_of!(ComplexTup, 0.1.1.1)); | ||
println!("{}", builtin # offset_of(ComplexTup, 0. 1.1.1)); | ||
println!("{}", offset_of!(ComplexTup, 0 . 1.1.1)); | ||
println!("{}", offset_of!(ComplexTup, 0 .1.1.1)); | ||
println!("{}", offset_of!(ComplexTup, 0.1 .1.1)); | ||
println!("{}", offset_of!(ComplexTup, 0.1 . 1.1)); | ||
println!("{}", offset_of!(ComplexTup, 0.1. 1.1)); | ||
println!("{}", builtin # offset_of(ComplexTup, 0.1.1. 1)); | ||
println!("{}", offset_of!(ComplexTup, 0.1.1 . 1)); | ||
println!("{}", offset_of!(ComplexTup, 0.1.1 .1)); | ||
|
||
println!("{}", offset_of!(((u8, u16), (u32, u16, u8)), 0.0)); | ||
println!("{}", offset_of!(((u8, u16), (u32, u16, u8)), 1.2)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,54 @@ | ||
#![feature(offset_of)] | ||
#![feature(builtin_syntax)] | ||
|
||
use std::mem::offset_of; | ||
|
||
fn main() { | ||
core::mem::offset_of!((u8, u8), _0); //~ ERROR no field `_0` | ||
core::mem::offset_of!((u8, u8), +1); //~ ERROR no rules expected | ||
core::mem::offset_of!((u8, u8), -1); //~ ERROR no rules expected | ||
offset_of!((u8, u8), _0); //~ ERROR no field `_0` | ||
offset_of!((u8, u8), 01); //~ ERROR no field `01` | ||
offset_of!((u8, u8), 1e2); //~ ERROR no field `1e2` | ||
offset_of!((u8, u8), 1_u8); //~ ERROR no field `1_` | ||
//~| ERROR suffixes on a tuple index | ||
offset_of!((u8, u8), +1); //~ ERROR no rules expected | ||
offset_of!((u8, u8), -1); //~ ERROR no rules expected | ||
offset_of!((u8, u8), 1.); //~ ERROR expected identifier, found `)` | ||
offset_of!((u8, u8), 1 .); //~ ERROR unexpected end of macro | ||
builtin # offset_of((u8, u8), 1e2); //~ ERROR no field `1e2` | ||
builtin # offset_of((u8, u8), _0); //~ ERROR no field `_0` | ||
builtin # offset_of((u8, u8), +1); //~ ERROR expected identifier | ||
builtin # offset_of((u8, u8), 01); //~ ERROR no field `01` | ||
builtin # offset_of((u8, u8), 1_u8); //~ ERROR no field `1_` | ||
//~| ERROR suffixes on a tuple index | ||
// We need to put these into curly braces, otherwise only one of the | ||
// errors will be emitted and the others suppressed. | ||
{ builtin # offset_of((u8, u8), +1) }; //~ ERROR expected identifier, found `+` | ||
{ builtin # offset_of((u8, u8), 1.) }; //~ ERROR expected identifier, found `)` | ||
{ builtin # offset_of((u8, u8), 1 .) }; //~ ERROR expected identifier, found `)` | ||
} | ||
|
||
type ComplexTup = ((u8, (u8, u8)), u8); | ||
|
||
fn nested() { | ||
offset_of!(((u8, u16), (u32, u16, u8)), 0.2); //~ ERROR no field `2` | ||
offset_of!(((u8, u16), (u32, u16, u8)), 1.2); | ||
offset_of!(((u8, u16), (u32, u16, u8)), 1.2.0); //~ ERROR no field `0` | ||
|
||
// All combinations of spaces (this sends different tokens to the parser) | ||
offset_of!(ComplexTup, 0.0.1.); //~ ERROR expected identifier | ||
offset_of!(ComplexTup, 0 .0.1.); //~ ERROR unexpected end of macro | ||
offset_of!(ComplexTup, 0 . 0.1.); //~ ERROR unexpected end of macro | ||
offset_of!(ComplexTup, 0. 0.1.); //~ ERROR no rules expected | ||
offset_of!(ComplexTup, 0.0 .1.); //~ ERROR expected identifier, found `)` | ||
offset_of!(ComplexTup, 0.0 . 1.); //~ ERROR expected identifier, found `)` | ||
offset_of!(ComplexTup, 0.0. 1.); //~ ERROR expected identifier, found `)` | ||
|
||
// Test for builtin too to ensure that the builtin syntax can also handle these cases | ||
// We need to put these into curly braces, otherwise only one of the | ||
// errors will be emitted and the others suppressed. | ||
{ builtin # offset_of(ComplexTup, 0.0.1.) }; //~ ERROR expected identifier, found `)` | ||
{ builtin # offset_of(ComplexTup, 0 .0.1.) }; //~ ERROR expected identifier, found `)` | ||
{ builtin # offset_of(ComplexTup, 0 . 0.1.) }; //~ ERROR expected identifier, found `)` | ||
{ builtin # offset_of(ComplexTup, 0. 0.1.) }; //~ ERROR expected identifier, found `)` | ||
{ builtin # offset_of(ComplexTup, 0.0 .1.) }; //~ ERROR expected identifier, found `)` | ||
{ builtin # offset_of(ComplexTup, 0.0 . 1.) }; //~ ERROR expected identifier, found `)` | ||
{ builtin # offset_of(ComplexTup, 0.0. 1.) }; //~ ERROR expected identifier, found `)` | ||
} |
Oops, something went wrong.