Skip to content

Commit 2593794

Browse files
committed
Revamp the "future incompatible" section to clarify the situation
better
1 parent 7cffc9b commit 2593794

File tree

8 files changed

+76
-21
lines changed

8 files changed

+76
-21
lines changed

src/librustc/lint/builtin.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@
1616
1717
use lint::{LintPass, LateLintPass, LintArray};
1818

19-
// name of the future-incompatible group
20-
pub const FUTURE_INCOMPATIBLE: &'static str = "future_incompatible";
21-
2219
declare_lint! {
2320
pub CONST_ERR,
2421
Warn,

src/librustc/lint/context.rs

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,22 @@ pub struct LintStore {
7575
/// is true if the lint group was added by a plugin.
7676
lint_groups: FnvHashMap<&'static str, (Vec<LintId>, bool)>,
7777

78+
/// Extra info for future incompatibility lints, descibing the
79+
/// issue or RFC that caused the incompatibility.
80+
future_incompatible: FnvHashMap<LintId, FutureIncompatibleInfo>,
81+
7882
/// Maximum level a lint can be
7983
lint_cap: Option<Level>,
8084
}
8185

86+
/// Extra information for a future incompatibility lint. See the call
87+
/// to `register_future_incompatible` in `librustc_lint/lib.rs` for
88+
/// guidelines.
89+
pub struct FutureIncompatibleInfo {
90+
pub id: LintId,
91+
pub reference: &'static str // e.g., a URL for an issue/PR/RFC or error code
92+
}
93+
8294
/// The targed of the `by_name` map, which accounts for renaming/deprecation.
8395
enum TargetLint {
8496
/// A direct lint target
@@ -123,6 +135,7 @@ impl LintStore {
123135
late_passes: Some(vec!()),
124136
by_name: FnvHashMap(),
125137
levels: FnvHashMap(),
138+
future_incompatible: FnvHashMap(),
126139
lint_groups: FnvHashMap(),
127140
lint_cap: None,
128141
}
@@ -182,6 +195,20 @@ impl LintStore {
182195
}
183196
}
184197

198+
pub fn register_future_incompatible(&mut self,
199+
sess: Option<&Session>,
200+
lints: Vec<FutureIncompatibleInfo>) {
201+
let ids = lints.iter().map(|f| f.id).collect();
202+
self.register_group(sess, false, "future_incompatible", ids);
203+
for info in lints {
204+
self.future_incompatible.insert(info.id, info);
205+
}
206+
}
207+
208+
pub fn future_incompatible(&self, id: LintId) -> Option<&FutureIncompatibleInfo> {
209+
self.future_incompatible.get(&id)
210+
}
211+
185212
pub fn register_group(&mut self, sess: Option<&Session>,
186213
from_plugin: bool, name: &'static str,
187214
to: Vec<LintId>) {
@@ -417,14 +444,18 @@ pub fn raw_struct_lint<'a>(sess: &'a Session,
417444
};
418445

419446
// Check for future incompatibility lints and issue a stronger warning.
420-
let future_incompat_lints = &lints.lint_groups[builtin::FUTURE_INCOMPATIBLE];
421-
let this_id = LintId::of(lint);
422-
if future_incompat_lints.0.iter().any(|&id| id == this_id) {
423-
let msg = "this lint will become a HARD ERROR in a future release!";
447+
if let Some(future_incompatible) = lints.future_incompatible(LintId::of(lint)) {
448+
let explanation = format!("this was previously accepted by the compiler \
449+
but is being phased out, \
450+
and will become a HARD ERROR in a future release!");
451+
let citation = format!("for more information, see {}",
452+
future_incompatible.reference);
424453
if let Some(sp) = span {
425-
err.span_note(sp, msg);
454+
err.span_warn(sp, &explanation);
455+
err.span_note(sp, &citation);
426456
} else {
427-
err.note(msg);
457+
err.warn(&explanation);
458+
err.note(&citation);
428459
}
429460
}
430461

src/librustc/lint/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ use rustc_front::hir;
4141

4242
pub use lint::context::{LateContext, EarlyContext, LintContext, LintStore,
4343
raw_emit_lint, check_crate, check_ast_crate, gather_attrs,
44-
raw_struct_lint, GatherNodeLevels};
44+
raw_struct_lint, GatherNodeLevels, FutureIncompatibleInfo};
4545

4646
/// Specification of a single lint.
4747
#[derive(Copy, Clone, Debug)]

src/librustc_lint/lib.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ pub use rustc::util as util;
5454

5555
use session::Session;
5656
use lint::LintId;
57+
use lint::FutureIncompatibleInfo;
5758

5859
mod bad_style;
5960
mod builtin;
@@ -144,9 +145,28 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
144145
UNUSED_MUT, UNREACHABLE_CODE, UNUSED_MUST_USE,
145146
UNUSED_UNSAFE, PATH_STATEMENTS, UNUSED_ATTRIBUTES);
146147

147-
add_lint_group!(sess, FUTURE_INCOMPATIBLE,
148-
PRIVATE_IN_PUBLIC, INVALID_TYPE_PARAM_DEFAULT,
149-
MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT);
148+
// Guidelines for creating a future incompatibility lint:
149+
//
150+
// - Create a lint defaulting to warn as normal, with ideally the same error
151+
// message you would normally give
152+
// - Add a suitable reference, typically an RFC or tracking issue. Go ahead
153+
// and include the full URL.
154+
// - Later, change lint to error
155+
// - Eventually, remove lint
156+
store.register_future_incompatible(sess, vec![
157+
FutureIncompatibleInfo {
158+
id: LintId::of(PRIVATE_IN_PUBLIC),
159+
reference: "the explanation for E0446 (`--explain E0446`)",
160+
},
161+
FutureIncompatibleInfo {
162+
id: LintId::of(INVALID_TYPE_PARAM_DEFAULT),
163+
reference: "PR 30742 <https://github.com/rust-lang/rust/pull/30724>",
164+
},
165+
FutureIncompatibleInfo {
166+
id: LintId::of(MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT),
167+
reference: "RFC 218 <https://github.com/rust-lang/rfcs/blob/master/text/0218-empty-struct-with-braces.md>",
168+
},
169+
]);
150170

151171
// We have one lint pass defined specially
152172
store.register_late_pass(sess, false, box lint::GatherNodeLevels);

src/librustc_privacy/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1528,7 +1528,7 @@ impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a,
15281528
lint::builtin::PRIVATE_IN_PUBLIC,
15291529
node_id,
15301530
ty.span,
1531-
"private type in public interface (error E0446)".to_string()
1531+
format!("private type in public interface"),
15321532
);
15331533
}
15341534
}

