rustc: Rearchitect lints to be emitted more eagerly

In preparation for incremental compilation this commit refactors the lint
handling infrastructure in the compiler to be more "eager" and overall more
incremental-friendly. Many passes of the compiler can emit lints at various
points but before this commit all lints were buffered in a table to be emitted
at the very end of compilation. This commit changes these lints to be emitted
immediately during compilation using pre-calculated lint level-related data
structures.

Linting today is split into two phases, one set of "early" lints run on the
`syntax::ast` and a "late" set of lints run on the HIR. This commit moves the
"early" lints to running as late as possible in compilation, just before HIR
lowering. This notably means that we're catching resolve-related lints just
before HIR lowering. The early linting remains a pass very similar to how it was
before, maintaining context of the current lint level as it walks the tree.

Post-HIR, however, linting is structured as a method on the `TyCtxt` which
transitively executes a query to calculate lint levels. Each request to lint on
a `TyCtxt` will query the entire crate's 'lint level data structure' and then go
from there about whether the lint should be emitted or not.

The query depends on the entire HIR crate but should be very quick to calculate
(just a quick walk of the HIR) and the red-green system should notice that the
lint level data structure rarely changes, and should hopefully preserve
incrementality.

Overall this resulted in a pretty big change to the test suite now that lints
are emitted much earlier in compilation (on-demand vs only at the end). This in
turn necessitated the addition of many `#![allow(warnings)]` directives
throughout the compile-fail test suite and a number of updates to the UI test
suite.
This commit is contained in:
Alex Crichton 2017-07-26 21:51:09 -07:00
parent c2de81f4c9
commit 0374e6aab7
84 changed files with 1345 additions and 1067 deletions

View File

@ -521,6 +521,7 @@ define_dep_nodes!( <'tcx>
[] IsAllocator(DefId),
[] IsPanicRuntime(DefId),
[] ExternCrate(DefId),
[] LintLevels,
);
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {

View File

@ -625,8 +625,6 @@ for ty::TypeckTables<'tcx> {
ref cast_kinds,
// FIXME(#41184): This is still ignored at the moment.
lints: _,
ref used_trait_imports,
tainted_by_errors,
ref free_region_map,

File diff suppressed because it is too large Load Diff

343
src/librustc/lint/levels.rs Normal file
View File

@ -0,0 +1,343 @@
// Copyright 2017 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.
use std::cmp;
use errors::DiagnosticBuilder;
use hir::HirId;
use lint::builtin;
use lint::context::CheckLintNameResult;
use lint::{self, Lint, LintId, Level, LintSource};
use session::Session;
use syntax::ast;
use syntax::attr;
use syntax::codemap::MultiSpan;
use syntax::symbol::Symbol;
use util::nodemap::FxHashMap;
pub struct LintLevelSets {
list: Vec<LintSet>,
lint_cap: Level,
}
enum LintSet {
CommandLine {
// -A,-W,-D flags, a `Symbol` for the flag itself and `Level` for which
// flag.
specs: FxHashMap<LintId, (Level, LintSource)>,
},
Node {
specs: FxHashMap<LintId, (Level, LintSource)>,
parent: u32,
},
}
impl LintLevelSets {
pub fn new(sess: &Session) -> LintLevelSets {
let mut me = LintLevelSets {
list: Vec::new(),
lint_cap: Level::Forbid,
};
me.process_command_line(sess);
return me
}
pub fn builder(sess: &Session) -> LintLevelsBuilder {
LintLevelsBuilder::new(sess, LintLevelSets::new(sess))
}
fn process_command_line(&mut self, sess: &Session) {
let store = sess.lint_store.borrow();
let mut specs = FxHashMap();
self.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid);
for &(ref lint_name, level) in &sess.opts.lint_opts {
store.check_lint_name_cmdline(sess, &lint_name, level);
// If the cap is less than this specified level, e.g. if we've got
// `--cap-lints allow` but we've also got `-D foo` then we ignore
// this specification as the lint cap will set it to allow anyway.
let level = cmp::min(level, self.lint_cap);
let lint_flag_val = Symbol::intern(lint_name);
let ids = match store.find_lints(&lint_name) {
Ok(ids) => ids,
Err(_) => continue, // errors handled in check_lint_name_cmdline above
};
for id in ids {
let src = LintSource::CommandLine(lint_flag_val);
specs.insert(id, (level, src));
}
}
self.list.push(LintSet::CommandLine {
specs: specs,
});
}
fn get_lint_level(&self, lint: &'static Lint, idx: u32)
-> (Level, LintSource)
{
let (level, mut src) = self.get_lint_id_level(LintId::of(lint), idx);
// If `level` is none then we actually assume the default level for this
// lint.
let mut level = level.unwrap_or(lint.default_level);
// If we're about to issue a warning, check at the last minute for any
// directives against the warnings "lint". If, for example, there's an
// `allow(warnings)` in scope then we want to respect that instead.
if level == Level::Warn {
let (warnings_level, warnings_src) =
self.get_lint_id_level(LintId::of(lint::builtin::WARNINGS), idx);
if let Some(configured_warning_level) = warnings_level {
if configured_warning_level != Level::Warn {
level = configured_warning_level;
src = warnings_src;
}
}
}
// Ensure that we never exceed the `--cap-lints` argument.
level = cmp::min(level, self.lint_cap);
return (level, src)
}
fn get_lint_id_level(&self, id: LintId, mut idx: u32)
-> (Option<Level>, LintSource)
{
loop {
match self.list[idx as usize] {
LintSet::CommandLine { ref specs } => {
if let Some(&(level, src)) = specs.get(&id) {
return (Some(level), src)
}
return (None, LintSource::Default)
}
LintSet::Node { ref specs, parent } => {
if let Some(&(level, src)) = specs.get(&id) {
return (Some(level), src)
}
idx = parent;
}
}
}
}
}
pub struct LintLevelsBuilder<'a> {
sess: &'a Session,
sets: LintLevelSets,
id_to_set: FxHashMap<HirId, u32>,
cur: u32,
warn_about_weird_lints: bool,
}
pub struct BuilderPush {
prev: u32,
}
impl<'a> LintLevelsBuilder<'a> {
pub fn new(sess: &'a Session, sets: LintLevelSets) -> LintLevelsBuilder<'a> {
assert_eq!(sets.list.len(), 1);
LintLevelsBuilder {
sess,
sets,
cur: 0,
id_to_set: FxHashMap(),
warn_about_weird_lints: sess.buffered_lints.borrow().is_some(),
}
}
/// Pushes a list of AST lint attributes onto this context.
///
/// This function will return a `BuilderPush` object which should be be
/// passed to `pop` when this scope for the attributes provided is exited.
///
/// This function will perform a number of tasks:
///
/// * It'll validate all lint-related attributes in `attrs`
/// * It'll mark all lint-related attriutes as used
/// * Lint levels will be updated based on the attributes provided
/// * Lint attributes are validated, e.g. a #[forbid] can't be switched to
/// #[allow]
///
/// Don't forget to call `pop`!
pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
let mut specs = FxHashMap();
let store = self.sess.lint_store.borrow();
let sess = self.sess;
let bad_attr = |span| {
span_err!(sess, span, E0452,
"malformed lint attribute");
};
for attr in attrs {
let level = match attr.name().and_then(|name| Level::from_str(&name.as_str())) {
None => continue,
Some(lvl) => lvl,
};
let meta = unwrap_or!(attr.meta(), continue);
attr::mark_used(attr);
let metas = if let Some(metas) = meta.meta_item_list() {
metas
} else {
bad_attr(meta.span);
continue
};
for li in metas {
let word = match li.word() {
Some(word) => word,
None => {
bad_attr(li.span);
continue
}
};
let name = word.name();
match store.check_lint_name(&name.as_str()) {
CheckLintNameResult::Ok(ids) => {
let src = LintSource::Node(name, li.span);
for id in ids {
specs.insert(*id, (level, src));
}
}
CheckLintNameResult::Warning(ref msg) => {
if self.warn_about_weird_lints {
self.struct_lint(builtin::RENAMED_AND_REMOVED_LINTS,
Some(li.span.into()),
msg)
.emit();
}
}
CheckLintNameResult::NoLint => {
if self.warn_about_weird_lints {
self.struct_lint(builtin::UNKNOWN_LINTS,
Some(li.span.into()),
&format!("unknown lint: `{}`", name))
.emit();
}
}
}
}
}
for (id, &(level, ref src)) in specs.iter() {
if level == Level::Forbid {
continue
}
let forbid_src = match self.sets.get_lint_id_level(*id, self.cur) {
(Some(Level::Forbid), src) => src,
_ => continue,
};
let forbidden_lint_name = match forbid_src {
LintSource::Default => id.to_string(),
LintSource::Node(name, _) => name.to_string(),
LintSource::CommandLine(name) => name.to_string(),
};
let (lint_attr_name, lint_attr_span) = match *src {
LintSource::Node(name, span) => (name, span),
_ => continue,
};
let mut diag_builder = struct_span_err!(self.sess,
lint_attr_span,
E0453,
"{}({}) overruled by outer forbid({})",
level.as_str(),
lint_attr_name,
forbidden_lint_name);
diag_builder.span_label(lint_attr_span, "overruled by previous forbid");
match forbid_src {
LintSource::Default => &mut diag_builder,
LintSource::Node(_, forbid_source_span) => {
diag_builder.span_label(forbid_source_span,
"`forbid` level set here")
},
LintSource::CommandLine(_) => {
diag_builder.note("`forbid` lint level was set on command line")
}
}.emit();
// don't set a separate error for every lint in the group
break
}
let prev = self.cur;
if specs.len() > 0 {
self.cur = self.sets.list.len() as u32;
self.sets.list.push(LintSet::Node {
specs: specs,
parent: prev,
});
}
BuilderPush {
prev: prev,
}
}
/// Called after `push` when the scope of a set of attributes are exited.
pub fn pop(&mut self, push: BuilderPush) {
self.cur = push.prev;
}
/// Used to emit a lint-related diagnostic based on the current state of
/// this lint context.
pub fn struct_lint(&self,
lint: &'static Lint,
span: Option<MultiSpan>,
msg: &str)
-> DiagnosticBuilder<'a>
{
let (level, src) = self.sets.get_lint_level(lint, self.cur);
lint::struct_lint_level(self.sess, lint, level, src, span, msg)
}
/// Registers the ID provided with the current set of lints stored in
/// this context.
pub fn register_id(&mut self, id: HirId) {
self.id_to_set.insert(id, self.cur);
}
pub fn build(self) -> LintLevelSets {
self.sets
}
pub fn build_map(self) -> LintLevelMap {
LintLevelMap {
sets: self.sets,
id_to_set: self.id_to_set,
}
}
}
pub struct LintLevelMap {
sets: LintLevelSets,
id_to_set: FxHashMap<HirId, u32>,
}
impl LintLevelMap {
/// If the `id` was previously registered with `register_id` when building
/// this `LintLevelMap` this returns the corresponding lint level and source
/// of the lint level for the lint provided.
///
/// If the `id` was not previously registered, returns `None`. If `None` is
/// returned then the parent of `id` should be acquired and this function
/// should be called again.
pub fn level_and_source(&self, lint: &'static Lint, id: HirId)
-> Option<(Level, LintSource)>
{
self.id_to_set.get(&id).map(|idx| {
self.sets.get_lint_level(lint, *idx)
})
}
}

View File

@ -31,20 +31,27 @@
pub use self::Level::*;
pub use self::LintSource::*;
use std::rc::Rc;
use errors::DiagnosticBuilder;
use hir::def_id::{CrateNum, LOCAL_CRATE};
use hir::intravisit::{self, FnKind};
use hir;
use hir::intravisit::FnKind;
use std::hash;
use session::Session;
use std::ascii::AsciiExt;
use syntax_pos::Span;
use syntax::visit as ast_visit;
use std::hash;
use syntax::ast;
use syntax::codemap::MultiSpan;
use syntax::symbol::Symbol;
use syntax::visit as ast_visit;
use syntax_pos::Span;
use ty::TyCtxt;
use ty::maps::Providers;
use util::nodemap::NodeMap;
pub use lint::context::{LateContext, EarlyContext, LintContext, LintStore,
raw_emit_lint, check_crate, check_ast_crate, gather_attrs,
raw_struct_lint, FutureIncompatibleInfo, EarlyLint, IntoEarlyLint};
pub use lint::table::LintTable;
check_crate, check_ast_crate,
FutureIncompatibleInfo, BufferedEarlyLint};
/// Specification of a single lint.
#[derive(Copy, Clone, Debug)]
@ -351,4 +358,215 @@ pub type LevelSource = (Level, LintSource);
pub mod builtin;
mod context;
mod table;
mod levels;
pub use self::levels::{LintLevelSets, LintLevelMap};
pub struct LintBuffer {
map: NodeMap<Vec<BufferedEarlyLint>>,
}
impl LintBuffer {
pub fn new() -> LintBuffer {
LintBuffer { map: NodeMap() }
}
pub fn add_lint(&mut self,
lint: &'static Lint,
id: ast::NodeId,
sp: MultiSpan,
msg: &str) {
let early_lint = BufferedEarlyLint {
lint_id: LintId::of(lint),
ast_id: id,
span: sp,
msg: msg.to_string(),
};
let arr = self.map.entry(id).or_insert(Vec::new());
if !arr.contains(&early_lint) {
arr.push(early_lint);
}
}
pub fn take(&mut self, id: ast::NodeId) -> Vec<BufferedEarlyLint> {
self.map.remove(&id).unwrap_or(Vec::new())
}
pub fn get_any(&self) -> Option<&[BufferedEarlyLint]> {
let key = self.map.keys().next().map(|k| *k);
key.map(|k| &self.map[&k][..])
}
}
pub fn struct_lint_level<'a>(sess: &'a Session,
lint: &'static Lint,
level: Level,
src: LintSource,
span: Option<MultiSpan>,
msg: &str)
-> DiagnosticBuilder<'a>
{
let mut err = match (level, span) {
(Level::Allow, _) => return sess.diagnostic().struct_dummy(),
(Level::Warn, Some(span)) => sess.struct_span_warn(span, msg),
(Level::Warn, None) => sess.struct_warn(msg),
(Level::Deny, Some(span)) |
(Level::Forbid, Some(span)) => sess.struct_span_err(span, msg),
(Level::Deny, None) |
(Level::Forbid, None) => sess.struct_err(msg),
};
let name = lint.name_lower();
match src {
LintSource::Default => {
sess.diag_note_once(
&mut err,
lint,
&format!("#[{}({})] on by default", level.as_str(), name));
}
LintSource::CommandLine(lint_flag_val) => {
let flag = match level {
Level::Warn => "-W",
Level::Deny => "-D",
Level::Forbid => "-F",
Level::Allow => panic!(),
};
let hyphen_case_lint_name = name.replace("_", "-");
if lint_flag_val.as_str() == name {
sess.diag_note_once(
&mut err,
lint,
&format!("requested on the command line with `{} {}`",
flag, hyphen_case_lint_name));
} else {
let hyphen_case_flag_val = lint_flag_val.as_str().replace("_", "-");
sess.diag_note_once(
&mut err,
lint,
&format!("`{} {}` implied by `{} {}`",
flag, hyphen_case_lint_name, flag,
hyphen_case_flag_val));
}
}
LintSource::Node(lint_attr_name, src) => {
sess.diag_span_note_once(&mut err, lint, src, "lint level defined here");
if lint_attr_name.as_str() != name {
let level_str = level.as_str();
sess.diag_note_once(&mut err, lint,
&format!("#[{}({})] implied by #[{}({})]",
level_str, name, level_str, lint_attr_name));
}
}
}
// Check for future incompatibility lints and issue a stronger warning.
let lints = sess.lint_store.borrow();
if let Some(future_incompatible) = lints.future_incompatible(LintId::of(lint)) {
let explanation = format!("this was previously accepted by the compiler \
but is being phased out; \
it will become a hard error in a future release!");
let citation = format!("for more information, see {}",
future_incompatible.reference);
err.warn(&explanation);
err.note(&citation);
}
return err
}
fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum)
-> Rc<LintLevelMap>
{
assert_eq!(cnum, LOCAL_CRATE);
let mut builder = LintLevelMapBuilder {
levels: LintLevelSets::builder(tcx.sess),
tcx: tcx,
};
let krate = tcx.hir.krate();
builder.with_lint_attrs(ast::CRATE_NODE_ID, &krate.attrs, |builder| {
intravisit::walk_crate(builder, krate);
});
Rc::new(builder.levels.build_map())
}
struct LintLevelMapBuilder<'a, 'tcx: 'a> {
levels: levels::LintLevelsBuilder<'tcx>,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
impl<'a, 'tcx> LintLevelMapBuilder<'a, 'tcx> {
fn with_lint_attrs<F>(&mut self,
id: ast::NodeId,
attrs: &[ast::Attribute],
f: F)
where F: FnOnce(&mut Self)
{
let push = self.levels.push(attrs);
self.levels.register_id(self.tcx.hir.definitions().node_to_hir_id(id));
f(self);
self.levels.pop(push);
}
}
impl<'a, 'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'tcx> {
intravisit::NestedVisitorMap::All(&self.tcx.hir)
}
fn visit_item(&mut self, it: &'tcx hir::Item) {
self.with_lint_attrs(it.id, &it.attrs, |builder| {
intravisit::walk_item(builder, it);
});
}
fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem) {
self.with_lint_attrs(it.id, &it.attrs, |builder| {
intravisit::walk_foreign_item(builder, it);
})
}
fn visit_expr(&mut self, e: &'tcx hir::Expr) {
self.with_lint_attrs(e.id, &e.attrs, |builder| {
intravisit::walk_expr(builder, e);
})
}
fn visit_struct_field(&mut self, s: &'tcx hir::StructField) {
self.with_lint_attrs(s.id, &s.attrs, |builder| {
intravisit::walk_struct_field(builder, s);
})
}
fn visit_variant(&mut self,
v: &'tcx hir::Variant,
g: &'tcx hir::Generics,
item_id: ast::NodeId) {
self.with_lint_attrs(v.node.data.id(), &v.node.attrs, |builder| {
intravisit::walk_variant(builder, v, g, item_id);
})
}
fn visit_local(&mut self, l: &'tcx hir::Local) {
self.with_lint_attrs(l.id, &l.attrs, |builder| {
intravisit::walk_local(builder, l);
})
}
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
self.with_lint_attrs(trait_item.id, &trait_item.attrs, |builder| {
intravisit::walk_trait_item(builder, trait_item);
});
}
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
self.with_lint_attrs(impl_item.id, &impl_item.attrs, |builder| {
intravisit::walk_impl_item(builder, impl_item);
});
}
}
pub fn provide(providers: &mut Providers) {
providers.lint_levels = lint_levels;
}

