Skip to content

Commit 7249a1b

Browse files
committed
Suggest valid crate type if invalid
This adds a suggestion to the `invalid_crate_types` lint. The suggestion is based on the Levenshtein distance to existing crate types. If no suggestion is found it will show the lint without any suggestions.
1 parent d8af8b6 commit 7249a1b

File tree

4 files changed

+143
-10
lines changed

4 files changed

+143
-10
lines changed

src/librustc/lint/builtin.rs

+9
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ pub enum BuiltinLintDiagnostics {
422422
ProcMacroDeriveResolutionFallback(Span),
423423
MacroExpandedMacroExportsAccessedByAbsolutePaths(Span),
424424
ElidedLifetimesInPaths(usize, Span, bool, Span, String),
425+
UnknownCrateTypes(Span, String, String),
425426
}
426427

427428
impl BuiltinLintDiagnostics {
@@ -500,6 +501,14 @@ impl BuiltinLintDiagnostics {
500501
Applicability::MachineApplicable
501502
);
502503
}
504+
BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => {
505+
db.span_suggestion_with_applicability(
506+
span,
507+
&note,
508+
sugg,
509+
Applicability::MaybeIncorrect
510+
);
511+
}
503512
}
504513
}
505514
}

src/librustc_driver/driver.rs

+41-7
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ use syntax::ext::base::ExtCtxt;
5757
use syntax::fold::Folder;
5858
use syntax::parse::{self, PResult};
5959
use syntax::util::node_count::NodeCounter;
60+
use syntax::util::lev_distance::find_best_match_for_name;
61+
use syntax::symbol::Symbol;
6062
use syntax_pos::{FileName, hygiene};
6163
use syntax_ext;
6264

