Rollup merge of #112475 - chenyukang:yukang-fix-112278, r=compiler-errors
Fix issue for module name when surround the struct literal with parentheses Fixes #112278
This commit is contained in:
commit
e19a509f8f
6 changed files with 113 additions and 9 deletions
|
@ -695,7 +695,7 @@ parse_struct_literal_body_without_path =
|
||||||
|
|
||||||
parse_struct_literal_needing_parens =
|
parse_struct_literal_needing_parens =
|
||||||
invalid struct literal
|
invalid struct literal
|
||||||
.suggestion = you might need to surround the struct literal in parentheses
|
.suggestion = you might need to surround the struct literal with parentheses
|
||||||
|
|
||||||
parse_struct_literal_not_allowed_here = struct literals are not allowed here
|
parse_struct_literal_not_allowed_here = struct literals are not allowed here
|
||||||
.suggestion = surround the struct literal with parentheses
|
.suggestion = surround the struct literal with parentheses
|
||||||
|
|
|
@ -751,13 +751,24 @@ impl<'a> Parser<'a> {
|
||||||
tail.could_be_bare_literal = true;
|
tail.could_be_bare_literal = true;
|
||||||
if maybe_struct_name.is_ident() && can_be_struct_literal {
|
if maybe_struct_name.is_ident() && can_be_struct_literal {
|
||||||
// Account for `if Example { a: one(), }.is_pos() {}`.
|
// Account for `if Example { a: one(), }.is_pos() {}`.
|
||||||
Err(self.sess.create_err(StructLiteralNeedingParens {
|
// expand `before` so that we take care of module path such as:
|
||||||
span: maybe_struct_name.span.to(expr.span),
|
// `foo::Bar { ... } `
|
||||||
sugg: StructLiteralNeedingParensSugg {
|
// we expect to suggest `(foo::Bar { ... })` instead of `foo::(Bar { ... })`
|
||||||
before: maybe_struct_name.span.shrink_to_lo(),
|
let sm = self.sess.source_map();
|
||||||
after: expr.span.shrink_to_hi(),
|
let before = maybe_struct_name.span.shrink_to_lo();
|
||||||
},
|
if let Ok(extend_before) = sm.span_extend_prev_while(before, |t| {
|
||||||
}))
|
t.is_alphanumeric() || t == ':' || t == '_'
|
||||||
|
}) {
|
||||||
|
Err(self.sess.create_err(StructLiteralNeedingParens {
|
||||||
|
span: maybe_struct_name.span.to(expr.span),
|
||||||
|
sugg: StructLiteralNeedingParensSugg {
|
||||||
|
before: extend_before.shrink_to_lo(),
|
||||||
|
after: expr.span.shrink_to_hi(),
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.sess.emit_err(StructLiteralBodyWithoutPath {
|
self.sess.emit_err(StructLiteralBodyWithoutPath {
|
||||||
span: expr.span,
|
span: expr.span,
|
||||||
|
|
|
@ -744,6 +744,21 @@ impl SourceMap {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extends the given `Span` to previous character while the previous character matches the predicate
|
||||||
|
pub fn span_extend_prev_while(
|
||||||
|
&self,
|
||||||
|
span: Span,
|
||||||
|
f: impl Fn(char) -> bool,
|
||||||
|
) -> Result<Span, SpanSnippetError> {
|
||||||
|
self.span_to_source(span, |s, start, _end| {
|
||||||
|
let n = s[..start]
|
||||||
|
.char_indices()
|
||||||
|
.rfind(|&(_, c)| !f(c))
|
||||||
|
.map_or(start, |(i, _)| start - i - 1);
|
||||||
|
Ok(span.with_lo(span.lo() - BytePos(n as u32)))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Extends the given `Span` to just before the next occurrence of `c`.
|
/// Extends the given `Span` to just before the next occurrence of `c`.
|
||||||
pub fn span_extend_to_next_char(&self, sp: Span, c: char, accept_newlines: bool) -> Span {
|
pub fn span_extend_to_next_char(&self, sp: Span, c: char, accept_newlines: bool) -> Span {
|
||||||
if let Ok(next_source) = self.span_to_next_source(sp) {
|
if let Ok(next_source) = self.span_to_next_source(sp) {
|
||||||
|
|
32
tests/ui/parser/issues/issue-111692.rs
Normal file
32
tests/ui/parser/issues/issue-111692.rs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
mod module {
|
||||||
|
#[derive(Eq, PartialEq)]
|
||||||
|
pub struct Type {
|
||||||
|
pub x: u8,
|
||||||
|
pub y: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const C: u8 = 32u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test(x: module::Type) {
|
||||||
|
if x == module::Type { x: module::C, y: 1 } { //~ ERROR invalid struct literal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test2(x: module::Type) {
|
||||||
|
if x ==module::Type { x: module::C, y: 1 } { //~ ERROR invalid struct literal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn test3(x: module::Type) {
|
||||||
|
if x == Type { x: module::C, y: 1 } { //~ ERROR invalid struct literal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test4(x: module::Type) {
|
||||||
|
if x == demo_module::Type { x: module::C, y: 1 } { //~ ERROR invalid struct literal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() { }
|
46
tests/ui/parser/issues/issue-111692.stderr
Normal file
46
tests/ui/parser/issues/issue-111692.stderr
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
error: invalid struct literal
|
||||||
|
--> $DIR/issue-111692.rs:12:21
|
||||||
|
|
|
||||||
|
LL | if x == module::Type { x: module::C, y: 1 } {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: you might need to surround the struct literal with parentheses
|
||||||
|
|
|
||||||
|
LL | if x == (module::Type { x: module::C, y: 1 }) {
|
||||||
|
| + +
|
||||||
|
|
||||||
|
error: invalid struct literal
|
||||||
|
--> $DIR/issue-111692.rs:17:20
|
||||||
|
|
|
||||||
|
LL | if x ==module::Type { x: module::C, y: 1 } {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: you might need to surround the struct literal with parentheses
|
||||||
|
|
|
||||||
|
LL | if x ==(module::Type { x: module::C, y: 1 }) {
|
||||||
|
| + +
|
||||||
|
|
||||||
|
error: invalid struct literal
|
||||||
|
--> $DIR/issue-111692.rs:23:13
|
||||||
|
|
|
||||||
|
LL | if x == Type { x: module::C, y: 1 } {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: you might need to surround the struct literal with parentheses
|
||||||
|
|
|
||||||
|
LL | if x == (Type { x: module::C, y: 1 }) {
|
||||||
|
| + +
|
||||||
|
|
||||||
|
error: invalid struct literal
|
||||||
|
--> $DIR/issue-111692.rs:28:26
|
||||||
|
|
|
||||||
|
LL | if x == demo_module::Type { x: module::C, y: 1 } {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: you might need to surround the struct literal with parentheses
|
||||||
|
|
|
||||||
|
LL | if x == (demo_module::Type { x: module::C, y: 1 }) {
|
||||||
|
| + +
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
|
@ -4,7 +4,7 @@ error: invalid struct literal
|
||||||
LL | if Example { a: one(), }.is_pos() {
|
LL | if Example { a: one(), }.is_pos() {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
help: you might need to surround the struct literal in parentheses
|
help: you might need to surround the struct literal with parentheses
|
||||||
|
|
|
|
||||||
LL | if (Example { a: one(), }).is_pos() {
|
LL | if (Example { a: one(), }).is_pos() {
|
||||||
| + +
|
| + +
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue