mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-06 12:54:51 +00:00
Auto merge of #21610 - sfackler:debug-lint, r=alexcrichton
Closes #20855 r? @alexcrichton
This commit is contained in:
commit
59dcba5d14
@ -245,6 +245,7 @@ pub trait Show {
|
||||
#[unstable = "I/O and core have yet to be reconciled"]
|
||||
#[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is defined in your \
|
||||
crate, add `#[derive(Debug)]` or manually implement it"]
|
||||
#[lang = "debug_trait"]
|
||||
pub trait Debug {
|
||||
/// Formats the value using the given formatter.
|
||||
fn fmt(&self, &mut Formatter) -> Result;
|
||||
|
@ -1627,6 +1627,69 @@ impl LintPass for MissingCopyImplementations {
|
||||
}
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
MISSING_DEBUG_IMPLEMENTATIONS,
|
||||
Allow,
|
||||
"detects missing implementations of fmt::Debug"
|
||||
}
|
||||
|
||||
pub struct MissingDebugImplementations {
|
||||
impling_types: Option<NodeSet>,
|
||||
}
|
||||
|
||||
impl MissingDebugImplementations {
|
||||
pub fn new() -> MissingDebugImplementations {
|
||||
MissingDebugImplementations {
|
||||
impling_types: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LintPass for MissingDebugImplementations {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(MISSING_DEBUG_IMPLEMENTATIONS)
|
||||
}
|
||||
|
||||
fn check_item(&mut self, cx: &Context, item: &ast::Item) {
|
||||
if !cx.exported_items.contains(&item.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
match item.node {
|
||||
ast::ItemStruct(..) | ast::ItemEnum(..) => {},
|
||||
_ => return,
|
||||
}
|
||||
|
||||
let debug = match cx.tcx.lang_items.debug_trait() {
|
||||
Some(debug) => debug,
|
||||
None => return,
|
||||
};
|
||||
|
||||
if self.impling_types.is_none() {
|
||||
let impls = cx.tcx.trait_impls.borrow();
|
||||
let impls = match impls.get(&debug) {
|
||||
Some(impls) => {
|
||||
impls.borrow().iter()
|
||||
.filter(|d| d.krate == ast::LOCAL_CRATE)
|
||||
.filter_map(|d| ty::ty_to_def_id(ty::node_id_to_type(cx.tcx, d.node)))
|
||||
.map(|d| d.node)
|
||||
.collect()
|
||||
}
|
||||
None => NodeSet(),
|
||||
};
|
||||
self.impling_types = Some(impls);
|
||||
debug!("{:?}", self.impling_types);
|
||||
}
|
||||
|
||||
if !self.impling_types.as_ref().unwrap().contains(&item.id) {
|
||||
cx.span_lint(MISSING_DEBUG_IMPLEMENTATIONS,
|
||||
item.span,
|
||||
"type does not implement `fmt::Debug`; consider adding #[derive(Debug)] \
|
||||
or a manual implementation")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
DEPRECATED,
|
||||
Warn,
|
||||
|
@ -219,6 +219,7 @@ impl LintStore {
|
||||
RawPointerDerive,
|
||||
MissingDoc,
|
||||
Stability,
|
||||
MissingDebugImplementations,
|
||||
);
|
||||
|
||||
add_lint_group!(sess, "bad_style",
|
||||
|
@ -328,4 +328,6 @@ lets_do_this! {
|
||||
IteratorItem, "iterator", iterator;
|
||||
|
||||
StackExhaustedLangItem, "stack_exhausted", stack_exhausted;
|
||||
|
||||
DebugTraitLangItem, "debug_trait", debug_trait;
|
||||
}
|
||||
|
48
src/test/compile-fail/missing_debug_impls.rs
Normal file
48
src/test/compile-fail/missing_debug_impls.rs
Normal file
@ -0,0 +1,48 @@
|
||||
// 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.
|
||||
|
||||
// compile-flags: --crate-type lib
|
||||
#![deny(missing_debug_implementations)]
|
||||
#![allow(unused, unstable, missing_copy_implementations)]
|
||||
|
||||
use std::fmt;
|
||||
|
||||
pub enum A {} //~ ERROR type does not implement `fmt::Debug`
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum B {}
|
||||
|
||||
pub enum C {}
|
||||
|
||||
impl fmt::Debug for C {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Foo; //~ ERROR type does not implement `fmt::Debug`
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Bar;
|
||||
|
||||
pub struct Baz;
|
||||
|
||||
impl fmt::Debug for Baz {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
struct PrivateStruct;
|
||||
|
||||
enum PrivateEnum {}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct GenericType<T>(T);
|
Loading…
Reference in New Issue
Block a user