Detect bare blocks with type ascription that were meant to be a struct literal

Address part of #34255.

Potential improvement: silence the other knock down errors in
`issue-34255-1.rs`.
This commit is contained in:
Esteban Kuber
2021-09-02 18:34:03 +00:00
parent fcce644119
commit 12ce6e9c60
13 changed files with 67 additions and 5 deletions

View File

@@ -383,6 +383,11 @@ struct DiagnosticMetadata<'ast> {
/// Only used for better errors on `fn(): fn()`.
current_type_ascription: Vec<Span>,
/// Only used for better errors on `let x = { foo: bar };`.
/// In the case of a parse error with `let x = { foo: bar, };`, this isn't needed, it's only
/// needed for cases where this parses as a correct type ascription.
current_block_could_be_bare_struct_literal: Option<Span>,
/// Only used for better errors on `let <pat>: <expr, not type>;`.
current_let_binding: Option<(Span, Option<Span>, Option<Span>)>,
@@ -1859,6 +1864,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
let instead = res.is_some();
let suggestion =
if res.is_none() { this.report_missing_type_error(path) } else { None };
// get_from_node_id
this.r.use_injections.push(UseError {
err,
@@ -2242,6 +2248,15 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
self.ribs[ValueNS].push(Rib::new(NormalRibKind));
}
let prev = self.diagnostic_metadata.current_block_could_be_bare_struct_literal.take();
if let (true, [Stmt { kind: StmtKind::Expr(expr), .. }]) =
(block.could_be_bare_literal, &block.stmts[..])
{
if let ExprKind::Type(..) = expr.kind {
self.diagnostic_metadata.current_block_could_be_bare_struct_literal =
Some(block.span);
}
}
// Descend into the block.
for stmt in &block.stmts {
if let StmtKind::Item(ref item) = stmt.kind {
@@ -2255,6 +2270,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
self.visit_stmt(stmt);
}
self.diagnostic_metadata.current_block_could_be_bare_struct_literal = prev;
// Move back up.
self.parent_scope.module = orig_module;