Skip to content

Commit

Permalink
Merge pull request #30844 from pnkfelix/pr30753-betaport-downgrade-st…
Browse files Browse the repository at this point in the history
…ruct-warn-to-err

[beta] downgrade struct warn to err
  • Loading branch information
brson committed Jan 12, 2016
2 parents 2e48b59 + 5e2e81b commit 4dd6b09
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 21 deletions.
11 changes: 11 additions & 0 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

use lint::{LintPass, LateLintPass, LintArray};

// name of the future-incompatible group
pub const FUTURE_INCOMPATIBLE: &'static str = "future_incompatible";

declare_lint! {
pub CONST_ERR,
Warn,
Expand Down Expand Up @@ -117,6 +120,13 @@ declare_lint! {
Allow,
"detects trivial casts of numeric types which could be removed"
}

declare_lint! {
pub MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
Warn,
"unit struct or enum variant erroneously allowed to match via path::ident(..)"
}

/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
#[derive(Copy, Clone)]
Expand All @@ -141,6 +151,7 @@ impl LintPass for HardwiredLints {
FAT_PTR_TRANSMUTES,
TRIVIAL_CASTS,
TRIVIAL_NUMERIC_CASTS,
MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
CONST_ERR
)
}
Expand Down
22 changes: 19 additions & 3 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,8 +363,12 @@ pub fn gather_attrs(attrs: &[ast::Attribute])
/// in trans that run after the main lint pass is finished. Most
/// lints elsewhere in the compiler should call
/// `Session::add_lint()` instead.
pub fn raw_emit_lint(sess: &Session, lint: &'static Lint,
lvlsrc: LevelSource, span: Option<Span>, msg: &str) {
pub fn raw_emit_lint(sess: &Session,
lints: &LintStore,
lint: &'static Lint,
lvlsrc: LevelSource,
span: Option<Span>,
msg: &str) {
let (mut level, source) = lvlsrc;
if level == Allow { return }

Expand Down Expand Up @@ -399,6 +403,18 @@ pub fn raw_emit_lint(sess: &Session, lint: &'static Lint,
_ => sess.bug("impossible level in raw_emit_lint"),
}

// Check for future incompatibility lints and issue a stronger warning.
let future_incompat_lints = &lints.lint_groups[builtin::FUTURE_INCOMPATIBLE];
let this_id = LintId::of(lint);
if future_incompat_lints.0.iter().any(|&id| id == this_id) {
let msg = "this lint will become a HARD ERROR in a future release!";
if let Some(sp) = span {
sess.span_note(sp, msg);
} else {
sess.note(msg);
}
}

if let Some(span) = def {
sess.span_note(span, "lint level defined here");
}
Expand Down Expand Up @@ -428,7 +444,7 @@ pub trait LintContext: Sized {
Some(&pair) => pair,
};

raw_emit_lint(&self.sess(), lint, (level, src), span, msg);
raw_emit_lint(&self.sess(), self.lints(), lint, (level, src), span, msg);
}

/// Emit a lint at the appropriate level, for a particular span.
Expand Down
3 changes: 3 additions & 0 deletions src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
UNUSED_MUT, UNREACHABLE_CODE, UNUSED_MUST_USE,
UNUSED_UNSAFE, PATH_STATEMENTS, UNUSED_ATTRIBUTES);

add_lint_group!(sess, FUTURE_INCOMPATIBLE,
MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT);

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

