Skip to content

Commit 939c2b6

Browse files
committed
Provide suggestion on missing let in binding statement
Fix #78907.
1 parent 7308c22 commit 939c2b6

File tree

4 files changed

+53
-3
lines changed

4 files changed

+53
-3
lines changed

compiler/rustc_ast_passes/src/feature_gate.rs

+27-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use rustc_ast as ast;
22
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
33
use rustc_ast::{AssocConstraint, AssocConstraintKind, NodeId};
44
use rustc_ast::{PatKind, RangeEnd, VariantData};
5-
use rustc_errors::struct_span_err;
5+
use rustc_errors::{struct_span_err, Applicability};
66
use rustc_feature::{AttributeGate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
77
use rustc_feature::{Features, GateIssue};
88
use rustc_session::parse::{feature_err, feature_err_issue};
@@ -577,6 +577,32 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
577577
}
578578
}
579579

580+
fn visit_stmt(&mut self, stmt: &'a ast::Stmt) {
581+
if let ast::StmtKind::Semi(expr) = &stmt.kind
582+
&& let ast::ExprKind::Assign(lhs, _, _) = &expr.kind
583+
&& let ast::ExprKind::Type(..) = lhs.kind
584+
&& self.sess.parse_sess.span_diagnostic.err_count() == 0
585+
&& !self.features.type_ascription
586+
&& !lhs.span.allows_unstable(sym::type_ascription)
587+
{
588+
// When we encounter a statement of the form `foo: Ty = val;`, this will emit a type
589+
// ascription error, but the likely intention was to write a `let` statement. (#78907).
590+
feature_err_issue(
591+
&self.sess.parse_sess,
592+
sym::type_ascription,
593+
lhs.span,
594+
GateIssue::Language,
595+
"type ascription is experimental",
596+
).span_suggestion_verbose(
597+
lhs.span.shrink_to_lo(),
598+
"you might have meant to introduce a new binding",
599+
"let ".to_string(),
600+
Applicability::MachineApplicable,
601+
).emit();
602+
}
603+
visit::walk_stmt(self, stmt);
604+
}
605+
580606
fn visit_expr(&mut self, e: &'a ast::Expr) {
581607
match e.kind {
582608
ast::ExprKind::Box(_) => {
@@ -795,8 +821,6 @@ fn maybe_stage_features(sess: &Session, krate: &ast::Crate) {
795821
// checks if `#![feature]` has been used to enable any lang feature
796822
// does not check the same for lib features unless there's at least one
797823
// declared lang feature
798-
use rustc_errors::Applicability;
799-
800824
if !sess.opts.unstable_features.is_nightly_build() {
801825
let lang_features = &sess.features_untracked().declared_lang_features;
802826
if lang_features.len() == 0 {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// run-rustfix
2+
fn main() {
3+
let mut _foo: i32 = 1;
4+
let _foo: i32 = 4; //~ ERROR type ascription is experimental
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// run-rustfix
2+
fn main() {
3+
let mut _foo: i32 = 1;
4+
_foo: i32 = 4; //~ ERROR type ascription is experimental
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0658]: type ascription is experimental
2+
--> $DIR/missing-let-in-binding.rs:4:5
3+
|
4+
LL | _foo: i32 = 4;
5+
| ^^^^^^^^^
6+
|
7+
= note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
8+
= help: add `#![feature(type_ascription)]` to the crate attributes to enable
9+
help: you might have meant to introduce a new binding
10+
|
11+
LL | let _foo: i32 = 4;
12+
| +++
13+
14+
error: aborting due to previous error
15+
16+
For more information about this error, try `rustc --explain E0658`.

0 commit comments

Comments
 (0)