Skip to content

Add some extended errors for match expression checking. #21343

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mk/tests.mk
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ tidy:
| grep '^$(S)src/libbacktrace' -v \
| grep '^$(S)src/rust-installer' -v \
| xargs $(CFG_PYTHON) $(S)src/etc/check-binaries.py
$(Q) $(CFG_PYTHON) $(S)src/etc/errorck.py $(S)src/


endif
Expand Down
70 changes: 70 additions & 0 deletions src/etc/errorck.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Copyright 2015 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.

# Digs error codes out of files named 'diagnostics.rs' across
# the tree, and ensures thare are no duplicates.

import sys, os, re

src_dir = sys.argv[1]

errcode_map = { }

for (dirpath, dirnames, filenames) in os.walk(src_dir):

if "src/test" in dirpath or "src/llvm" in dirpath:
# Short circuit for fast
continue

for filename in filenames:
if filename != "diagnostics.rs":
continue

path = os.path.join(dirpath, filename)
line_num = 1
with open(path, 'r') as f:
for line in f:

p = re.compile("(E\d\d\d\d)")
m = p.search(line)
if not m is None:
errcode = m.group(1)

new_record = [(errcode, path, line_num, line)]
existing = errcode_map.get(errcode)
if existing is not None:
# This is a dupe
errcode_map[errcode] = existing + new_record
else:
errcode_map[errcode] = new_record

line_num += 1

errors = False
all_errors = []
for errcode in errcode_map:
entries = errcode_map[errcode]
all_errors += [entries[0][0]]
if len(entries) > 1:
print "error: duplicate error code " + errcode
for entry in entries:
print entry[1] + ": " + str(entry[2])
print entry[3]
errors = True

print str(len(errcode_map)) + " error codes"

all_errors.sort()
all_errors.reverse()

print "highest error code: " + all_errors[0]

if errors:
sys.exit(1)
60 changes: 38 additions & 22 deletions src/librustc/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,55 @@

#![allow(non_snake_case)]

register_diagnostic! { E0001, r##"
register_long_diagnostics! {
E0001: r##"
This error suggests that the expression arm corresponding to the noted pattern
will never be reached as for all possible values of the expression being matched,
one of the preceeding patterns will match.

This means that perhaps some of the preceeding patterns are too general, this
one is too specific or the ordering is incorrect.
"## }
"##,

E0003: r##"
Not-a-Number (NaN) values can not be compared for equality and hence can never match
the input to a match expression. To match against NaN values, you should instead use
the `is_nan` method in a guard, as in: x if x.is_nan() => ...
"##,

E0004: r##"
This error indicates that the compiler can not guarantee a matching pattern for one
or more possible inputs to a match expression. Guaranteed matches are required in order
to assign values to match expressions, or alternatively, determine the flow of execution.

If you encounter this error you must alter your patterns so that every possible value of
the input type is matched. For types with a small number of variants (like enums) you
should probably cover all cases explicitly. Alternatively, the underscore `_` wildcard
pattern can be added after all other patterns to match "anything else".
"##,

// FIXME: Remove duplication here?
E0005: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
name will be extracted in all cases. If you encounter this error you probably need
to use a `match` or `if let` to deal with the possibility of failure.
"##,

E0006: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
name will be extracted in all cases. If you encounter this error you probably need
to use a `match` or `if let` to deal with the possibility of failure.
"##
}

register_diagnostics! {
E0002,
E0003,
E0004,
E0005,
E0006,
E0007,
E0008,
E0009,
E0010,
E0011,
E0012,
E0013,
E0014,
E0015,
E0016,
Expand All @@ -49,24 +76,13 @@ register_diagnostics! {
E0137,
E0138,
E0139,
E0140,
E0152,
E0153,
E0157,
E0158,
E0161,
E0162,
E0165,
E0166,
E0167,
E0168,
E0169,
E0170,
E0171,
E0172,
E0173,
E0174,
E0177,
E0178,
E0179
E0170
}

__build_diagnostic_array! { DIAGNOSTICS }

6 changes: 3 additions & 3 deletions src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ extern crate test;

pub use rustc_llvm as llvm;

mod diagnostics;
// NB: This module needs to be declared first so diagnostics are
// registered before they are used.
pub mod diagnostics;

pub mod back {
pub use rustc_back::abi;
Expand Down Expand Up @@ -130,8 +132,6 @@ pub mod lib {
pub use llvm;
}

__build_diagnostic_array! { DIAGNOSTICS }

// A private module so that macro-expanded idents like
// `::rustc::lint::Lint` will also work in `rustc` itself.
//
Expand Down
15 changes: 13 additions & 2 deletions src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ use rustc::lint::Lint;
use rustc::lint;
use rustc::metadata;
use rustc::metadata::creader::CrateOrString::Str;
use rustc::DIAGNOSTICS;
use rustc::util::common::time;

use std::cmp::Ordering::Equal;
Expand Down Expand Up @@ -96,7 +95,7 @@ fn run_compiler(args: &[String]) {
None => return
};

let descriptions = diagnostics::registry::Registry::new(&DIAGNOSTICS);
let descriptions = diagnostics_registry();
match matches.opt_str("explain") {
Some(ref code) => {
match descriptions.find_description(&code[]) {
Expand Down Expand Up @@ -657,8 +656,20 @@ pub fn monitor<F:FnOnce()+Send>(f: F) {
}
}

pub fn diagnostics_registry() -> diagnostics::registry::Registry {
use syntax::diagnostics::registry::Registry;

let all_errors = Vec::new() +
rustc::diagnostics::DIAGNOSTICS.as_slice() +
rustc_typeck::diagnostics::DIAGNOSTICS.as_slice() +
rustc_resolve::diagnostics::DIAGNOSTICS.as_slice();

Registry::new(&*all_errors)
}

pub fn main() {
let args = std::os::args();
let result = run(args);
std::os::set_exit_status(result);
}

18 changes: 18 additions & 0 deletions src/librustc_resolve/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_snake_case)]

register_diagnostics! {
E0157,
E0153
}

__build_diagnostic_array! { DIAGNOSTICS }
4 changes: 4 additions & 0 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ use std::mem::replace;
use std::rc::{Rc, Weak};
use std::uint;

// NB: This module needs to be declared first so diagnostics are
// registered before they are used.
pub mod diagnostics;

mod check_unused;
mod record_exports;
mod build_reduced_graph;
Expand Down
Loading