View File

@ -1,71 +0,0 @@
// Copyright 2012-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.
use syntax::ast;
use syntax_pos::MultiSpan;
use util::nodemap::NodeMap;
use super::{Lint, LintId, EarlyLint, IntoEarlyLint};
#[derive(RustcEncodable, RustcDecodable)]
pub struct LintTable {
map: NodeMap<Vec<EarlyLint>>
}
impl LintTable {
pub fn new() -> Self {
LintTable { map: NodeMap() }
}
pub fn add_lint<S: Into<MultiSpan>>(&mut self,
lint: &'static Lint,
id: ast::NodeId,
sp: S,
msg: String)
{
self.add_lint_diagnostic(lint, id, (sp, &msg[..]))
}
pub fn add_lint_diagnostic<M>(&mut self,
lint: &'static Lint,
id: ast::NodeId,
msg: M)
where M: IntoEarlyLint,
{
let lint_id = LintId::of(lint);
let early_lint = msg.into_early_lint(lint_id);
let arr = self.map.entry(id).or_insert(vec![]);
if !arr.contains(&early_lint) {
arr.push(early_lint);
}
}
pub fn get(&self, id: ast::NodeId) -> &[EarlyLint] {
self.map.get(&id).map(|v| &v[..]).unwrap_or(&[])
}
pub fn take(&mut self, id: ast::NodeId) -> Vec<EarlyLint> {
self.map.remove(&id).unwrap_or(vec![])
}
pub fn transfer(&mut self, into: &mut LintTable) {
into.map.extend(self.map.drain());
}
/// Returns the first (id, lint) pair that is non-empty. Used to
/// implement a sanity check in lints that all node-ids are
/// visited.
pub fn get_any(&self) -> Option<(&ast::NodeId, &Vec<EarlyLint>)> {
self.map.iter()
.filter(|&(_, v)| !v.is_empty())
.next()
}
}

View File

