Skip to content

Commit 8fefdd5

Browse files
Deprecate set Keyword (#2062)
Makes the `set` keyword optional for assignment expressions. Adds a lint and code action to deprecate the use of the `set` keyword. The lint level is set to "Allow". Closes #1496
1 parent 8f28aa9 commit 8fefdd5

File tree

9 files changed

+597
-136
lines changed

9 files changed

+597
-136
lines changed

compiler/qsc_linter/src/linter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub fn run_lints(
2626
compile_unit,
2727
};
2828

29-
let mut ast_lints = run_ast_lints(&compile_unit.ast.package, config);
29+
let mut ast_lints = run_ast_lints(&compile_unit.ast.package, config, compilation);
3030
let mut hir_lints = run_hir_lints(&compile_unit.package, config, compilation);
3131

3232
let mut lints = Vec::new();

compiler/qsc_linter/src/linter/ast.rs

Lines changed: 106 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ use qsc_ast::{
1616
/// The entry point to the AST linter. It takes a [`qsc_ast::ast::Package`]
1717
/// as input and outputs a [`Vec<Lint>`](Lint).
1818
#[must_use]
19-
pub fn run_ast_lints(package: &qsc_ast::ast::Package, config: Option<&[LintConfig]>) -> Vec<Lint> {
19+
pub fn run_ast_lints(
20+
package: &qsc_ast::ast::Package,
21+
config: Option<&[LintConfig]>,
22+
compilation: Compilation,
23+
) -> Vec<Lint> {
2024
let config: Vec<(AstLint, LintLevel)> = config
2125
.unwrap_or(&[])
2226
.iter()
@@ -29,7 +33,7 @@ pub fn run_ast_lints(package: &qsc_ast::ast::Package, config: Option<&[LintConfi
2933
})
3034
.collect();
3135

32-
let mut lints = CombinedAstLints::from_config(config);
36+
let mut lints = CombinedAstLints::from_config(config, compilation);
3337

3438
for node in &package.nodes {
3539
match node {
@@ -46,23 +50,71 @@ pub fn run_ast_lints(package: &qsc_ast::ast::Package, config: Option<&[LintConfi
4650
/// The trait provides default empty implementations for the rest of the methods,
4751
/// which will be optimized to a no-op by the rust compiler.
4852
pub(crate) trait AstLintPass {
49-
fn check_attr(&self, _attr: &Attr, _buffer: &mut Vec<Lint>) {}
50-
fn check_block(&self, _block: &Block, _buffer: &mut Vec<Lint>) {}
51-
fn check_callable_decl(&self, _callable_decl: &CallableDecl, _buffer: &mut Vec<Lint>) {}
52-
fn check_expr(&self, _expr: &Expr, _buffer: &mut Vec<Lint>) {}
53-
fn check_functor_expr(&self, _functor_expr: &FunctorExpr, _buffer: &mut Vec<Lint>) {}
54-
fn check_ident(&self, _ident: &Ident, _buffer: &mut Vec<Lint>) {}
55-
fn check_item(&self, _item: &Item, _buffer: &mut Vec<Lint>) {}
56-
fn check_namespace(&self, _namespace: &Namespace, _buffer: &mut Vec<Lint>) {}
57-
fn check_package(&self, _package: &Package, _buffer: &mut Vec<Lint>) {}
58-
fn check_pat(&self, _pat: &Pat, _buffer: &mut Vec<Lint>) {}
59-
fn check_path(&self, _path: &Path, _buffer: &mut Vec<Lint>) {}
60-
fn check_path_kind(&self, _path: &PathKind, _buffer: &mut Vec<Lint>) {}
61-
fn check_qubit_init(&self, _qubit_init: &QubitInit, _buffer: &mut Vec<Lint>) {}
62-
fn check_spec_decl(&self, _spec_decl: &SpecDecl, _buffer: &mut Vec<Lint>) {}
63-
fn check_stmt(&self, _stmt: &Stmt, _buffer: &mut Vec<Lint>) {}
64-
fn check_ty(&self, _ty: &Ty, _buffer: &mut Vec<Lint>) {}
65-
fn check_ty_def(&self, _ty_def: &TyDef, _buffer: &mut Vec<Lint>) {}
53+
fn check_attr(&mut self, _attr: &Attr, _buffer: &mut Vec<Lint>, _compilation: Compilation) {}
54+
fn check_block(&mut self, _block: &Block, _buffer: &mut Vec<Lint>, _compilation: Compilation) {}
55+
fn check_callable_decl(
56+
&mut self,
57+
_callable_decl: &CallableDecl,
58+
_buffer: &mut Vec<Lint>,
59+
_compilation: Compilation,
60+
) {
61+
}
62+
fn check_expr(&mut self, _expr: &Expr, _buffer: &mut Vec<Lint>, _compilation: Compilation) {}
63+
fn check_functor_expr(
64+
&mut self,
65+
_functor_expr: &FunctorExpr,
66+
_buffer: &mut Vec<Lint>,
67+
_compilation: Compilation,
68+
) {
69+
}
70+
fn check_ident(&mut self, _ident: &Ident, _buffer: &mut Vec<Lint>, _compilation: Compilation) {}
71+
fn check_item(&mut self, _item: &Item, _buffer: &mut Vec<Lint>, _compilation: Compilation) {}
72+
fn check_namespace(
73+
&mut self,
74+
_namespace: &Namespace,
75+
_buffer: &mut Vec<Lint>,
76+
_compilation: Compilation,
77+
) {
78+
}
79+
fn check_package(
80+
&mut self,
81+
_package: &Package,
82+
_buffer: &mut Vec<Lint>,
83+
_compilation: Compilation,
84+
) {
85+
}
86+
fn check_pat(&mut self, _pat: &Pat, _buffer: &mut Vec<Lint>, _compilation: Compilation) {}
87+
fn check_path(&mut self, _path: &Path, _buffer: &mut Vec<Lint>, _compilation: Compilation) {}
88+
fn check_path_kind(
89+
&mut self,
90+
_path: &PathKind,
91+
_buffer: &mut Vec<Lint>,
92+
_compilation: Compilation,
93+
) {
94+
}
95+
fn check_qubit_init(
96+
&mut self,
97+
_qubit_init: &QubitInit,
98+
_buffer: &mut Vec<Lint>,
99+
_compilation: Compilation,
100+
) {
101+
}
102+
fn check_spec_decl(
103+
&mut self,
104+
_spec_decl: &SpecDecl,
105+
_buffer: &mut Vec<Lint>,
106+
_compilation: Compilation,
107+
) {
108+
}
109+
fn check_stmt(&mut self, _stmt: &Stmt, _buffer: &mut Vec<Lint>, _compilation: Compilation) {}
110+
fn check_ty(&mut self, _ty: &Ty, _buffer: &mut Vec<Lint>, _compilation: Compilation) {}
111+
fn check_ty_def(
112+
&mut self,
113+
_ty_def: &TyDef,
114+
_buffer: &mut Vec<Lint>,
115+
_compilation: Compilation,
116+
) {
117+
}
66118
}
67119

68120
/// This macro allow us to declare lints while avoiding boilerplate. It does three things:
@@ -82,7 +134,7 @@ macro_rules! declare_ast_lints {
82134
// This is a silly wrapper module to avoid contaminating the environment
83135
// calling the macro with unwanted imports.
84136
mod _ast_macro_expansion {
85-
use crate::{linter::ast::{declare_ast_lints, AstLintPass}, Lint, LintLevel};
137+
use crate::{linter::Compilation, linter::ast::{declare_ast_lints, AstLintPass}, Lint, LintLevel};
86138
use qsc_ast::{
87139
ast::{
88140
Attr, Block, CallableDecl, Expr, FunctorExpr, Ident, Item, Namespace, Package, Pat, Path, PathKind,
@@ -106,25 +158,14 @@ macro_rules! declare_ast_lints {
106158

107159
// Declare & implement a struct representing a lint.
108160
(@LINT_STRUCT $lint_name:ident, $default_level:expr, $msg:expr, $help:expr) => {
109-
pub(crate) struct $lint_name {
110-
level: LintLevel,
111-
}
112-
113-
impl Default for $lint_name {
114-
fn default() -> Self {
115-
Self { level: Self::DEFAULT_LEVEL }
116-
}
117-
}
118-
119-
impl From<LintLevel> for $lint_name {
120-
fn from(value: LintLevel) -> Self {
121-
Self { level: value }
122-
}
123-
}
124-
125161
impl $lint_name {
126162
const DEFAULT_LEVEL: LintLevel = $default_level;
127163

164+
fn new() -> Self {
165+
#[allow(clippy::needless_update)]
166+
Self { level: Self::DEFAULT_LEVEL, ..Default::default() }
167+
}
168+
128169
const fn lint_kind(&self) -> LintKind {
129170
LintKind::Ast(AstLint::$lint_name)
130171
}
@@ -164,24 +205,26 @@ macro_rules! declare_ast_lints {
164205
/// Combined AST lints for speed. This combined lint allow us to
165206
/// evaluate all the lints in a single AST pass, instead of doing
166207
/// an individual pass for each lint in the linter.
167-
pub(crate) struct CombinedAstLints {
208+
pub(crate) struct CombinedAstLints<'compilation> {
168209
pub buffer: Vec<Lint>,
210+
pub compilation: Compilation<'compilation>,
169211
$($lint_name: $lint_name),*
170212
}
171213

172-
impl Default for CombinedAstLints {
173-
fn default() -> Self {
214+
impl<'compilation> CombinedAstLints<'compilation> {
215+
fn new(compilation: Compilation<'compilation>) -> Self {
174216
Self {
175-
buffer: Vec::default(),
176-
$($lint_name: <$lint_name>::default()),*
217+
buffer: Vec::new(),
218+
compilation,
219+
$($lint_name: <$lint_name>::new()),*
177220
}
178221
}
179222
}
180223

181224
// Most of the calls here are empty methods and they get optimized at compile time to a no-op.
182-
impl CombinedAstLints {
183-
pub fn from_config(config: Vec<(AstLint, LintLevel)>) -> Self {
184-
let mut combined_ast_lints = Self::default();
225+
impl<'compilation> CombinedAstLints<'compilation> {
226+
pub fn from_config(config: Vec<(AstLint, LintLevel)>, compilation: Compilation<'compilation>) -> Self {
227+
let mut combined_ast_lints = Self::new(compilation);
185228
for (lint, level) in config {
186229
match lint {
187230
$(AstLint::$lint_name => combined_ast_lints.$lint_name.level = level),*
@@ -190,26 +233,26 @@ macro_rules! declare_ast_lints {
190233
combined_ast_lints
191234
}
192235

193-
fn check_package(&mut self, package: &Package) { $(self.$lint_name.check_package(package, &mut self.buffer));*; }
194-
fn check_namespace(&mut self, namespace: &Namespace) { $(self.$lint_name.check_namespace(namespace, &mut self.buffer));*; }
195-
fn check_item(&mut self, item: &Item) { $(self.$lint_name.check_item(item, &mut self.buffer));*; }
196-
fn check_attr(&mut self, attr: &Attr) { $(self.$lint_name.check_attr(attr, &mut self.buffer));*; }
197-
fn check_ty_def(&mut self, def: &TyDef) { $(self.$lint_name.check_ty_def(def, &mut self.buffer));*; }
198-
fn check_callable_decl(&mut self, decl: &CallableDecl) { $(self.$lint_name.check_callable_decl(decl, &mut self.buffer));*; }
199-
fn check_spec_decl(&mut self, decl: &SpecDecl) { $(self.$lint_name.check_spec_decl(decl, &mut self.buffer));*; }
200-
fn check_functor_expr(&mut self, expr: &FunctorExpr) { $(self.$lint_name.check_functor_expr(expr, &mut self.buffer));*; }
201-
fn check_ty(&mut self, ty: &Ty) { $(self.$lint_name.check_ty(ty, &mut self.buffer));*; }
202-
fn check_block(&mut self, block: &Block) { $(self.$lint_name.check_block(block, &mut self.buffer));*; }
203-
fn check_stmt(&mut self, stmt: &Stmt) { $(self.$lint_name.check_stmt(stmt, &mut self.buffer));*; }
204-
fn check_expr(&mut self, expr: &Expr) { $(self.$lint_name.check_expr(expr, &mut self.buffer));*; }
205-
fn check_pat(&mut self, pat: &Pat) { $(self.$lint_name.check_pat(pat, &mut self.buffer));*; }
206-
fn check_qubit_init(&mut self, init: &QubitInit) { $(self.$lint_name.check_qubit_init(init, &mut self.buffer));*; }
207-
fn check_path(&mut self, path: &Path) { $(self.$lint_name.check_path(path, &mut self.buffer));*; }
208-
fn check_path_kind(&mut self, path: &PathKind) { $(self.$lint_name.check_path_kind(path, &mut self.buffer));*; }
209-
fn check_ident(&mut self, ident: &Ident) { $(self.$lint_name.check_ident(ident, &mut self.buffer));*; }
236+
fn check_package(&mut self, package: &Package) { $(self.$lint_name.check_package(package, &mut self.buffer, self.compilation));*; }
237+
fn check_namespace(&mut self, namespace: &Namespace) { $(self.$lint_name.check_namespace(namespace, &mut self.buffer, self.compilation));*; }
238+
fn check_item(&mut self, item: &Item) { $(self.$lint_name.check_item(item, &mut self.buffer, self.compilation));*; }
239+
fn check_attr(&mut self, attr: &Attr) { $(self.$lint_name.check_attr(attr, &mut self.buffer, self.compilation));*; }
240+
fn check_ty_def(&mut self, def: &TyDef) { $(self.$lint_name.check_ty_def(def, &mut self.buffer, self.compilation));*; }
241+
fn check_callable_decl(&mut self, decl: &CallableDecl) { $(self.$lint_name.check_callable_decl(decl, &mut self.buffer, self.compilation));*; }
242+
fn check_spec_decl(&mut self, decl: &SpecDecl) { $(self.$lint_name.check_spec_decl(decl, &mut self.buffer, self.compilation));*; }
243+
fn check_functor_expr(&mut self, expr: &FunctorExpr) { $(self.$lint_name.check_functor_expr(expr, &mut self.buffer, self.compilation));*; }
244+
fn check_ty(&mut self, ty: &Ty) { $(self.$lint_name.check_ty(ty, &mut self.buffer, self.compilation));*; }
245+
fn check_block(&mut self, block: &Block) { $(self.$lint_name.check_block(block, &mut self.buffer, self.compilation));*; }
246+
fn check_stmt(&mut self, stmt: &Stmt) { $(self.$lint_name.check_stmt(stmt, &mut self.buffer, self.compilation));*; }
247+
fn check_expr(&mut self, expr: &Expr) { $(self.$lint_name.check_expr(expr, &mut self.buffer, self.compilation));*; }
248+
fn check_pat(&mut self, pat: &Pat) { $(self.$lint_name.check_pat(pat, &mut self.buffer, self.compilation));*; }
249+
fn check_qubit_init(&mut self, init: &QubitInit) { $(self.$lint_name.check_qubit_init(init, &mut self.buffer, self.compilation));*; }
250+
fn check_path(&mut self, path: &Path) { $(self.$lint_name.check_path(path, &mut self.buffer, self.compilation));*; }
251+
fn check_path_kind(&mut self, path: &PathKind) { $(self.$lint_name.check_path_kind(path, &mut self.buffer, self.compilation));*; }
252+
fn check_ident(&mut self, ident: &Ident) { $(self.$lint_name.check_ident(ident, &mut self.buffer, self.compilation));*; }
210253
}
211254

212-
impl<'a> Visitor<'a> for CombinedAstLints {
255+
impl<'a> Visitor<'a> for CombinedAstLints<'_> {
213256
fn visit_package(&mut self, package: &'a Package) {
214257
self.check_package(package);
215258
visit::walk_package(self, package);
@@ -299,4 +342,4 @@ macro_rules! declare_ast_lints {
299342

300343
pub(crate) use declare_ast_lints;
301344

302-
use super::LintKind;
345+
use super::{Compilation, LintKind};

0 commit comments

Comments
 (0)