diff options
| author | bors <bors@rust-lang.org> | 2021-09-04 01:40:36 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-09-04 01:40:36 +0000 |
| commit | b4e8596e3e78395543747ebaba26b49f6a478aa8 (patch) | |
| tree | c782e430605f5b820e4c4aaa448493bf706eccd2 /compiler/rustc_resolve/src | |
| parent | 03c775c95596cbd92f2b1e8ca98e7addfa3eade2 (diff) | |
| parent | 12ce6e9c60c662dc7181b70021145f191c0f9f3e (diff) | |
| download | rust-b4e8596e3e78395543747ebaba26b49f6a478aa8.tar.gz rust-b4e8596e3e78395543747ebaba26b49f6a478aa8.zip | |
Auto merge of #88598 - estebank:type-ascription-can-die-in-a-fire, r=wesleywiser
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`.
Diffstat (limited to 'compiler/rustc_resolve/src')
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late/diagnostics.rs | 10 |
2 files changed, 26 insertions, 0 deletions
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 7b65ab2acf6..60573968361 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -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>)>, @@ -1871,6 +1876,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, @@ -2254,6 +2260,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 { @@ -2267,6 +2282,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; diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index d7cd34c5922..b2c0c787465 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -207,6 +207,16 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { let code = source.error_code(res.is_some()); let mut err = self.r.session.struct_span_err_with_code(base_span, &base_msg, code); + if let Some(span) = self.diagnostic_metadata.current_block_could_be_bare_struct_literal { + err.multipart_suggestion( + "you might have meant to write a `struct` literal", + vec![ + (span.shrink_to_lo(), "{ SomeStruct ".to_string()), + (span.shrink_to_hi(), "}".to_string()), + ], + Applicability::HasPlaceholders, + ); + } match (source, self.diagnostic_metadata.in_if_condition) { (PathSource::Expr(_), Some(Expr { span, kind: ExprKind::Assign(..), .. })) => { err.span_suggestion_verbose( |