@ -17,11 +17,11 @@ use hir::{self, Item_, PatKind};
use hir::intravisit::{self, Visitor, NestedVisitorMap};
use hir::itemlikevisit::ItemLikeVisitor;
use middle::privacy;
use ty::{self, TyCtxt};
use hir::def::Def;
use hir::def_id::{DefId, LOCAL_CRATE};
use lint;
use middle::privacy;
use ty::{self, TyCtxt};
use util::nodemap::FxHashSet;
use syntax::{ast, codemap};
@ -299,7 +299,9 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
}
}
fn has_allow_dead_code_or_lang_attr(attrs: &[ast::Attribute]) -> bool {
fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt,
id: ast::NodeId,
attrs: &[ast::Attribute]) -> bool {
if attr::contains_name(attrs, "lang") {
return true;
}
@ -315,14 +317,7 @@ fn has_allow_dead_code_or_lang_attr(attrs: &[ast::Attribute]) -> bool {
return true;
}
let dead_code = lint::builtin::DEAD_CODE.name_lower();
for attr in lint::gather_attrs(attrs) {
match attr {
Ok((name, lint::Allow, _)) if name == &*dead_code => return true,
_ => (),
}
}
false
tcx.lint_level_at_node(lint::builtin::DEAD_CODE, id).0 == lint::Allow
}
// This visitor seeds items that
@ -338,14 +333,17 @@ fn has_allow_dead_code_or_lang_attr(attrs: &[ast::Attribute]) -> bool {
// or
// 2) We are not sure to be live or not
// * Implementation of a trait method
struct LifeSeeder<'k> {
struct LifeSeeder<'k, 'tcx: 'k> {
worklist: Vec<ast::NodeId>,
krate: &'k hir::Crate,
tcx: TyCtxt<'k, 'tcx, 'tcx>,
}
impl<'v, 'k> ItemLikeVisitor<'v> for LifeSeeder<'k> {
impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
fn visit_item(&mut self, item: &hir::Item) {
let allow_dead_code = has_allow_dead_code_or_lang_attr(&item.attrs);
let allow_dead_code = has_allow_dead_code_or_lang_attr(self.tcx,
item.id,
&item.attrs);
if allow_dead_code {
self.worklist.push(item.id);
}
@ -360,7 +358,9 @@ impl<'v, 'k> ItemLikeVisitor<'v> for LifeSeeder<'k> {
match trait_item.node {
hir::TraitItemKind::Const(_, Some(_)) |
hir::TraitItemKind::Method(_, hir::TraitMethod::Provided(_)) => {
if has_allow_dead_code_or_lang_attr(&trait_item.attrs) {
if has_allow_dead_code_or_lang_attr(self.tcx,
trait_item.id,
&trait_item.attrs) {
self.worklist.push(trait_item.id);
}
}
@ -372,7 +372,9 @@ impl<'v, 'k> ItemLikeVisitor<'v> for LifeSeeder<'k> {
for impl_item_ref in impl_item_refs {
let impl_item = self.krate.impl_item(impl_item_ref.id);
if opt_trait.is_some() ||
has_allow_dead_code_or_lang_attr(&impl_item.attrs) {
has_allow_dead_code_or_lang_attr(self.tcx,
impl_item.id,
&impl_item.attrs) {
self.worklist.push(impl_item_ref.id.node_id);
}
}
@ -408,6 +410,7 @@ fn create_and_seed_worklist<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let mut life_seeder = LifeSeeder {
worklist,
krate,
tcx,
};
krate.visit_all_item_likes(&mut life_seeder);
@ -472,17 +475,19 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
!field.is_positional()
&& !self.symbol_is_live(field.id, None)
&& !is_marker_field
&& !has_allow_dead_code_or_lang_attr(&field.attrs)
&& !has_allow_dead_code_or_lang_attr(self.tcx, field.id, &field.attrs)
}
fn should_warn_about_variant(&mut self, variant: &hir::Variant_) -> bool {
!self.symbol_is_live(variant.data.id(), None)
&& !has_allow_dead_code_or_lang_attr(&variant.attrs)
&& !has_allow_dead_code_or_lang_attr(self.tcx,
variant.data.id(),
&variant.attrs)
}
fn should_warn_about_foreign_item(&mut self, fi: &hir::ForeignItem) -> bool {
!self.symbol_is_live(fi.id, None)
&& !has_allow_dead_code_or_lang_attr(&fi.attrs)
&& !has_allow_dead_code_or_lang_attr(self.tcx, fi.id, &fi.attrs)
}
// id := node id of an item's definition.
@ -528,11 +533,10 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
node_type: &str) {
if !name.as_str().starts_with("_") {
self.tcx
.sess
.add_lint(lint::builtin::DEAD_CODE,
id,
span,
format!("{} is never used: `{}`", node_type, name));
.lint_node(lint::builtin::DEAD_CODE,
id,
span,
&format!("{} is never used: `{}`", node_type, name));
}
}
}

View File

@ -56,11 +56,11 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> {
match self.unsafe_context.root {
SafeContext => {
if is_lint {
self.tcx.sess.add_lint(lint::builtin::SAFE_EXTERN_STATICS,
node_id,
span,
format!("{} requires unsafe function or \
block (error E0133)", description));
self.tcx.lint_node(lint::builtin::SAFE_EXTERN_STATICS,
node_id,
span,
&format!("{} requires unsafe function or \
block (error E0133)", description));
} else {
// Report an error.
struct_span_err!(

View File

@ -1482,12 +1482,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
};
if is_assigned {
self.ir.tcx.sess.add_lint(lint::builtin::UNUSED_VARIABLES, id, sp,
format!("variable `{}` is assigned to, but never used",
name));
self.ir.tcx.lint_node(lint::builtin::UNUSED_VARIABLES, id, sp,
&format!("variable `{}` is assigned to, but never used",
name));
} else if name != "self" {
self.ir.tcx.sess.add_lint(lint::builtin::UNUSED_VARIABLES, id, sp,
format!("unused variable: `{}`", name));
self.ir.tcx.lint_node(lint::builtin::UNUSED_VARIABLES, id, sp,
&format!("unused variable: `{}`", name));
}
}
true
@ -1509,11 +1509,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
fn report_dead_assign(&self, id: NodeId, sp: Span, var: Variable, is_argument: bool) {
if let Some(name) = self.should_warn(var) {
if is_argument {
self.ir.tcx.sess.add_lint(lint::builtin::UNUSED_ASSIGNMENTS, id, sp,
format!("value passed to `{}` is never read", name));
self.ir.tcx.lint_node(lint::builtin::UNUSED_ASSIGNMENTS, id, sp,
&format!("value passed to `{}` is never read", name));
} else {
self.ir.tcx.sess.add_lint(lint::builtin::UNUSED_ASSIGNMENTS, id, sp,
format!("value assigned to `{}` is never read", name));
self.ir.tcx.lint_node(lint::builtin::UNUSED_ASSIGNMENTS, id, sp,
&format!("value assigned to `{}` is never read", name));
}
}
}

View File

@ -493,7 +493,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
format!("use of deprecated item")
};
self.sess.add_lint(lint::builtin::DEPRECATED, id, span, msg);
self.lint_node(lint::builtin::DEPRECATED, id, span, &msg);
};
// Deprecated attributes apply in-crate and cross-crate.
@ -737,10 +737,10 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
for &(ref stable_lang_feature, span) in &sess.features.borrow().declared_stable_lang_features {
let version = find_lang_feature_accepted_version(&stable_lang_feature.as_str())
.expect("unexpectedly couldn't find version feature was stabilized");
sess.add_lint(lint::builtin::STABLE_FEATURES,
tcx.lint_node(lint::builtin::STABLE_FEATURES,
ast::CRATE_NODE_ID,
span,
format_stable_since_msg(version));
&format_stable_since_msg(version));
}
let index = tcx.stability.borrow();
@ -748,10 +748,10 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
match remaining_lib_features.remove(used_lib_feature) {
Some(span) => {
if let &attr::StabilityLevel::Stable { since: ref version } = level {
sess.add_lint(lint::builtin::STABLE_FEATURES,
tcx.lint_node(lint::builtin::STABLE_FEATURES,
ast::CRATE_NODE_ID,
span,
format_stable_since_msg(&version.as_str()));
&format_stable_since_msg(&version.as_str()));
}
}
None => ( /* used but undeclared, handled during the previous ast visit */ )
@ -759,9 +759,9 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
}
for &span in remaining_lib_features.values() {
sess.add_lint(lint::builtin::UNUSED_FEATURES,
tcx.lint_node(lint::builtin::UNUSED_FEATURES,
ast::CRATE_NODE_ID,
span,
"unused or unknown feature".to_string());
"unused or unknown feature");
}
}

View File

@ -79,7 +79,7 @@ pub struct Session {
// if the value stored here has been affected by path remapping.
pub working_dir: (String, bool),
pub lint_store: RefCell<lint::LintStore>,
pub lints: RefCell<lint::LintTable>,
pub buffered_lints: RefCell<Option<lint::LintBuffer>>,
/// Set of (LintId, Option<Span>, message) tuples tracking lint
/// (sub)diagnostics that have been set once, but should not be set again,
/// in order to avoid redundantly verbose output (Issue #24690).
@ -307,22 +307,15 @@ impl Session {
self.diagnostic().unimpl(msg)
}
pub fn add_lint<S: Into<MultiSpan>>(&self,
lint: &'static lint::Lint,
id: ast::NodeId,
sp: S,
msg: String)
{
self.lints.borrow_mut().add_lint(lint, id, sp, msg);
}
pub fn add_lint_diagnostic<M>(&self,
lint: &'static lint::Lint,
id: ast::NodeId,
msg: M)
where M: lint::IntoEarlyLint,
{
self.lints.borrow_mut().add_lint_diagnostic(lint, id, msg);
pub fn buffer_lint<S: Into<MultiSpan>>(&self,
lint: &'static lint::Lint,
id: ast::NodeId,
sp: S,
msg: &str) {
match *self.buffered_lints.borrow_mut() {
Some(ref mut buffer) => buffer.add_lint(lint, id, sp.into(), msg),
None => bug!("can't buffer lints after HIR lowering"),
}
}
pub fn reserve_node_ids(&self, count: usize) -> ast::NodeId {
@ -708,7 +701,7 @@ pub fn build_session_(sopts: config::Options,
local_crate_source_file,
working_dir,
lint_store: RefCell::new(lint::LintStore::new()),
lints: RefCell::new(lint::LintTable::new()),
buffered_lints: RefCell::new(Some(lint::LintBuffer::new())),
one_time_diagnostics: RefCell::new(FxHashSet()),
plugin_llvm_passes: RefCell::new(Vec::new()),
plugin_attributes: RefCell::new(Vec::new()),

View File

@ -499,11 +499,21 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// weird effect -- the diagnostic is reported as a lint, and
// the builder which is returned is marked as canceled.
let mut err =
struct_span_err!(self.tcx.sess,
error_span,
E0276,
"impl has stricter requirements than trait");
let msg = "impl has stricter requirements than trait";
let mut err = match lint_id {
Some(node_id) => {
self.tcx.struct_span_lint_node(EXTRA_REQUIREMENT_IN_IMPL,
node_id,
error_span,
msg)
}
None => {
struct_span_err!(self.tcx.sess,
error_span,
E0276,
"{}", msg)
}
};
if let Some(trait_item_span) = self.tcx.hir.span_if_local(trait_item_def_id) {
let span = self.tcx.sess.codemap().def_span(trait_item_span);
@ -514,13 +524,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
error_span,
format!("impl has extra requirement {}", requirement));
if let Some(node_id) = lint_id {
self.tcx.sess.add_lint_diagnostic(EXTRA_REQUIREMENT_IN_IMPL,
node_id,
(*err).clone());
err.cancel();
}
err
}

View File

@ -512,11 +512,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
}
if raise_warning {
tcx.sess.add_lint(lint::builtin::RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
obligation.cause.body_id,
obligation.cause.span,
format!("code relies on type inference rules which are likely \
to change"));
tcx.lint_node(lint::builtin::RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
obligation.cause.body_id,
obligation.cause.span,
&format!("code relies on type inference rules which are likely \
to change"));
}
}
Ok(ret)

View File

@ -11,14 +11,15 @@
//! type context book-keeping
use dep_graph::DepGraph;
use errors::DiagnosticBuilder;
use session::Session;
use lint;
use middle;
use hir::TraitMap;
use hir::def::{Def, ExportMap};
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use hir::map as hir_map;
use hir::map::DefPathHash;
use lint::{self, Lint};
use middle::free_region::FreeRegionMap;
use middle::lang_items;
use middle::resolve_lifetime;
@ -58,6 +59,7 @@ use std::rc::Rc;
use syntax::abi;
use syntax::ast::{self, Name, NodeId};
use syntax::attr;
use syntax::codemap::MultiSpan;
use syntax::symbol::{Symbol, keywords};
use syntax_pos::Span;
@ -254,9 +256,6 @@ pub struct TypeckTables<'tcx> {
/// *from* expression of the cast, not the cast itself.
pub cast_kinds: NodeMap<ty::cast::CastKind>,
/// Lints for the body of this fn generated by typeck.
pub lints: lint::LintTable,
/// Set of trait imports actually used in the method resolution.
/// This is used for warning unused imports.
pub used_trait_imports: DefIdSet,
@ -285,7 +284,6 @@ impl<'tcx> TypeckTables<'tcx> {
liberated_fn_sigs: NodeMap(),
fru_field_types: NodeMap(),
cast_kinds: NodeMap(),
lints: lint::LintTable::new(),
used_trait_imports: DefIdSet(),
tainted_by_errors: false,
free_region_map: FreeRegionMap::new(),
@ -1515,6 +1513,59 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
{
self.mk_substs(iter::once(s).chain(t.into_iter().cloned()).map(Kind::from))
}
pub fn lint_node<S: Into<MultiSpan>>(self,
lint: &'static Lint,
id: NodeId,
span: S,
msg: &str) {
self.struct_span_lint_node(lint, id, span.into(), msg).emit()
}
pub fn lint_level_at_node(self, lint: &'static Lint, mut id: NodeId)
-> (lint::Level, lint::LintSource)
{
// Right now we insert a `with_ignore` node in the dep graph here to
// ignore the fact that `lint_levels` below depends on the entire crate.
// For now this'll prevent false positives of recompiling too much when
// anything changes.
//
// Once red/green incremental compilation lands we should be able to
// remove this because while the crate changes often the lint level map
// will change rarely.
self.dep_graph.with_ignore(|| {
let sets = self.lint_levels(LOCAL_CRATE);
loop {
let hir_id = self.hir.definitions().node_to_hir_id(id);
if let Some(pair) = sets.level_and_source(lint, hir_id) {
return pair
}
let next = self.hir.get_parent_node(id);
if next == id {
bug!("lint traversal reached the root of the crate");
}
id = next;
}
})
}
pub fn struct_span_lint_node<S: Into<MultiSpan>>(self,
lint: &'static Lint,
id: NodeId,
span: S,
msg: &str)
-> DiagnosticBuilder<'tcx>
{
let (level, src) = self.lint_level_at_node(lint, id);
lint::struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg)
}
pub fn struct_lint_node(self, lint: &'static Lint, id: NodeId, msg: &str)
-> DiagnosticBuilder<'tcx>
{
let (level, src) = self.lint_level_at_node(lint, id);
lint::struct_lint_level(self.sess, lint, level, src, None, msg)
}
}
pub trait InternAs<T: ?Sized, R> {

View File

@ -12,6 +12,7 @@ use dep_graph::{DepConstructor, DepNode, DepNodeIndex};
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use hir::def::Def;
use hir;
use lint;
use middle::const_val;
use middle::cstore::{ExternCrate, LinkagePreference};
use middle::privacy::AccessLevels;
@ -506,6 +507,12 @@ impl<'tcx> QueryDescription for queries::extern_crate<'tcx> {
}
}
impl<'tcx> QueryDescription for queries::lint_levels<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("computing the lint levels for items in this crate")
}
}
macro_rules! define_maps {
(<$tcx:tt>
$($(#[$attr:meta])*
@ -988,6 +995,8 @@ define_maps! { <'tcx>
[] is_panic_runtime: IsPanicRuntime(DefId) -> bool,
[] extern_crate: ExternCrate(DefId) -> Rc<Option<ExternCrate>>,
[] lint_levels: lint_levels(CrateNum) -> Rc<lint::LintLevelMap>,
}
fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> {
@ -1059,3 +1068,7 @@ fn needs_drop_dep_node<'tcx>(_: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepConstruct
fn layout_dep_node<'tcx>(_: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepConstructor<'tcx> {
DepConstructor::Layout
}
fn lint_levels<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::LintLevels
}

View File

@ -23,7 +23,7 @@ use rustc::session::Session;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::subst::Substs;
use rustc::lint;
use rustc_errors::{Diagnostic, Level, DiagnosticBuilder};
use rustc_errors::DiagnosticBuilder;
use rustc::hir::def::*;
use rustc::hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap};
@ -351,12 +351,10 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
match arm_index {
// The arm with the user-specified pattern.
0 => {
let mut diagnostic = Diagnostic::new(Level::Warning,
"unreachable pattern");
diagnostic.set_span(pat.span);
cx.tcx.sess.add_lint_diagnostic(
cx.tcx.lint_node(
lint::builtin::UNREACHABLE_PATTERNS,
hir_pat.id, diagnostic);
hir_pat.id, pat.span,
"unreachable pattern");
},
// The arm with the wildcard pattern.
1 => {
@ -371,16 +369,18 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
hir::MatchSource::ForLoopDesugar |
hir::MatchSource::Normal => {
let mut diagnostic = Diagnostic::new(Level::Warning,
"unreachable pattern");
diagnostic.set_span(pat.span);
let mut err = cx.tcx.struct_span_lint_node(
lint::builtin::UNREACHABLE_PATTERNS,
hir_pat.id,
pat.span,
"unreachable pattern",
);
// if we had a catchall pattern, hint at that
if let Some(catchall) = catchall {
diagnostic.span_label(pat.span, "this is an unreachable pattern");
diagnostic.span_note(catchall, "this pattern matches any value");
err.span_label(pat.span, "this is an unreachable pattern");
err.span_note(catchall, "this pattern matches any value");
}
cx.tcx.sess.add_lint_diagnostic(lint::builtin::UNREACHABLE_PATTERNS,
hir_pat.id, diagnostic);
err.emit();
},
// Unreachable patterns in try expressions occur when one of the arms

View File

@ -638,7 +638,6 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
super::describe_lints(&sess.lint_store.borrow(), true);
return Err(CompileIncomplete::Stopped);
}
sess.track_errors(|| sess.lint_store.borrow_mut().process_command_line(sess))?;
// Currently, we ignore the name resolution data structures for the purposes of dependency
// tracking. Instead we will run name resolution and include its output in the hash of each
@ -708,8 +707,8 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
missing_fragment_specifiers.sort();
for span in missing_fragment_specifiers {
let lint = lint::builtin::MISSING_FRAGMENT_SPECIFIER;
let msg = "missing fragment specifier".to_string();
sess.add_lint(lint, ast::CRATE_NODE_ID, span, msg);
let msg = "missing fragment specifier";
sess.buffer_lint(lint, ast::CRATE_NODE_ID, span, msg);
}
if ecx.parse_sess.span_diagnostic.err_count() - ecx.resolve_err_count > err_count {
ecx.parse_sess.span_diagnostic.abort_if_errors();
@ -772,10 +771,6 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
"checking for inline asm in case the target doesn't support it",
|| no_asm::check_crate(sess, &krate));
time(time_passes,
"early lint checks",
|| lint::check_ast_crate(sess, &krate));
time(time_passes,
"AST validation",
|| ast_validation::check_crate(sess, &krate));
@ -800,6 +795,10 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
})
})?;
time(time_passes,
"early lint checks",
|| lint::check_ast_crate(sess, &krate));
// Lower ast -> hir.
let hir_forest = time(time_passes, "lowering ast -> hir", || {
let hir_crate = lower_crate(sess, &krate, &mut resolver);
@ -908,6 +907,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
rustc_const_eval::provide(&mut local_providers);
middle::region::provide(&mut local_providers);
cstore::provide_local(&mut local_providers);
lint::provide(&mut local_providers);
let mut extern_providers = ty::maps::Providers::default();
cstore::provide(&mut extern_providers);
@ -1194,10 +1194,10 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
}
Some(ref n) if *n == "bin" => Some(config::CrateTypeExecutable),
Some(_) => {
session.add_lint(lint::builtin::UNKNOWN_CRATE_TYPES,
ast::CRATE_NODE_ID,
a.span,
"invalid `crate_type` value".to_string());
session.buffer_lint(lint::builtin::UNKNOWN_CRATE_TYPES,
ast::CRATE_NODE_ID,
a.span,
"invalid `crate_type` value");
None
}
_ => {

View File

@ -36,7 +36,7 @@ use rustc::ty::{self, Ty};
use rustc::traits::{self, Reveal};
use rustc::hir::map as hir_map;
use util::nodemap::NodeSet;
use lint::{Level, LateContext, LintContext, LintArray};
use lint::{LateContext, LintContext, LintArray};
use lint::{LintPass, LateLintPass, EarlyLintPass, EarlyContext};
use std::collections::HashSet;
@ -876,16 +876,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion {
let mut db = cx.struct_span_lint(UNCONDITIONAL_RECURSION,
sp,
"function cannot return without recurring");
// FIXME #19668: these could be span_lint_note's instead of this manual guard.
if cx.current_level(UNCONDITIONAL_RECURSION) != Level::Allow {
// offer some help to the programmer.
for call in &self_call_spans {
db.span_note(*call, "recursive call site");
}
db.help("a `loop` may express intention \
better if this is on purpose");
// offer some help to the programmer.
for call in &self_call_spans {
db.span_note(*call, "recursive call site");
}
db.help("a `loop` may express intention \
better if this is on purpose");
db.emit();
}

View File

@ -237,10 +237,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.check_trait_fn_not_const(sig.constness);
if block.is_none() {
self.check_decl_no_pat(&sig.decl, |span, _| {
self.session.add_lint(lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY,
trait_item.id, span,
"patterns aren't allowed in methods \
without bodies".to_string());
self.session.buffer_lint(
lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY,
trait_item.id, span,
"patterns aren't allowed in methods \
without bodies");
});
}
}
@ -252,7 +253,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
if item.attrs.iter().any(|attr| attr.check_name("warn_directory_ownership")) {
let lint = lint::builtin::LEGACY_DIRECTORY_OWNERSHIP;
let msg = "cannot declare a new module at this location";
self.session.add_lint(lint, item.id, item.span, msg.to_string());
self.session.buffer_lint(lint, item.id, item.span, msg);
}
}
ItemKind::Union(ref vdata, _) => {

View File

@ -76,12 +76,12 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
ErroneousReferencedConstant(_) => {}
TypeckError => {}
_ => {
self.tcx.sess.add_lint(CONST_ERR,
expr.id,
expr.span,
format!("constant evaluation error: {}. This will \
become a HARD ERROR in the future",
err.description().into_oneline()))
self.tcx.lint_node(CONST_ERR,
expr.id,
expr.span,
&format!("constant evaluation error: {}. This will \
become a HARD ERROR in the future",
err.description().into_oneline()));
}
}
}
@ -260,10 +260,10 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> {
kind: LayoutError(ty::layout::LayoutError::Unknown(_)), ..
}) => {}
Err(msg) => {
self.tcx.sess.add_lint(CONST_ERR,
ex.id,
msg.span,
msg.description().into_oneline().into_owned())
self.tcx.lint_node(CONST_ERR,
ex.id,
msg.span,
&msg.description().into_oneline().into_owned());
}
}
}

View File

@ -1345,11 +1345,11 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
"private trait can't be public"))
.emit();
} else {
self.tcx.sess.add_lint(lint::builtin::PRIVATE_IN_PUBLIC,
node_id,
self.span,
format!("private trait `{}` in public \
interface (error E0445)", trait_ref));
self.tcx.lint_node(lint::builtin::PRIVATE_IN_PUBLIC,
node_id,
self.span,
&format!("private trait `{}` in public \
interface (error E0445)", trait_ref));
}
}
}
@ -1393,11 +1393,11 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'
err.span_label(self.span, "can't leak private type");
err.emit();
} else {
self.tcx.sess.add_lint(lint::builtin::PRIVATE_IN_PUBLIC,
node_id,
self.span,
format!("private type `{}` in public \
interface (error E0446)", ty));
self.tcx.lint_node(lint::builtin::PRIVATE_IN_PUBLIC,
node_id,
self.span,
&format!("private type `{}` in public \
interface (error E0446)", ty));
}
}
}

