mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-22 12:43:36 +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"]
|
#[unstable = "I/O and core have yet to be reconciled"]
|
||||||
#[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is defined in your \
|
#[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is defined in your \
|
||||||
crate, add `#[derive(Debug)]` or manually implement it"]
|
crate, add `#[derive(Debug)]` or manually implement it"]
|
||||||
|
#[lang = "debug_trait"]
|
||||||
pub trait Debug {
|
pub trait Debug {
|
||||||
/// Formats the value using the given formatter.
|
/// Formats the value using the given formatter.
|
||||||
fn fmt(&self, &mut Formatter) -> Result;
|
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! {
|
declare_lint! {
|
||||||
DEPRECATED,
|
DEPRECATED,
|
||||||
Warn,
|
Warn,
|
||||||
|
@ -219,6 +219,7 @@ impl LintStore {
|
|||||||
RawPointerDerive,
|
RawPointerDerive,
|
||||||
MissingDoc,
|
MissingDoc,
|
||||||
Stability,
|
Stability,
|
||||||
|
MissingDebugImplementations,
|
||||||
);
|
);
|
||||||
|
|
||||||
add_lint_group!(sess, "bad_style",
|
add_lint_group!(sess, "bad_style",
|
||||||
|
@ -328,4 +328,6 @@ lets_do_this! {
|
|||||||
IteratorItem, "iterator", iterator;
|
IteratorItem, "iterator", iterator;
|
||||||
|
|
||||||
StackExhaustedLangItem, "stack_exhausted", stack_exhausted;
|
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