@@ -1508,13 +1510,45 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
15081510
Some(ref n) if *n == "staticlib" => Some(config::CrateType::Staticlib),
15091511
Some(ref n) if *n == "proc-macro" => Some(config::CrateType::ProcMacro),
15101512
Some(ref n) if *n == "bin" => Some(config::CrateType::Executable),
1511-
Some(_) => {
1512-
session.buffer_lint(
1513-
lint::builtin::UNKNOWN_CRATE_TYPES,
1514-
ast::CRATE_NODE_ID,
1515-
a.span,
1516-
"invalid `crate_type` value",
1517-
);
1513+
Some(ref n) => {
1514+
let crate_types = vec![
1515+
Symbol::intern("rlib"),
1516+
Symbol::intern("dylib"),
1517+
Symbol::intern("cdylib"),
1518+
Symbol::intern("lib"),
1519+
Symbol::intern("staticlib"),
1520+
Symbol::intern("proc-macro"),
1521+
Symbol::intern("bin")
1522+
];
1523+
if let ast::MetaItemKind::NameValue(spanned) = a.meta().unwrap().node {
1524+
let span = spanned.span;
1525+
let lev_candidate = find_best_match_for_name(
1526+
crate_types.iter(),
1527+
&n.as_str(),
1528+
None
1529+
);
1530+
if let Some(candidate) = lev_candidate {
1531+
session.buffer_lint_with_diagnostic(
1532+
lint::builtin::UNKNOWN_CRATE_TYPES,
1533+
ast::CRATE_NODE_ID,
1534+
span,
1535+
"invalid `crate_type` value",
1536+
lint::builtin::BuiltinLintDiagnostics::
1537+
UnknownCrateTypes(
1538+
span,
1539+
"did you mean".to_string(),
1540+
format!("\"{}\"", candidate)
1541+
)
1542+
);
1543+
} else {
1544+
session.buffer_lint(
1545+
lint::builtin::UNKNOWN_CRATE_TYPES,
1546+
ast::CRATE_NODE_ID,
1547+
span,
1548+
"invalid `crate_type` value"
1549+
);
1550+
}
1551+
}
15181552
None
15191553
}
15201554
_ => {

src/test/ui/invalid/invalid-crate-type.rs

+42
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,48 @@
1111
// regression test for issue 11256
1212
#![crate_type="foo"] //~ ERROR invalid `crate_type` value
1313

14+
// Tests for suggestions (#53958)
15+
16+
#![crate_type="statoclib"]
17+
//~^ ERROR invalid `crate_type` value
18+
//~| HELP did you mean
19+
//~| SUGGESTION staticlib
20+
21+
#![crate_type="procmacro"]
22+
//~^ ERROR invalid `crate_type` value
23+
//~| HELP did you mean
24+
//~| SUGGESTION proc-macro
25+
26+
#![crate_type="static-lib"]
27+
//~^ ERROR invalid `crate_type` value
28+
//~| HELP did you mean
29+
//~| SUGGESTION staticlib
30+
31+
#![crate_type="drylib"]
32+
//~^ ERROR invalid `crate_type` value
33+
//~| HELP did you mean
34+
//~| SUGGESTION dylib
35+
36+
#![crate_type="dlib"]
37+
//~^ ERROR invalid `crate_type` value
38+
//~| HELP did you mean
39+
//~| SUGGESTION rlib
40+
41+
#![crate_type="lob"]
42+
//~^ ERROR invalid `crate_type` value
43+
//~| HELP did you mean
44+
//~| SUGGESTION lib
45+
46+
#![crate_type="bon"]
47+
//~^ ERROR invalid `crate_type` value
48+
//~| HELP did you mean
49+
//~| SUGGESTION bin
50+
51+
#![crate_type="cdalib"]
52+
//~^ ERROR invalid `crate_type` value
53+
//~| HELP did you mean
54+
//~| SUGGESTION cdylib
55+
1456
fn main() {
1557
return
1658
}
+51-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,58 @@
11
error: invalid `crate_type` value
2-
--> $DIR/invalid-crate-type.rs:12:1
2+
--> $DIR/invalid-crate-type.rs:12:15
33
|
44
LL | #![crate_type="foo"] //~ ERROR invalid `crate_type` value
5-
| ^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^
66
|
77
= note: #[deny(unknown_crate_types)] on by default
88

9-
error: aborting due to previous error
9+
error: invalid `crate_type` value
10+
--> $DIR/invalid-crate-type.rs:16:15
11+
|
12+
LL | #![crate_type="statoclib"]
13+
| ^^^^^^^^^^^ help: did you mean: `"staticlib"`
14+
15+
error: invalid `crate_type` value
16+
--> $DIR/invalid-crate-type.rs:21:15
17+
|
18+
LL | #![crate_type="procmacro"]
19+
| ^^^^^^^^^^^ help: did you mean: `"proc-macro"`
20+
21+
error: invalid `crate_type` value
22+
--> $DIR/invalid-crate-type.rs:26:15
23+
|
24+
LL | #![crate_type="static-lib"]
25+
| ^^^^^^^^^^^^ help: did you mean: `"staticlib"`
26+
27+
error: invalid `crate_type` value
28+
--> $DIR/invalid-crate-type.rs:31:15
29+
|
30+
LL | #![crate_type="drylib"]
31+
| ^^^^^^^^ help: did you mean: `"dylib"`
32+
33+
error: invalid `crate_type` value
34+
--> $DIR/invalid-crate-type.rs:36:15
35+
|
36+
LL | #![crate_type="dlib"]
37+
| ^^^^^^ help: did you mean: `"rlib"`
38+
39+
error: invalid `crate_type` value
40+
--> $DIR/invalid-crate-type.rs:41:15
41+
|
42+
LL | #![crate_type="lob"]
43+
| ^^^^^ help: did you mean: `"lib"`
44+
45+
error: invalid `crate_type` value
46+
--> $DIR/invalid-crate-type.rs:46:15
47+
|
48+
LL | #![crate_type="bon"]
49+
| ^^^^^ help: did you mean: `"bin"`
50+
51+
error: invalid `crate_type` value
52+
--> $DIR/invalid-crate-type.rs:51:15
53+
|
54+
LL | #![crate_type="cdalib"]
55+
| ^^^^^^^^ help: did you mean: `"cdylib"`
56+
57+
error: aborting due to 9 previous errors
1058

0 commit comments

Comments
 (0)