View File

@ -122,13 +122,13 @@ pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) {
directive.span.source_equal(&DUMMY_SP) => {}
ImportDirectiveSubclass::ExternCrate => {
let lint = lint::builtin::UNUSED_EXTERN_CRATES;
let msg = "unused extern crate".to_string();
resolver.session.add_lint(lint, directive.id, directive.span, msg);
let msg = "unused extern crate";
; resolver.session.buffer_lint(lint, directive.id, directive.span, msg)
}
ImportDirectiveSubclass::MacroUse => {
let lint = lint::builtin::UNUSED_IMPORTS;
let msg = "unused `#[macro_use]` import".to_string();
resolver.session.add_lint(lint, directive.id, directive.span, msg);
let msg = "unused `#[macro_use]` import";
resolver.session.buffer_lint(lint, directive.id, directive.span, msg);
}
_ => {}
}
@ -160,9 +160,6 @@ pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) {
} else {
String::new()
});
visitor.session.add_lint(lint::builtin::UNUSED_IMPORTS,
*id,
ms,
msg);
visitor.session.buffer_lint(lint::builtin::UNUSED_IMPORTS, *id, ms, &msg);
}
}

View File

@ -2552,9 +2552,10 @@ impl<'a> Resolver<'a> {
= self.struct_constructors.get(&def_id).cloned() {
if is_expected(ctor_def) && self.is_accessible(ctor_vis) {
let lint = lint::builtin::LEGACY_CONSTRUCTOR_VISIBILITY;
self.session.add_lint(lint, id, span,
self.session.buffer_lint(lint, id, span,
"private struct constructors are not usable through \
reexports in outer modules".to_string());
reexports in outer modules",
);
res = Some(PathResolution::new(ctor_def));
}
}
@ -2748,7 +2749,7 @@ impl<'a> Resolver<'a> {
};
if result.base_def() == unqualified_result {
let lint = lint::builtin::UNUSED_QUALIFICATIONS;
self.session.add_lint(lint, id, span, "unnecessary qualification".to_string());
self.session.buffer_lint(lint, id, span, "unnecessary qualification")
}
}
@ -3486,7 +3487,7 @@ impl<'a> Resolver<'a> {
span.push_span_label(b1.span, msg1);
span.push_span_label(b2.span, msg2);
let msg = format!("`{}` is ambiguous", name);
self.session.add_lint(lint::builtin::LEGACY_IMPORTS, id, span, msg);
self.session.buffer_lint(lint::builtin::LEGACY_IMPORTS, id, span, &msg);
} else {
let mut err =
self.session.struct_span_err(span, &format!("`{}` is ambiguous", name));
@ -3607,8 +3608,8 @@ impl<'a> Resolver<'a> {
fn warn_legacy_self_import(&self, directive: &'a ImportDirective<'a>) {
let (id, span) = (directive.id, directive.span);
let msg = "`self` no longer imports values".to_string();
self.session.add_lint(lint::builtin::LEGACY_IMPORTS, id, span, msg);
let msg = "`self` no longer imports values";
self.session.buffer_lint(lint::builtin::LEGACY_IMPORTS, id, span, msg);
}
fn check_proc_macro_attrs(&mut self, attrs: &[ast::Attribute]) {

View File

@ -319,8 +319,8 @@ impl<'a> base::Resolver for Resolver<'a> {
};
if let Some((id, span)) = id_span {
let lint = lint::builtin::UNUSED_MACROS;
let msg = "unused macro definition".to_string();
self.session.add_lint(lint, id, span, msg);
let msg = "unused macro definition";
self.session.buffer_lint(lint, id, span, msg);
} else {
bug!("attempted to create unused macro error, but span not available");
}

View File

@ -745,8 +745,10 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
let msg = format!("extern crate `{}` is private, and cannot be reexported \
(error E0365), consider declaring with `pub`",
ident);
self.session.add_lint(PUB_USE_OF_PRIVATE_EXTERN_CRATE,
directive.id, directive.span, msg);
self.session.buffer_lint(PUB_USE_OF_PRIVATE_EXTERN_CRATE,
directive.id,
directive.span,
&msg);
} else if ns == TypeNS {
struct_span_err!(self.session, directive.span, E0365,
"`{}` is private, and cannot be reexported", ident)

View File

@ -985,9 +985,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
.span_label(data.span, "only traits may use parentheses")
.emit();
} else {
let msg = "parenthesized parameters may only be used with a trait".to_string();
self.tcx().sess.add_lint(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
ast::CRATE_NODE_ID, data.span, msg);
let msg = "parenthesized parameters may only be used with a trait";
self.tcx().lint_node(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
ast::CRATE_NODE_ID, data.span, msg);
}
}
}

