diag(wgsl-in): use backticks for code-like text in WGSL FE errors (#6908)

This commit is contained in:
Erich Gubler
2025-01-13 17:13:40 -05:00
committed by GitHub
parent cc741735df
commit 1963eb7c3f
2 changed files with 70 additions and 70 deletions

View File

@@ -359,22 +359,22 @@ impl<'a> Error<'a> {
Error::Unexpected(unexpected_span, expected) => {
let expected_str = match expected {
ExpectedToken::Token(token) => match token {
Token::Separator(c) => format!("'{c}'"),
Token::Paren(c) => format!("'{c}'"),
Token::Separator(c) => format!("`{c}`"),
Token::Paren(c) => format!("`{c}`"),
Token::Attribute => "@".to_string(),
Token::Number(_) => "number".to_string(),
Token::Word(s) => s.to_string(),
Token::Operation(c) => format!("operation ('{c}')"),
Token::LogicalOperation(c) => format!("logical operation ('{c}')"),
Token::ShiftOperation(c) => format!("bitshift ('{c}{c}')"),
Token::Operation(c) => format!("operation (`{c}`)"),
Token::LogicalOperation(c) => format!("logical operation (`{c}`)"),
Token::ShiftOperation(c) => format!("bitshift (`{c}{c}`)"),
Token::AssignmentOperation(c) if c == '<' || c == '>' => {
format!("bitshift ('{c}{c}=')")
format!("bitshift (`{c}{c}=`)")
}
Token::AssignmentOperation(c) => format!("operation ('{c}=')"),
Token::AssignmentOperation(c) => format!("operation (`{c}=`)"),
Token::IncrementOperation => "increment operation".to_string(),
Token::DecrementOperation => "decrement operation".to_string(),
Token::Arrow => "->".to_string(),
Token::Unknown(c) => format!("unknown ('{c}')"),
Token::Unknown(c) => format!("unknown (`{c}`)"),
Token::Trivia => "trivia".to_string(),
Token::End => "end".to_string(),
},
@@ -382,15 +382,15 @@ impl<'a> Error<'a> {
ExpectedToken::PrimaryExpression => "expression".to_string(),
ExpectedToken::Assignment => "assignment or increment/decrement".to_string(),
ExpectedToken::SwitchItem => concat!(
"switch item ('case' or 'default') or a closing curly bracket ",
"to signify the end of the switch statement ('}')"
"switch item (`case` or `default`) or a closing curly bracket ",
"to signify the end of the switch statement (`}`)"
)
.to_string(),
ExpectedToken::WorkgroupSizeSeparator => {
"workgroup size separator (',') or a closing parenthesis".to_string()
"workgroup size separator (`,`) or a closing parenthesis".to_string()
}
ExpectedToken::GlobalItem => concat!(
"global item ('struct', 'const', 'var', 'alias', 'fn', 'diagnostic', 'enable', 'requires', ';') ",
"global item (`struct`, `const`, `var`, `alias`, `fn`, `diagnostic`, `enable`, `requires`, `;`) ",
"or the end of the file"
)
.to_string(),
@@ -398,13 +398,13 @@ impl<'a> Error<'a> {
ExpectedToken::Variable => "variable access".to_string(),
ExpectedToken::Function => "function name".to_string(),
ExpectedToken::AfterIdentListArg => {
"next argument, trailing comma, or end of list (',' or ';')".to_string()
"next argument, trailing comma, or end of list (`,` or `;`)".to_string()
}
ExpectedToken::AfterIdentListComma => {
"next argument or end of list (';')".to_string()
"next argument or end of list (`;`)".to_string()
}
ExpectedToken::DiagnosticAttribute => {
"the 'diagnostic' attribute identifier".to_string()
"the `diagnostic` attribute identifier".to_string()
}
};
ParseError {
@@ -445,12 +445,12 @@ impl<'a> Error<'a> {
notes: vec![],
},
Error::UnknownIdent(ident_span, ident) => ParseError {
message: format!("no definition in scope for identifier: '{ident}'"),
message: format!("no definition in scope for identifier: `{ident}`"),
labels: vec![(ident_span, "unknown identifier".into())],
notes: vec![],
},
Error::UnknownScalarType(bad_span) => ParseError {
message: format!("unknown scalar type: '{}'", &source[bad_span]),
message: format!("unknown scalar type: `{}`", &source[bad_span]),
labels: vec![(bad_span, "unknown scalar type".into())],
notes: vec!["Valid scalar types are f32, f64, i32, u32, bool".into()],
},
@@ -473,7 +473,7 @@ impl<'a> Error<'a> {
},
Error::BadTexture(bad_span) => ParseError {
message: format!(
"expected an image, but found '{}' which is not an image",
"expected an image, but found `{}` which is not an image",
&source[bad_span]
),
labels: vec![(bad_span, "not an image".into())],
@@ -498,7 +498,7 @@ impl<'a> Error<'a> {
},
Error::InvalidForInitializer(bad_span) => ParseError {
message: format!(
"for(;;) initializer is not an assignment or a function call: '{}'",
"for(;;) initializer is not an assignment or a function call: `{}`",
&source[bad_span]
),
labels: vec![(bad_span, "not an assignment or function call".into())],
@@ -511,7 +511,7 @@ impl<'a> Error<'a> {
},
Error::InvalidGatherComponent(bad_span) => ParseError {
message: format!(
"textureGather component '{}' doesn't exist, must be 0, 1, 2, or 3",
"textureGather component `{}` doesn't exist, must be 0, 1, 2, or 3",
&source[bad_span]
),
labels: vec![(bad_span, "invalid component".into())],
@@ -523,58 +523,58 @@ impl<'a> Error<'a> {
notes: vec![],
},
Error::InvalidIdentifierUnderscore(bad_span) => ParseError {
message: "Identifier can't be '_'".to_string(),
message: "Identifier can't be `_`".to_string(),
labels: vec![(bad_span, "invalid identifier".into())],
notes: vec![
"Use phony assignment instead ('_ =' notice the absence of 'let' or 'var')"
"Use phony assignment instead (`_ =` notice the absence of `let` or `var`)"
.to_string(),
],
},
Error::ReservedIdentifierPrefix(bad_span) => ParseError {
message: format!(
"Identifier starts with a reserved prefix: '{}'",
"Identifier starts with a reserved prefix: `{}`",
&source[bad_span]
),
labels: vec![(bad_span, "invalid identifier".into())],
notes: vec![],
},
Error::UnknownAddressSpace(bad_span) => ParseError {
message: format!("unknown address space: '{}'", &source[bad_span]),
message: format!("unknown address space: `{}`", &source[bad_span]),
labels: vec![(bad_span, "unknown address space".into())],
notes: vec![],
},
Error::RepeatedAttribute(bad_span) => ParseError {
message: format!("repeated attribute: '{}'", &source[bad_span]),
message: format!("repeated attribute: `{}`", &source[bad_span]),
labels: vec![(bad_span, "repeated attribute".into())],
notes: vec![],
},
Error::UnknownAttribute(bad_span) => ParseError {
message: format!("unknown attribute: '{}'", &source[bad_span]),
message: format!("unknown attribute: `{}`", &source[bad_span]),
labels: vec![(bad_span, "unknown attribute".into())],
notes: vec![],
},
Error::UnknownBuiltin(bad_span) => ParseError {
message: format!("unknown builtin: '{}'", &source[bad_span]),
message: format!("unknown builtin: `{}`", &source[bad_span]),
labels: vec![(bad_span, "unknown builtin".into())],
notes: vec![],
},
Error::UnknownAccess(bad_span) => ParseError {
message: format!("unknown access: '{}'", &source[bad_span]),
message: format!("unknown access: `{}`", &source[bad_span]),
labels: vec![(bad_span, "unknown access".into())],
notes: vec![],
},
Error::UnknownStorageFormat(bad_span) => ParseError {
message: format!("unknown storage format: '{}'", &source[bad_span]),
message: format!("unknown storage format: `{}`", &source[bad_span]),
labels: vec![(bad_span, "unknown storage format".into())],
notes: vec![],
},
Error::UnknownConservativeDepth(bad_span) => ParseError {
message: format!("unknown conservative depth: '{}'", &source[bad_span]),
message: format!("unknown conservative depth: `{}`", &source[bad_span]),
labels: vec![(bad_span, "unknown conservative depth".into())],
notes: vec![],
},
Error::UnknownType(bad_span) => ParseError {
message: format!("unknown type: '{}'", &source[bad_span]),
message: format!("unknown type: `{}`", &source[bad_span]),
labels: vec![(bad_span, "unknown type".into())],
notes: vec![],
},
@@ -702,7 +702,7 @@ impl<'a> Error<'a> {
InvalidAssignmentType::ImmutableBinding(binding_span) => (
Some((binding_span, "this is an immutable binding".into())),
vec![format!(
"consider declaring '{}' with `var` instead of `let`",
"consider declaring `{}` with `var` instead of `let`",
&source[binding_span]
)],
),
@@ -782,11 +782,11 @@ impl<'a> Error<'a> {
.into(),
)],
notes: vec![if uint {
format!("suffix the integer with a `u`: '{}u'", &source[span])
format!("suffix the integer with a `u`: `{}u`", &source[span])
} else {
let span = span.to_range().unwrap();
format!(
"remove the `u` suffix: '{}'",
"remove the `u` suffix: `{}`",
&source[span.start..span.end - 1]
)
}],
@@ -833,10 +833,10 @@ impl<'a> Error<'a> {
Error::ExpectedConstExprConcreteIntegerScalar(span) => ParseError {
message: concat!(
"must be a const-expression that ",
"resolves to a concrete integer scalar (u32 or i32)"
"resolves to a concrete integer scalar (`u32` or `i32`)"
)
.to_string(),
labels: vec![(span, "must resolve to u32 or i32".into())],
labels: vec![(span, "must resolve to `u32` or `i32`".into())],
notes: vec![],
},
Error::ExpectedNonNegative(span) => ParseError {
@@ -858,7 +858,7 @@ impl<'a> Error<'a> {
message: "workgroup size is missing on compute shader entry point".to_string(),
labels: vec![(
span,
"must be paired with a @workgroup_size attribute".into(),
"must be paired with a `@workgroup_size` attribute".into(),
)],
notes: vec![],
},
@@ -947,13 +947,13 @@ impl<'a> Error<'a> {
notes: vec![],
},
Error::NotBool(span) => ParseError {
message: "must be a const-expression that resolves to a bool".to_string(),
labels: vec![(span, "must resolve to bool".into())],
message: "must be a const-expression that resolves to a `bool`".to_string(),
labels: vec![(span, "must resolve to `bool`".into())],
notes: vec![],
},
Error::ConstAssertFailed(span) => ParseError {
message: "const_assert failure".to_string(),
labels: vec![(span, "evaluates to false".into())],
message: "`const_assert` failure".to_string(),
labels: vec![(span, "evaluates to `false`".into())],
notes: vec![],
},
Error::DirectiveAfterFirstGlobalDecl { directive_span } => ParseError {

View File

@@ -38,7 +38,7 @@ fn very_negative_integers() {
fn reserved_identifier_prefix() {
check(
"var __bad;",
r###"error: Identifier starts with a reserved prefix: '__bad'
r###"error: Identifier starts with a reserved prefix: `__bad`
┌─ wgsl:1:5
1 │ var __bad;
@@ -112,7 +112,7 @@ fn unknown_identifier() {
return x * schmoo;
}
"###,
r###"error: no definition in scope for identifier: 'schmoo'
r###"error: no definition in scope for identifier: `schmoo`
┌─ wgsl:3:30
3 │ return x * schmoo;
@@ -134,7 +134,7 @@ fn bad_texture() {
return textureSample(a, sampler1, vec2<f32>(0.0));
}
"#,
r#"error: expected an image, but found 'a' which is not an image
r#"error: expected an image, but found `a` which is not an image
┌─ wgsl:7:38
7 │ return textureSample(a, sampler1, vec2<f32>(0.0));
@@ -266,7 +266,7 @@ fn bad_for_initializer() {
for ({};;) {}
}
"#,
r#"error: for(;;) initializer is not an assignment or a function call: '{}'
r#"error: for(;;) initializer is not an assignment or a function call: `{}`
┌─ wgsl:3:22
3 │ for ({};;) {}
@@ -282,7 +282,7 @@ fn unknown_storage_class() {
r#"
@group(0) @binding(0) var<bad> texture: texture_2d<f32>;
"#,
r#"error: unknown address space: 'bad'
r#"error: unknown address space: `bad`
┌─ wgsl:2:39
2 │ @group(0) @binding(0) var<bad> texture: texture_2d<f32>;
@@ -299,7 +299,7 @@ fn unknown_attribute() {
@a
fn x() {}
"#,
r#"error: unknown attribute: 'a'
r#"error: unknown attribute: `a`
┌─ wgsl:2:14
2 │ @a
@@ -315,7 +315,7 @@ fn unknown_built_in() {
r#"
fn x(@builtin(unknown_built_in) y: u32) {}
"#,
r#"error: unknown builtin: 'unknown_built_in'
r#"error: unknown builtin: `unknown_built_in`
┌─ wgsl:2:27
2 │ fn x(@builtin(unknown_built_in) y: u32) {}
@@ -331,7 +331,7 @@ fn unknown_access() {
r#"
var<storage,unknown_access> x: array<u32>;
"#,
r#"error: unknown access: 'unknown_access'
r#"error: unknown access: `unknown_access`
┌─ wgsl:2:25
2 │ var<storage,unknown_access> x: array<u32>;
@@ -349,7 +349,7 @@ fn unknown_ident() {
let a = b;
}
"#,
r#"error: no definition in scope for identifier: 'b'
r#"error: no definition in scope for identifier: `b`
┌─ wgsl:3:25
3 │ let a = b;
@@ -365,7 +365,7 @@ fn unknown_scalar_type() {
r#"
const a = vec2<vec2f>();
"#,
r#"error: unknown scalar type: 'vec2f'
r#"error: unknown scalar type: `vec2f`
┌─ wgsl:2:28
2 │ const a = vec2<vec2f>();
@@ -383,7 +383,7 @@ fn unknown_type() {
r#"
const a: Vec = 10;
"#,
r#"error: unknown type: 'Vec'
r#"error: unknown type: `Vec`
┌─ wgsl:2:22
2 │ const a: Vec = 10;
@@ -399,7 +399,7 @@ fn unknown_storage_format() {
r#"
const storage1: texture_storage_1d<rgba>;
"#,
r#"error: unknown storage format: 'rgba'
r#"error: unknown storage format: `rgba`
┌─ wgsl:2:48
2 │ const storage1: texture_storage_1d<rgba>;
@@ -415,7 +415,7 @@ fn unknown_conservative_depth() {
r#"
@early_depth_test(abc) fn main() {}
"#,
r#"error: unknown conservative depth: 'abc'
r#"error: unknown conservative depth: `abc`
┌─ wgsl:2:31
2 │ @early_depth_test(abc) fn main() {}
@@ -503,7 +503,7 @@ fn unknown_local_function() {
for (a();;) {}
}
"#,
r#"error: no definition in scope for identifier: 'a'
r#"error: no definition in scope for identifier: `a`
┌─ wgsl:3:22
3 │ for (a();;) {}
@@ -1010,11 +1010,11 @@ fn invalid_arrays() {
check(
"alias Bad = array<f32, true>;",
r###"error: must be a const-expression that resolves to a concrete integer scalar (u32 or i32)
r###"error: must be a const-expression that resolves to a concrete integer scalar (`u32` or `i32`)
┌─ wgsl:1:24
1 │ alias Bad = array<f32, true>;
│ ^^^^ must resolve to u32 or i32
│ ^^^^ must resolve to `u32` or `i32`
"###,
);
@@ -1024,11 +1024,11 @@ fn invalid_arrays() {
const length: f32 = 2.718;
alias Bad = array<f32, length>;
"#,
r###"error: must be a const-expression that resolves to a concrete integer scalar (u32 or i32)
r###"error: must be a const-expression that resolves to a concrete integer scalar (`u32` or `i32`)
┌─ wgsl:3:36
3 │ alias Bad = array<f32, length>;
│ ^^^^^^ must resolve to u32 or i32
│ ^^^^^^ must resolve to `u32` or `i32`
"###,
);
@@ -1842,7 +1842,7 @@ fn assign_to_let() {
4 │ a = 20;
│ ^ cannot assign to this expression
= note: consider declaring 'a' with `var` instead of `let`
= note: consider declaring `a` with `var` instead of `let`
"###,
);
@@ -1862,7 +1862,7 @@ fn assign_to_let() {
4 │ a[0] = 1;
│ ^^^^ cannot assign to this expression
= note: consider declaring 'a' with `var` instead of `let`
= note: consider declaring `a` with `var` instead of `let`
"###,
);
@@ -1884,7 +1884,7 @@ fn assign_to_let() {
6 │ a.a = 20;
│ ^^^ cannot assign to this expression
= note: consider declaring 'a' with `var` instead of `let`
= note: consider declaring `a` with `var` instead of `let`
"###,
);
@@ -1954,7 +1954,7 @@ fn switch_signed_unsigned_mismatch() {
4 │ case 1: {}
│ ^ expected unsigned integer
= note: suffix the integer with a `u`: '1u'
= note: suffix the integer with a `u`: `1u`
"###,
);
@@ -1973,7 +1973,7 @@ fn switch_signed_unsigned_mismatch() {
4 │ case 1u: {}
│ ^^ expected signed integer
= note: remove the `u` suffix: '1'
= note: remove the `u` suffix: `1`
"###,
);
@@ -2407,11 +2407,11 @@ fn const_assert_must_be_bool() {
"
const_assert(5); // 5 is not bool
",
r###"error: must be a const-expression that resolves to a bool
r###"error: must be a const-expression that resolves to a `bool`
┌─ wgsl:2:26
2 │ const_assert(5); // 5 is not bool
│ ^ must resolve to bool
│ ^ must resolve to `bool`
"###,
);
@@ -2423,11 +2423,11 @@ fn const_assert_failed() {
"
const_assert(false);
",
r###"error: const_assert failure
r###"error: `const_assert` failure
┌─ wgsl:2:26
2 │ const_assert(false);
│ ^^^^^ evaluates to false
│ ^^^^^ evaluates to `false`
"###,
);
@@ -2437,11 +2437,11 @@ fn const_assert_failed() {
fn reject_utf8_bom() {
check(
"\u{FEFF}fn main() {}",
r#"error: expected global item ('struct', 'const', 'var', 'alias', 'fn', 'diagnostic', 'enable', 'requires', ';') or the end of the file, found "\u{feff}"
r#"error: expected global item (`struct`, `const`, `var`, `alias`, `fn`, `diagnostic`, `enable`, `requires`, `;`) or the end of the file, found "\u{feff}"
┌─ wgsl:1:1
1 │ fn main() {}
│ expected global item ('struct', 'const', 'var', 'alias', 'fn', 'diagnostic', 'enable', 'requires', ';') or the end of the file
│ expected global item (`struct`, `const`, `var`, `alias`, `fn`, `diagnostic`, `enable`, `requires`, `;`) or the end of the file
"#,
);