Expand Down
1 change: 1 addition & 0 deletions src/librustc_trans/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2204,6 +2204,7 @@ fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &hir::EnumDef, sp: Span,
// Use lint::raw_emit_lint rather than sess.add_lint because the lint-printing
// pass for the latter already ran.
lint::raw_emit_lint(&ccx.tcx().sess,
&ccx.tcx().sess.lint_store.borrow(),
lint::builtin::VARIANT_SIZE_DIFFERENCES,
*lvlsrc.unwrap(),
Some(sp),
Expand Down
36 changes: 22 additions & 14 deletions src/librustc_typeck/check/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use check::{check_expr, check_expr_has_type, check_expr_with_expectation};
use check::{check_expr_coercable_to_type, demand, FnCtxt, Expectation};
use check::{check_expr_with_lvalue_pref};
use check::{instantiate_path, resolve_ty_and_def_ufcs, structurally_resolved_type};
use lint;
use require_same_types;
use util::nodemap::FnvHashMap;
use session::Session;
Expand Down Expand Up @@ -138,7 +139,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
if pat_is_resolved_const(&tcx.def_map.borrow(), pat) => {
if let hir::PatEnum(ref path, ref subpats) = pat.node {
if !(subpats.is_some() && subpats.as_ref().unwrap().is_empty()) {
bad_struct_kind_err(tcx.sess, pat.span, path, false);
bad_struct_kind_err(tcx.sess, pat, path, false);
return;
}
}
Expand Down Expand Up @@ -580,10 +581,21 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx hir::Pat,
}

// This function exists due to the warning "diagnostic code E0164 already used"
fn bad_struct_kind_err(sess: &Session, span: Span, path: &hir::Path, is_warning: bool) {
fn bad_struct_kind_err(sess: &Session, pat: &hir::Pat, path: &hir::Path, lint: bool) {
let name = pprust::path_to_string(path);
span_err_or_warn!(is_warning, sess, span, E0164,
"`{}` does not name a tuple variant or a tuple struct", name);
let msg = format!("`{}` does not name a tuple variant or a tuple struct", name);
if lint {
let expanded_msg =
format!("{}; RFC 218 disallowed matching of unit variants or unit structs via {}(..)",
msg,
name);
sess.add_lint(lint::builtin::MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
pat.id,
pat.span,
expanded_msg);
} else {
span_err!(sess, pat.span, E0164, "{}", msg);
}
}

pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
Expand Down Expand Up @@ -634,11 +646,8 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
opt_ty, def, pat.span, pat.id);

let report_bad_struct_kind = |is_warning| {
bad_struct_kind_err(tcx.sess, pat.span, path, is_warning);
if is_warning {
return
}

bad_struct_kind_err(tcx.sess, pat, path, is_warning);
if is_warning { return; }
fcx.write_error(pat.id);
if let Some(subpats) = subpats {
for pat in subpats {
Expand Down Expand Up @@ -676,10 +685,6 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
report_bad_struct_kind(is_special_case);
if !is_special_case {
return
} else {
span_note!(tcx.sess, pat.span,
"this warning will become a HARD ERROR in a future release. \
See RFC 218 for details.");
}
}
(variant.fields
Expand All @@ -693,7 +698,10 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
ty::TyStruct(struct_def, expected_substs) => {
let variant = struct_def.struct_variant();
if is_tuple_struct_pat && variant.kind() != ty::VariantKind::Tuple {
report_bad_struct_kind(false);
// Matching unit structs with tuple variant patterns (`UnitVariant(..)`)
// is allowed for backward compatibility.
let is_special_case = variant.kind() == ty::VariantKind::Unit;
report_bad_struct_kind(is_special_case);
return;
}
(variant.fields
Expand Down
8 changes: 6 additions & 2 deletions src/test/compile-fail/empty-struct-unit-pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

// Can't use unit struct as enum pattern

#![feature(rustc_attrs)]
// remove prior feature after warning cycle and promoting warnings to errors
#![feature(braced_empty_structs)]

struct Empty1;
Expand All @@ -18,7 +20,9 @@ enum E {
Empty2
}

fn main() {
// remove attribute after warning cycle and promoting warnings to errors
#[rustc_error]
fn main() { //~ ERROR: compilation successful
let e1 = Empty1;
let e2 = E::Empty2;

Expand All @@ -27,7 +31,7 @@ fn main() {
// Empty1() => () // ERROR `Empty1` does not name a tuple variant or a tuple struct
// }
match e1 {
Empty1(..) => () //~ ERROR `Empty1` does not name a tuple variant or a tuple struct
Empty1(..) => () //~ WARN `Empty1` does not name a tuple variant or a tuple struct
}
// Rejected by parser as yet
// match e2 {
Expand Down
1 change: 0 additions & 1 deletion src/test/compile-fail/match-pattern-field-mismatch-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ fn main() {
color::cmyk(_, _, _, _) => { }
color::no_color(_) => { }
//~^ ERROR this pattern has 1 field, but the corresponding variant has no fields
//~^^ WARN `color::no_color` does not name a tuple variant or a tuple struct
}
}
}
1 change: 0 additions & 1 deletion src/test/compile-fail/pattern-error-continue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ fn main() {
match A::B(1, 2) {
A::B(_, _, _) => (), //~ ERROR this pattern has 3 fields, but
A::D(_) => (), //~ ERROR this pattern has 1 field, but
//~^ WARN `A::D` does not name a tuple variant or a tuple struct
_ => ()
}
match 'c' {
Expand Down

0 comments on commit 4dd6b09

Please sign in to comment.