View File

@ -291,25 +291,25 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
let t_cast = self.cast_ty;
let t_expr = self.expr_ty;
if t_cast.is_numeric() && t_expr.is_numeric() {
fcx.tables.borrow_mut().lints.add_lint(
fcx.tcx.lint_node(
lint::builtin::TRIVIAL_NUMERIC_CASTS,
self.expr.id,
self.span,
format!("trivial numeric cast: `{}` as `{}`. Cast can be \
replaced by coercion, this might require type \
ascription or a temporary variable",
fcx.ty_to_string(t_expr),
fcx.ty_to_string(t_cast)));
&format!("trivial numeric cast: `{}` as `{}`. Cast can be \
replaced by coercion, this might require type \
ascription or a temporary variable",
fcx.ty_to_string(t_expr),
fcx.ty_to_string(t_cast)));
} else {
fcx.tables.borrow_mut().lints.add_lint(
fcx.tcx.lint_node(
lint::builtin::TRIVIAL_CASTS,
self.expr.id,
self.span,
format!("trivial cast: `{}` as `{}`. Cast can be \
replaced by coercion, this might require type \
ascription or a temporary variable",
fcx.ty_to_string(t_expr),
fcx.ty_to_string(t_cast)));
&format!("trivial cast: `{}` as `{}`. Cast can be \
replaced by coercion, this might require type \
ascription or a temporary variable",
fcx.ty_to_string(t_expr),
fcx.ty_to_string(t_cast)));
}
}

View File

@ -1713,10 +1713,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
self.tables.borrow_mut().lints.add_lint(
self.tcx().lint_node(
lint::builtin::UNREACHABLE_CODE,
id, span,
format!("unreachable {}", kind));
&format!("unreachable {}", kind));
}
}
@ -4746,8 +4746,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
} else {
let mut multispan = MultiSpan::from_span(lifetimes[0].span);
multispan.push_span_label(span_late, note_msg.to_string());
self.tcx.sess.add_lint(lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS,
lifetimes[0].id, multispan, primary_msg.to_string());
self.tcx.lint_node(lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS,
lifetimes[0].id, multispan, primary_msg);
}
return;
}

View File

@ -43,7 +43,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
wbcx.visit_fru_field_types();
wbcx.visit_anon_types();
wbcx.visit_cast_types();
wbcx.visit_lints();
wbcx.visit_free_region_map();
let used_trait_imports = mem::replace(&mut self.tables.borrow_mut().used_trait_imports,
@ -234,10 +233,6 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
self.fcx.tables.borrow().cast_kinds.iter().map(|(&key, &value)| (key, value)));
}
fn visit_lints(&mut self) {
self.fcx.tables.borrow_mut().lints.transfer(&mut self.tables.lints);
}
fn visit_free_region_map(&mut self) {
let free_region_map = self.tcx().lift_to_global(&self.fcx.tables.borrow().free_region_map);
let free_region_map = free_region_map.expect("all regions in free-region-map are global");

View File

@ -39,7 +39,7 @@ impl<'a, 'tcx> CheckVisitor<'a, 'tcx> {
} else {
"unused import".to_string()
};
self.tcx.sess.add_lint(lint::builtin::UNUSED_IMPORTS, id, span, msg);
self.tcx.lint_node(lint::builtin::UNUSED_IMPORTS, id, span, &msg);
}
}

View File

@ -999,12 +999,12 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
if !allow_defaults && p.default.is_some() {
if !tcx.sess.features.borrow().default_type_parameter_fallback {
tcx.sess.add_lint(
tcx.lint_node(
lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
p.id,
p.span,
format!("defaults for type parameters are only allowed in `struct`, \
`enum`, `type`, or `trait` definitions."));
&format!("defaults for type parameters are only allowed in `struct`, \
`enum`, `type`, or `trait` definitions."));
}
}

View File

@ -11,6 +11,7 @@
// aux-build:attributes-included.rs
#![feature(proc_macro, rustc_attrs)]
#![warn(unused)]
extern crate attributes_included;

View File

@ -9,6 +9,7 @@
// except according to those terms.
#![feature(box_syntax)]
#![allow(warnings)]
const CON : Box<i32> = box 0; //~ ERROR E0010
//~| NOTE allocation not allowed in

View File

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![allow(warnings)]
static A: u32 = 0;
static B: u32 = A;
//~^ ERROR E0394

View File

@ -10,6 +10,7 @@
// compile-flags: --cap-lints deny
#![warn(unused)]
#![deny(warnings)]
use std::option; //~ ERROR

View File

@ -10,6 +10,7 @@
// compile-flags: --cap-lints warn
#![warn(unused)]
#![deny(warnings)]
#![feature(rustc_attrs)]

View File

@ -12,6 +12,7 @@
// gate-test-drop_types_in_const
#![allow(warnings)]
#![feature(box_syntax)]
use std::marker;

View File

@ -11,7 +11,7 @@
// Evaluation of constants in refutable patterns goes through
// different compiler control-flow paths.
#![allow(unused_imports)]
#![allow(unused_imports, warnings)]
use std::fmt;
use std::{i8, i16, i32, i64, isize};

