Skip to content

Commit a1bcfc5

Browse files
committed
Added proper lint for the unit variant/struct warning.
1 parent 0903f80 commit a1bcfc5

File tree

3 files changed

+29
-15
lines changed

3 files changed

+29
-15
lines changed

src/librustc/lint/builtin.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,13 @@ declare_lint! {
120120
Allow,
121121
"detects trivial casts of numeric types which could be removed"
122122
}
123+
124+
declare_lint! {
125+
pub MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
126+
Warn,
127+
"unit struct or enum variant erroneously allowed to match via path::ident(..)"
128+
}
129+
123130
/// Does nothing as a lint pass, but registers some `Lint`s
124131
/// which are used by other parts of the compiler.
125132
#[derive(Copy, Clone)]
@@ -144,6 +151,7 @@ impl LintPass for HardwiredLints {
144151
FAT_PTR_TRANSMUTES,
145152
TRIVIAL_CASTS,
146153
TRIVIAL_NUMERIC_CASTS,
154+
MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
147155
CONST_ERR
148156
)
149157
}

src/librustc_lint/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,9 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
146146
UNUSED_MUT, UNREACHABLE_CODE, UNUSED_MUST_USE,
147147
UNUSED_UNSAFE, PATH_STATEMENTS, UNUSED_ATTRIBUTES);
148148

149+
add_lint_group!(sess, FUTURE_INCOMPATIBLE,
150+
MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT);
151+
149152
// We have one lint pass defined specially
150153
store.register_late_pass(sess, false, box lint::GatherNodeLevels);
151154

src/librustc_typeck/check/_match.rs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use check::{check_expr, check_expr_has_type, check_expr_with_expectation};
1919
use check::{check_expr_coercable_to_type, demand, FnCtxt, Expectation};
2020
use check::{check_expr_with_lvalue_pref};
2121
use check::{instantiate_path, resolve_ty_and_def_ufcs, structurally_resolved_type};
22+
use lint;
2223
use require_same_types;
2324
use util::nodemap::FnvHashMap;
2425
use session::Session;
@@ -138,7 +139,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
138139
if pat_is_resolved_const(&tcx.def_map.borrow(), pat) => {
139140
if let hir::PatEnum(ref path, ref subpats) = pat.node {
140141
if !(subpats.is_some() && subpats.as_ref().unwrap().is_empty()) {
141-
bad_struct_kind_err(tcx.sess, pat.span, path, false);
142+
bad_struct_kind_err(tcx.sess, pat, path, false);
142143
return;
143144
}
144145
}
@@ -580,10 +581,21 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx hir::Pat,
580581
}
581582

582583
// This function exists due to the warning "diagnostic code E0164 already used"
583-
fn bad_struct_kind_err(sess: &Session, span: Span, path: &hir::Path, is_warning: bool) {
584+
fn bad_struct_kind_err(sess: &Session, pat: &hir::Pat, path: &hir::Path, lint: bool) {
584585
let name = pprust::path_to_string(path);
585-
span_err_or_warn!(is_warning, sess, span, E0164,
586-
"`{}` does not name a tuple variant or a tuple struct", name);
586+
let msg = format!("`{}` does not name a tuple variant or a tuple struct", name);
587+
if lint {
588+
let expanded_msg =
589+
format!("{}; RFC 218 disallowed matching of unit variants or unit structs via {}(..)",
590+
msg,
591+
name);
592+
sess.add_lint(lint::builtin::MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
593+
pat.id,
594+
pat.span,
595+
expanded_msg);
596+
} else {
597+
span_err!(sess, pat.span, E0164, "{}", msg);
598+
}
587599
}
588600

589601
pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
@@ -634,17 +646,8 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
634646
opt_ty, def, pat.span, pat.id);
635647

636648
let report_bad_struct_kind = |is_warning| {
637-
bad_struct_kind_err(tcx.sess, pat.span, path, is_warning);
638-
if is_warning {
639-
// Boo! Too painful to attach this to the actual warning,
640-
// it should go away at some point though.
641-
tcx.sess.span_note_without_error(
642-
pat.span,
643-
"this warning will become a HARD ERROR in a future release. \
644-
See RFC 218 for details.");
645-
return
646-
}
647-
649+
bad_struct_kind_err(tcx.sess, pat, path, is_warning);
650+
if is_warning { return; }
648651
fcx.write_error(pat.id);
649652
if let Some(subpats) = subpats {
650653
for pat in subpats {

0 commit comments

Comments
 (0)