src/librustc_typeck/check/_match.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -595,14 +595,10 @@ fn bad_struct_kind_err(sess: &Session, pat: &hir::Pat, path: &hir::Path, lint: b
595595
let name = pprust::path_to_string(path);
596596
let msg = format!("`{}` does not name a tuple variant or a tuple struct", name);
597597
if lint {
598-
let expanded_msg =
599-
format!("{}; RFC 218 disallowed matching of unit variants or unit structs via {}(..)",
600-
msg,
601-
name);
602598
sess.add_lint(lint::builtin::MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
603599
pat.id,
604600
pat.span,
605-
expanded_msg);
601+
msg);
606602
} else {
607603
span_err!(sess, pat.span, E0164, "{}", msg);
608604
}

src/librustc_typeck/collect.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1917,8 +1917,8 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
19171917
lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
19181918
param.id,
19191919
param.span,
1920-
format!("defaults for type parameters are only allowed \
1921-
on `struct` or `enum` definitions (see issue #27336)"));
1920+
format!("defaults for type parameters are only allowed on type definitions, \
1921+
like `struct` or `enum`"));
19221922
}
19231923
}
19241924

src/libsyntax/errors/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,17 @@ impl<'a> DiagnosticBuilder<'a> {
160160
self.sub(Level::Note, msg, Some(sp), None);
161161
self
162162
}
163+
pub fn warn(&mut self, msg: &str) -> &mut DiagnosticBuilder<'a> {
164+
self.sub(Level::Warning, msg, None, None);
165+
self
166+
}
167+
pub fn span_warn(&mut self,
168+
sp: Span,
169+
msg: &str)
170+
-> &mut DiagnosticBuilder<'a> {
171+
self.sub(Level::Warning, msg, Some(sp), None);
172+
self
173+
}
163174
pub fn help(&mut self , msg: &str) -> &mut DiagnosticBuilder<'a> {
164175
self.sub(Level::Help, msg, None, None);
165176
self

0 commit comments

Comments
 (0)