View File

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![allow(warnings)]
const x: bool = match Some(true) {
Some(value) => true,
//~^ ERROR: constant contains unimplemented expression type [E0019]

View File

@ -28,7 +28,6 @@ struct Foo<T> { data: Vec<T> }
impl<T> Drop for Foo<T> {
#[unsafe_destructor_blind_to_params] // This is the UGEH attribute
//~^ ERROR unsafe_destructor_blind_to_params has been replaced
//~^^ WARN: use of deprecated attribute
fn drop(&mut self) { }
}

View File

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![allow(safe_extern_statics, warnings)]
extern {
pub static symbol: ();
}

View File

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![allow(safe_extern_statics)]
mod Y {
pub type X = usize;
extern {

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![allow(dead_code)]
#![allow(dead_code, warnings)]
static mut x: isize = 3;
static mut y: isize = unsafe {

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![warn(unused)]
#[deny(warnings)]
const foo: isize = 3;

View File

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![allow(warnings)]
struct Struct { a: usize }
const C: usize = 1;

View File

@ -26,7 +26,7 @@ trait A<'a> {
}
impl<'a> A<'a> for B {
fn foo<F>(&mut self, f: F) //~ ERROR E0276
fn foo<F>(&mut self, f: F) //~ ERROR impl has stricter
//~^ WARNING future release
where F: fmt::Debug + 'static,
{

View File

@ -12,7 +12,7 @@
// aux-build:lint_stability.rs
#![allow(unused_imports)]
#![allow(warnings)]
extern crate lint_stability;

View File

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![allow(warnings)]
const X: u8 =
|| -> u8 { 5 }()
//~^ ERROR calls in constants are limited to constant functions

View File

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![allow(safe_extern_statics)]
extern {
static error_message_count: u32;
}

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![warn(unused)]
#![deny(warnings)] //~ NOTE: lint level defined here
use std::thread;
//~^ ERROR: unused import

View File

@ -9,6 +9,7 @@
// except according to those terms.
#![feature(rustc_attrs)]
#![warn(unused)]
type Z = for<'x> Send;
//~^ WARN type alias is never used

View File

@ -10,6 +10,7 @@
#![feature(box_syntax)]
#![feature(const_fn)]
#![allow(warnings)]
use std::cell::RefCell;

View File

@ -11,7 +11,8 @@
// No warnings about removed lint when
// allow(renamed_and_removed_lints)
#![allow(renamed_and_removed_lints)]
#[deny(raw_pointer_derive)]
#[allow(renamed_and_removed_lints)]
#[deny(unused_variables)]
fn main() { let unused = (); } //~ ERROR unused

View File

@ -16,5 +16,7 @@
// error-pattern:lint raw_pointer_derive has been removed
// error-pattern:requested on the command line with `-D raw_pointer_derive`
#![warn(unused)]
#[deny(warnings)]
fn main() { let unused = (); }

View File

@ -11,7 +11,8 @@
// No warnings about renamed lint when
// allow(renamed_and_removed_lints)
#![allow(renamed_and_removed_lints)]
#[deny(unknown_features)]
#[allow(renamed_and_removed_lints)]
#[deny(unused)]
fn main() { let unused = (); } //~ ERROR unused

View File

@ -13,9 +13,9 @@
// aux-build:stability_cfg1.rs
// aux-build:stability_cfg2.rs
#![deny(deprecated)]
#![warn(deprecated)]
#![allow(dead_code)]
#![feature(staged_api, test_feature)]
#![feature(staged_api, test_feature, rustc_attrs)]
#![stable(feature = "rust1", since = "1.0.0")]
@ -32,41 +32,41 @@ mod cross_crate {
type Foo = MethodTester;
let foo = MethodTester;
deprecated(); //~ ERROR use of deprecated item
foo.method_deprecated(); //~ ERROR use of deprecated item
Foo::method_deprecated(&foo); //~ ERROR use of deprecated item
<Foo>::method_deprecated(&foo); //~ ERROR use of deprecated item
foo.trait_deprecated(); //~ ERROR use of deprecated item
Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item
<Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item
<Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item
deprecated(); //~ WARN use of deprecated item
foo.method_deprecated(); //~ WARN use of deprecated item
Foo::method_deprecated(&foo); //~ WARN use of deprecated item
<Foo>::method_deprecated(&foo); //~ WARN use of deprecated item
foo.trait_deprecated(); //~ WARN use of deprecated item
Trait::trait_deprecated(&foo); //~ WARN use of deprecated item
<Foo>::trait_deprecated(&foo); //~ WARN use of deprecated item
<Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated item
deprecated_text(); //~ ERROR use of deprecated item: text
foo.method_deprecated_text(); //~ ERROR use of deprecated item: text
Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated item: text
<Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated item: text
foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
<Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
<Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
deprecated_text(); //~ WARN use of deprecated item: text
foo.method_deprecated_text(); //~ WARN use of deprecated item: text
Foo::method_deprecated_text(&foo); //~ WARN use of deprecated item: text
<Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated item: text
foo.trait_deprecated_text(); //~ WARN use of deprecated item: text
Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated item: text
<Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated item: text
<Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated item: text
deprecated_unstable(); //~ ERROR use of deprecated item
foo.method_deprecated_unstable(); //~ ERROR use of deprecated item
Foo::method_deprecated_unstable(&foo); //~ ERROR use of deprecated item
<Foo>::method_deprecated_unstable(&foo); //~ ERROR use of deprecated item
foo.trait_deprecated_unstable(); //~ ERROR use of deprecated item
Trait::trait_deprecated_unstable(&foo); //~ ERROR use of deprecated item
<Foo>::trait_deprecated_unstable(&foo); //~ ERROR use of deprecated item
<Foo as Trait>::trait_deprecated_unstable(&foo); //~ ERROR use of deprecated item
deprecated_unstable(); //~ WARN use of deprecated item
foo.method_deprecated_unstable(); //~ WARN use of deprecated item
Foo::method_deprecated_unstable(&foo); //~ WARN use of deprecated item
<Foo>::method_deprecated_unstable(&foo); //~ WARN use of deprecated item
foo.trait_deprecated_unstable(); //~ WARN use of deprecated item
Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item
<Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item
<Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item
deprecated_unstable_text(); //~ ERROR use of deprecated item: text
foo.method_deprecated_unstable_text(); //~ ERROR use of deprecated item: text
Foo::method_deprecated_unstable_text(&foo); //~ ERROR use of deprecated item: text
<Foo>::method_deprecated_unstable_text(&foo); //~ ERROR use of deprecated item: text
foo.trait_deprecated_unstable_text(); //~ ERROR use of deprecated item: text
Trait::trait_deprecated_unstable_text(&foo); //~ ERROR use of deprecated item: text
<Foo>::trait_deprecated_unstable_text(&foo); //~ ERROR use of deprecated item: text
<Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ ERROR use of deprecated item: text
deprecated_unstable_text(); //~ WARN use of deprecated item: text
foo.method_deprecated_unstable_text(); //~ WARN use of deprecated item: text
Foo::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated item: text
<Foo>::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated item: text
foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated item: text
Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item: text
<Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item: text
<Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item: text
unstable();
foo.method_unstable();
@ -106,30 +106,30 @@ mod cross_crate {
struct S1<T: TraitWithAssociatedTypes>(T::TypeUnstable);
struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated);
//~^ ERROR use of deprecated item
//~^ WARN use of deprecated item
let _ = DeprecatedStruct { //~ ERROR use of deprecated item
i: 0 //~ ERROR use of deprecated item
let _ = DeprecatedStruct { //~ WARN use of deprecated item
i: 0 //~ WARN use of deprecated item
};
let _ = DeprecatedUnstableStruct {
//~^ ERROR use of deprecated item
i: 0 //~ ERROR use of deprecated item
//~^ WARN use of deprecated item
i: 0 //~ WARN use of deprecated item
};
let _ = UnstableStruct { i: 0 };
let _ = StableStruct { i: 0 };
let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated item
let _ = DeprecatedUnstableUnitStruct; //~ ERROR use of deprecated item
let _ = DeprecatedUnitStruct; //~ WARN use of deprecated item
let _ = DeprecatedUnstableUnitStruct; //~ WARN use of deprecated item
let _ = UnstableUnitStruct;
let _ = StableUnitStruct;
let _ = Enum::DeprecatedVariant; //~ ERROR use of deprecated item
let _ = Enum::DeprecatedUnstableVariant; //~ ERROR use of deprecated item
let _ = Enum::DeprecatedVariant; //~ WARN use of deprecated item
let _ = Enum::DeprecatedUnstableVariant; //~ WARN use of deprecated item
let _ = Enum::UnstableVariant;
let _ = Enum::StableVariant;
let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated item
let _ = DeprecatedUnstableTupleStruct (1); //~ ERROR use of deprecated item
let _ = DeprecatedTupleStruct (1); //~ WARN use of deprecated item
let _ = DeprecatedUnstableTupleStruct (1); //~ WARN use of deprecated item
let _ = UnstableTupleStruct (1);
let _ = StableTupleStruct (1);
@ -138,28 +138,28 @@ mod cross_crate {
// Eventually, we will want to lint the contents of the
// macro in the module *defining* it. Also, stability levels
// on macros themselves are not yet linted.
macro_test_arg!(deprecated_text()); //~ ERROR use of deprecated item: text
macro_test_arg!(deprecated_unstable_text()); //~ ERROR use of deprecated item: text
macro_test_arg!(macro_test_arg!(deprecated_text())); //~ ERROR use of deprecated item: text
macro_test_arg!(deprecated_text()); //~ WARN use of deprecated item: text
macro_test_arg!(deprecated_unstable_text()); //~ WARN use of deprecated item: text
macro_test_arg!(macro_test_arg!(deprecated_text())); //~ WARN use of deprecated item: text
}
fn test_method_param<Foo: Trait>(foo: Foo) {
foo.trait_deprecated(); //~ ERROR use of deprecated item
Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item
<Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item
<Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item
foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
<Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
<Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
foo.trait_deprecated_unstable(); //~ ERROR use of deprecated item
Trait::trait_deprecated_unstable(&foo); //~ ERROR use of deprecated item
<Foo>::trait_deprecated_unstable(&foo); //~ ERROR use of deprecated item
<Foo as Trait>::trait_deprecated_unstable(&foo); //~ ERROR use of deprecated item
foo.trait_deprecated_unstable_text(); //~ ERROR use of deprecated item: text
Trait::trait_deprecated_unstable_text(&foo); //~ ERROR use of deprecated item: text
<Foo>::trait_deprecated_unstable_text(&foo); //~ ERROR use of deprecated item: text
<Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ ERROR use of deprecated item: text
foo.trait_deprecated(); //~ WARN use of deprecated item
Trait::trait_deprecated(&foo); //~ WARN use of deprecated item
<Foo>::trait_deprecated(&foo); //~ WARN use of deprecated item
<Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated item
foo.trait_deprecated_text(); //~ WARN use of deprecated item: text
Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated item: text
<Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated item: text
<Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated item: text
foo.trait_deprecated_unstable(); //~ WARN use of deprecated item
Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item
<Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item
<Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item
foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated item: text
Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item: text
<Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item: text
<Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item: text
foo.trait_unstable();
Trait::trait_unstable(&foo);
<Foo>::trait_unstable(&foo);
@ -175,10 +175,10 @@ mod cross_crate {
}
fn test_method_object(foo: &Trait) {
foo.trait_deprecated(); //~ ERROR use of deprecated item
foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
foo.trait_deprecated_unstable(); //~ ERROR use of deprecated item
foo.trait_deprecated_unstable_text(); //~ ERROR use of deprecated item: text
foo.trait_deprecated(); //~ WARN use of deprecated item
foo.trait_deprecated_text(); //~ WARN use of deprecated item: text
foo.trait_deprecated_unstable(); //~ WARN use of deprecated item
foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated item: text
foo.trait_unstable();
foo.trait_unstable_text();
foo.trait_stable();
@ -187,9 +187,9 @@ mod cross_crate {
struct S;
impl UnstableTrait for S { }
impl DeprecatedTrait for S {} //~ ERROR use of deprecated item: text
impl DeprecatedTrait for S {} //~ WARN use of deprecated item: text
trait LocalTrait : UnstableTrait { }
trait LocalTrait2 : DeprecatedTrait { } //~ ERROR use of deprecated item: text
trait LocalTrait2 : DeprecatedTrait { } //~ WARN use of deprecated item: text
impl Trait for S {
fn trait_stable(&self) {}
@ -208,7 +208,7 @@ mod inheritance {
stable_mod::unstable();
stable_mod::stable();
unstable_mod::deprecated(); //~ ERROR use of deprecated item
unstable_mod::deprecated(); //~ WARN use of deprecated item
unstable_mod::unstable();
let _ = Unstable::UnstableVariant;
@ -330,23 +330,23 @@ mod this_crate {
type Foo = MethodTester;
let foo = MethodTester;
deprecated(); //~ ERROR use of deprecated item
foo.method_deprecated(); //~ ERROR use of deprecated item
Foo::method_deprecated(&foo); //~ ERROR use of deprecated item
<Foo>::method_deprecated(&foo); //~ ERROR use of deprecated item
foo.trait_deprecated(); //~ ERROR use of deprecated item
Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item
<Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item
<Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item
deprecated(); //~ WARN use of deprecated item
foo.method_deprecated(); //~ WARN use of deprecated item
Foo::method_deprecated(&foo); //~ WARN use of deprecated item
<Foo>::method_deprecated(&foo); //~ WARN use of deprecated item
foo.trait_deprecated(); //~ WARN use of deprecated item
Trait::trait_deprecated(&foo); //~ WARN use of deprecated item
<Foo>::trait_deprecated(&foo); //~ WARN use of deprecated item
<Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated item
deprecated_text(); //~ ERROR use of deprecated item: text
foo.method_deprecated_text(); //~ ERROR use of deprecated item: text
Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated item: text
<Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated item: text
foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
<Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
<Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
deprecated_text(); //~ WARN use of deprecated item: text
foo.method_deprecated_text(); //~ WARN use of deprecated item: text
Foo::method_deprecated_text(&foo); //~ WARN use of deprecated item: text
<Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated item: text
foo.trait_deprecated_text(); //~ WARN use of deprecated item: text
Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated item: text
<Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated item: text
<Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated item: text
unstable();
foo.method_unstable();
@ -385,34 +385,34 @@ mod this_crate {
<Foo as Trait>::trait_stable_text(&foo);
let _ = DeprecatedStruct {
//~^ ERROR use of deprecated item
i: 0 //~ ERROR use of deprecated item
//~^ WARN use of deprecated item
i: 0 //~ WARN use of deprecated item
};
let _ = UnstableStruct { i: 0 };
let _ = StableStruct { i: 0 };
let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated item
let _ = DeprecatedUnitStruct; //~ WARN use of deprecated item
let _ = UnstableUnitStruct;
let _ = StableUnitStruct;
let _ = Enum::DeprecatedVariant; //~ ERROR use of deprecated item
let _ = Enum::DeprecatedVariant; //~ WARN use of deprecated item
let _ = Enum::UnstableVariant;
let _ = Enum::StableVariant;
let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated item
let _ = DeprecatedTupleStruct (1); //~ WARN use of deprecated item
let _ = UnstableTupleStruct (1);
let _ = StableTupleStruct (1);
}
fn test_method_param<Foo: Trait>(foo: Foo) {
foo.trait_deprecated(); //~ ERROR use of deprecated item
Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item
<Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item
<Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item
foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
<Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
<Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
foo.trait_deprecated(); //~ WARN use of deprecated item
Trait::trait_deprecated(&foo); //~ WARN use of deprecated item
<Foo>::trait_deprecated(&foo); //~ WARN use of deprecated item
<Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated item
foo.trait_deprecated_text(); //~ WARN use of deprecated item: text
Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated item: text
<Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated item: text
<Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated item: text
foo.trait_unstable();
Trait::trait_unstable(&foo);
<Foo>::trait_unstable(&foo);
@ -428,8 +428,8 @@ mod this_crate {
}
fn test_method_object(foo: &Trait) {
foo.trait_deprecated(); //~ ERROR use of deprecated item
foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
foo.trait_deprecated(); //~ WARN use of deprecated item
foo.trait_deprecated_text(); //~ WARN use of deprecated item: text
foo.trait_unstable();
foo.trait_unstable_text();
foo.trait_stable();
@ -439,7 +439,7 @@ mod this_crate {
#[rustc_deprecated(since = "1.0.0", reason = "text")]
fn test_fn_body() {
fn fn_in_body() {}
fn_in_body(); //~ ERROR use of deprecated item: text
fn_in_body(); //~ WARN use of deprecated item: text
}
impl MethodTester {
@ -447,7 +447,7 @@ mod this_crate {
#[rustc_deprecated(since = "1.0.0", reason = "text")]
fn test_method_body(&self) {
fn fn_in_body() {}
fn_in_body(); //~ ERROR use of deprecated item: text
fn_in_body(); //~ WARN use of deprecated item: text
}
}
@ -459,9 +459,9 @@ mod this_crate {
struct S;
impl DeprecatedTrait for S { } //~ ERROR use of deprecated item
impl DeprecatedTrait for S { } //~ WARN use of deprecated item
trait LocalTrait : DeprecatedTrait { } //~ ERROR use of deprecated item
trait LocalTrait : DeprecatedTrait { } //~ WARN use of deprecated item
}
fn main() {}
#[rustc_error] fn main() {} //~ ERROR: compilation successful

View File

@ -9,16 +9,18 @@
// except according to those terms.
//
#![deny(overflowing_literals)]
#![deny(const_err)]
#![warn(overflowing_literals)]
#![warn(const_err)]
#![feature(rustc_attrs)]
#[allow(unused_variables)]
fn main() {
let x2: i8 = --128; //~ error: literal out of range for i8
//~^ error: attempt to negate with overflow
#[rustc_error]
fn main() { //~ ERROR: compilation successful
let x2: i8 = --128; //~ warn: literal out of range for i8
//~^ warn: attempt to negate with overflow
let x = -3.40282357e+38_f32; //~ error: literal out of range for f32
let x = 3.40282357e+38_f32; //~ error: literal out of range for f32
let x = -1.7976931348623159e+308_f64; //~ error: literal out of range for f64
let x = 1.7976931348623159e+308_f64; //~ error: literal out of range for f64
let x = -3.40282357e+38_f32; //~ warn: literal out of range for f32
let x = 3.40282357e+38_f32; //~ warn: literal out of range for f32
let x = -1.7976931348623159e+308_f64; //~ warn: literal out of range for f64
let x = 1.7976931348623159e+308_f64; //~ warn: literal out of range for f64
}

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![warn(unused)]
#![allow(dead_code)]
#![deny(non_snake_case)]

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![warn(unused)]
#![deny(unused_variables)]
#![deny(unused_assignments)]
#![allow(dead_code, non_camel_case_types, trivial_numeric_casts)]

View File

@ -10,12 +10,12 @@
// Test that an assignment of type ! makes the rest of the block dead code.
#![feature(never_type)]
#![deny(unused, unreachable_code)]
#![feature(never_type, rustc_attrs)]
#![warn(unused)]
fn main() {
let x: ! = panic!("aah"); //~ ERROR unused
drop(x); //~ ERROR unreachable
//~^ ERROR unreachable
#[rustc_error]
fn main() { //~ ERROR: compilation successful
let x: ! = panic!("aah"); //~ WARN unused
drop(x); //~ WARN unreachable
//~^ WARN unreachable
}

View File

@ -11,6 +11,7 @@
#![feature(associated_consts)]
#![feature(conservative_impl_trait)]
#![feature(decl_macro)]
#![allow(warnings)]
mod m {
fn priv_fn() {}

View File

@ -11,6 +11,7 @@
// aux-build:private-inferred-type.rs
#![feature(conservative_impl_trait)]
#![allow(warnings)]
extern crate private_inferred_type as ext;

View File

@ -14,6 +14,7 @@
static mut a: Box<isize> = box 3;
//~^ ERROR allocations are not allowed in statics
//~^^ ERROR destructors in statics are an unstable feature
//~| ERROR destructors in statics are an unstable feature
//~| WARN: constant evaluation error
fn main() {}

View File

@ -8,9 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(never_type)]
#![deny(unreachable_code)]
#![deny(unreachable_patterns)]
#![feature(never_type, rustc_attrs)]
#![warn(unreachable_code)]
#![warn(unreachable_patterns)]
enum Void {}
@ -26,8 +26,8 @@ fn bar(x: Result<!, i32>) -> Result<u32, i32> {
fn foo(x: Result<!, i32>) -> Result<u32, i32> {
let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?;
//~^ ERROR unreachable pattern
//~| ERROR unreachable expression
//~^ WARN unreachable pattern
//~| WARN unreachable expression
Ok(y)
}
@ -37,11 +37,12 @@ fn qux(x: Result<u32, Void>) -> Result<u32, i32> {
fn vom(x: Result<u32, Void>) -> Result<u32, i32> {
let y = (match x { Ok(n) => Ok(n), Err(e) => Err(e) })?;
//~^ ERROR unreachable pattern
//~^ WARN unreachable pattern
Ok(y)
}
fn main() {
#[rustc_error]
fn main() { //~ ERROR: compilation successful
let _ = bar(Err(123));
let _ = foo(Err(123));
let _ = qux(Ok(123));

View File

@ -14,6 +14,7 @@
// compile-flags: -A test-lint
#![feature(plugin)]
#![warn(unused)]
#![plugin(lint_plugin_test)]
fn lintme() { }

View File

@ -1,8 +1,13 @@
warning: function is never used: `lintme`
--> $DIR/lint-plugin-cmdline-allow.rs:19:1
--> $DIR/lint-plugin-cmdline-allow.rs:20:1
|
19 | fn lintme() { }
20 | fn lintme() { }
| ^^^^^^^^^^^^^^^
|
= note: #[warn(dead_code)] on by default
note: lint level defined here
--> $DIR/lint-plugin-cmdline-allow.rs:17:9
|
17 | #![warn(unused)]
| ^^^^^^
= note: #[warn(dead_code)] implied by #[warn(unused)]

View File

@ -9,6 +9,7 @@
// except according to those terms.
#![feature(exclusive_range_pattern)]
#![warn(unreachable_patterns)]
fn main() {
// These cases should generate no warning.

View File

@ -1,20 +1,24 @@
warning: unreachable pattern
--> $DIR/issue-43253.rs:36:9
--> $DIR/issue-43253.rs:37:9
|
36 | 9 => {},
37 | 9 => {},
| ^
|
= note: #[warn(unreachable_patterns)] on by default
note: lint level defined here
--> $DIR/issue-43253.rs:12:9
|
12 | #![warn(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
warning: unreachable pattern
--> $DIR/issue-43253.rs:42:9
--> $DIR/issue-43253.rs:43:9
|
42 | 8...9 => {},
43 | 8...9 => {},
| ^^^^^
warning: unreachable pattern
--> $DIR/issue-43253.rs:48:9
--> $DIR/issue-43253.rs:49:9
|
48 | 9...9 => {},
49 | 9...9 => {},
| ^^^^^

View File

@ -1,4 +1,4 @@
error[E0276]: impl has stricter requirements than trait
error: impl has stricter requirements than trait
--> $DIR/proj-outlives-region.rs:19:5
|
14 | fn foo() where T: 'a;

View File

@ -1,4 +1,4 @@
error[E0276]: impl has stricter requirements than trait
error: impl has stricter requirements than trait
--> $DIR/region-unrelated.rs:19:5
|
14 | fn foo() where T: 'a;

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![warn(unused_must_use)]
struct MyStruct {
n: usize

View File

@ -1,14 +1,18 @@
warning: unused return value of `need_to_use_this_value` which must be used: it's important
--> $DIR/fn_must_use.rs:29:5
--> $DIR/fn_must_use.rs:30:5
|
29 | need_to_use_this_value();
30 | need_to_use_this_value();
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(unused_must_use)] on by default
note: lint level defined here
--> $DIR/fn_must_use.rs:11:9
|
11 | #![warn(unused_must_use)]
| ^^^^^^^^^^^^^^^
warning: unused return value of `MyStruct::need_to_use_this_method_value` which must be used
--> $DIR/fn_must_use.rs:32:5
--> $DIR/fn_must_use.rs:33:5
|
32 | m.need_to_use_this_method_value();
33 | m.need_to_use_this_method_value();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -16,7 +16,13 @@
#![forbid(unused, non_snake_case)]
#[allow(unused, unused_variables, bad_style)]
#[allow(unused_variables)]
fn foo() {}
#[allow(unused)]
fn bar() {}
#[allow(bad_style)]
fn main() {
println!("hello forbidden world")
}

View File

@ -1,29 +1,29 @@
error[E0453]: allow(unused) overruled by outer forbid(unused)
error[E0453]: allow(unused_variables) overruled by outer forbid(unused)
--> $DIR/outer-forbid.rs:19:9
|
17 | #![forbid(unused, non_snake_case)]
| ------ `forbid` level set here
18 |
19 | #[allow(unused, unused_variables, bad_style)]
| ^^^^^^ overruled by previous forbid
19 | #[allow(unused_variables)]
| ^^^^^^^^^^^^^^^^ overruled by previous forbid
error[E0453]: allow(unused_variables) overruled by outer forbid(unused)
--> $DIR/outer-forbid.rs:19:17
error[E0453]: allow(unused) overruled by outer forbid(unused)
--> $DIR/outer-forbid.rs:22:9
|
17 | #![forbid(unused, non_snake_case)]
| ------ `forbid` level set here
18 |
19 | #[allow(unused, unused_variables, bad_style)]
| ^^^^^^^^^^^^^^^^ overruled by previous forbid
...
22 | #[allow(unused)]
| ^^^^^^ overruled by previous forbid
error[E0453]: allow(bad_style) overruled by outer forbid(non_snake_case)
--> $DIR/outer-forbid.rs:19:35
--> $DIR/outer-forbid.rs:25:9
|
17 | #![forbid(unused, non_snake_case)]
| -------------- `forbid` level set here
18 |
19 | #[allow(unused, unused_variables, bad_style)]
| ^^^^^^^^^ overruled by previous forbid
...
25 | #[allow(bad_style)]
| ^^^^^^^^^ overruled by previous forbid
error: aborting due to 3 previous errors

View File

@ -10,6 +10,8 @@
// run-pass
#![warn(unused)]
// Parser test for #37765
fn with_parens<T: ToString>(arg: T) -> String { //~WARN function is never used: `with_parens`

View File

@ -1,26 +1,31 @@
warning: unnecessary parentheses around `return` value
--> $DIR/path-lookahead.rs:16:10
--> $DIR/path-lookahead.rs:18:10
|
16 | return (<T as ToString>::to_string(&arg)); //~WARN unnecessary parentheses around `return` value
18 | return (<T as ToString>::to_string(&arg)); //~WARN unnecessary parentheses around `return` value
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(unused_parens)] on by default
warning: function is never used: `with_parens`
--> $DIR/path-lookahead.rs:15:1
--> $DIR/path-lookahead.rs:17:1
|
15 | / fn with_parens<T: ToString>(arg: T) -> String { //~WARN function is never used: `with_parens`
16 | | return (<T as ToString>::to_string(&arg)); //~WARN unnecessary parentheses around `return` value
17 | | }
17 | / fn with_parens<T: ToString>(arg: T) -> String { //~WARN function is never used: `with_parens`
18 | | return (<T as ToString>::to_string(&arg)); //~WARN unnecessary parentheses around `return` value
19 | | }
| |_^
|
= note: #[warn(dead_code)] on by default
note: lint level defined here
--> $DIR/path-lookahead.rs:13:9
|
13 | #![warn(unused)]
| ^^^^^^
= note: #[warn(dead_code)] implied by #[warn(unused)]
warning: function is never used: `no_parens`
--> $DIR/path-lookahead.rs:19:1
--> $DIR/path-lookahead.rs:21:1
|
19 | / fn no_parens<T: ToString>(arg: T) -> String { //~WARN function is never used: `no_parens`
20 | | return <T as ToString>::to_string(&arg);
21 | | }
21 | / fn no_parens<T: ToString>(arg: T) -> String { //~WARN function is never used: `no_parens`
22 | | return <T as ToString>::to_string(&arg);
23 | | }
| |_^

View File

@ -1,8 +1,20 @@
error: unreachable expression
--> $DIR/expr_unary.rs:18:28
|
18 | let x: ! = ! { return; 22 };
| ^^
|
note: lint level defined here
--> $DIR/expr_unary.rs:14:9
|
14 | #![deny(unreachable_code)]
| ^^^^^^^^^^^^^^^^
error[E0600]: cannot apply unary operator `!` to type `!`
--> $DIR/expr_unary.rs:18:16
|
18 | let x: ! = ! { return; 22 };
| ^^^^^^^^^^^^^^^^
error: aborting due to previous error
error: aborting due to 2 previous errors

View File

@ -11,10 +11,13 @@
//! A test to ensure that helpful `note` messages aren't emitted more often
//! than necessary.
// Although there are three errors, we should only get two "lint level defined
// here" notes pointing at the `warnings` span, one for each error type.
#![deny(warnings)]
#![feature(rustc_attrs)]
// Although there are three warnings, we should only get two "lint level defined
// here" notes pointing at the `warnings` span, one for each error type.
#![warn(unused)]
#[rustc_error]
fn main() {
let theTwo = 2;
let theOtherTwo = 2;

View File

@ -1,34 +1,37 @@
error: variable `theTwo` should have a snake case name such as `the_two`
--> $DIR/issue-24690.rs:19:9
warning: unused variable: `theOtherTwo`
--> $DIR/issue-24690.rs:23:9
|
19 | let theTwo = 2;
23 | let theOtherTwo = 2;
| ^^^^^^^^^^^
|
note: lint level defined here
--> $DIR/issue-24690.rs:18:9
|
18 | #![warn(unused)]
| ^^^^^^
= note: #[warn(unused_variables)] implied by #[warn(unused)]
warning: variable `theTwo` should have a snake case name such as `the_two`
--> $DIR/issue-24690.rs:22:9
|
22 | let theTwo = 2;
| ^^^^^^
|
note: lint level defined here
--> $DIR/issue-24690.rs:16:9
|
16 | #![deny(warnings)]
| ^^^^^^^^
= note: #[deny(non_snake_case)] implied by #[deny(warnings)]
= note: #[warn(non_snake_case)] on by default
error: variable `theOtherTwo` should have a snake case name such as `the_other_two`
--> $DIR/issue-24690.rs:20:9
warning: variable `theOtherTwo` should have a snake case name such as `the_other_two`
--> $DIR/issue-24690.rs:23:9
|
20 | let theOtherTwo = 2;
23 | let theOtherTwo = 2;
| ^^^^^^^^^^^
error: unused variable: `theOtherTwo`
--> $DIR/issue-24690.rs:20:9
error: compilation successful
--> $DIR/issue-24690.rs:21:1
|
20 | let theOtherTwo = 2;
| ^^^^^^^^^^^
|
note: lint level defined here
--> $DIR/issue-24690.rs:16:9
|
16 | #![deny(warnings)]
| ^^^^^^^^
= note: #[deny(unused_variables)] implied by #[deny(warnings)]
error: aborting due to 3 previous errors
21 | / fn main() {
22 | | let theTwo = 2;
23 | | let theOtherTwo = 2;
24 | | println!("{}", theTwo);
25 | | }
| |_^

View File

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![warn(unused)]
macro_rules! m {
($a:tt $b:tt) => {
$b $a;

View File

@ -1,11 +1,16 @@
warning: struct is never used: `S`
--> $DIR/macro-span-replacement.rs:13:9
--> $DIR/macro-span-replacement.rs:15:9
|
13 | $b $a;
15 | $b $a;
| ^^^^^^
...
18 | m!(S struct);
20 | m!(S struct);
| ------------- in this macro invocation
|
= note: #[warn(dead_code)] on by default
note: lint level defined here
--> $DIR/macro-span-replacement.rs:11:9
|
11 | #![warn(unused)]
| ^^^^^^
= note: #[warn(dead_code)] implied by #[warn(unused)]

View File

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![warn(unused)]
use std::cmp::{Eq, Ord, min, PartialEq, PartialOrd};
fn main() {

View File

@ -1,8 +1,13 @@
warning: unused imports: `Eq`, `Ord`, `PartialEq`, `PartialOrd`
--> $DIR/multispan-import-lint.rs:11:16
--> $DIR/multispan-import-lint.rs:13:16
|
11 | use std::cmp::{Eq, Ord, min, PartialEq, PartialOrd};
13 | use std::cmp::{Eq, Ord, min, PartialEq, PartialOrd};
| ^^ ^^^ ^^^^^^^^^ ^^^^^^^^^^
|
= note: #[warn(unused_imports)] on by default
note: lint level defined here
--> $DIR/multispan-import-lint.rs:11:9
|
11 | #![warn(unused)]
| ^^^^^^
= note: #[warn(unused_imports)] implied by #[warn(unused)]

View File

@ -1156,9 +1156,21 @@ actual:\n\
fn compile_test(&self) -> ProcRes {
let aux_dir = self.aux_output_dir_name();
// FIXME (#9639): This needs to handle non-utf8 paths
let link_args = vec!["-L".to_owned(),
aux_dir.to_str().unwrap().to_owned()];
let args = self.make_compile_args(link_args,
let mut extra_args = vec!["-L".to_owned(),
aux_dir.to_str().unwrap().to_owned()];
match self.config.mode {
CompileFail | Ui => {
// compile-fail and ui tests tend to have tons of unused code as
// it's just testing various pieces of the compile, but we don't
// want to actually assert warnings about all this code. Instead
// let's just ignore unused code warnings by defaults and tests
// can turn it back on if needed.
extra_args.push("-A".to_owned());
extra_args.push("unused".to_owned());
}
_ => {}
}
let args = self.make_compile_args(extra_args,
&self.testpaths.file,
TargetLocation::ThisFile(self.make_exe_name()));
self.compose_and_run_compiler(args, None)