Skip to content

Commit

Permalink
Add a missing fmt::Debug impl lint
Browse files Browse the repository at this point in the history
Closes #20855
  • Loading branch information
sfackler committed Jan 25, 2015
1 parent d151923 commit 7021491
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/libcore/fmt/mod.rs
Expand Up @@ -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;
Expand Down
63 changes: 63 additions & 0 deletions src/librustc/lint/builtin.rs
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions src/librustc/lint/context.rs
Expand Up @@ -219,6 +219,7 @@ impl LintStore {
RawPointerDerive,
MissingDoc,
Stability,
MissingDebugImplementations,
);

add_lint_group!(sess, "bad_style",
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/middle/lang_items.rs
Expand Up @@ -328,4 +328,6 @@ lets_do_this! {
IteratorItem, "iterator", iterator;

StackExhaustedLangItem, "stack_exhausted", stack_exhausted;

DebugTraitLangItem, "debug_trait", debug_trait;
}
48 changes: 48 additions & 0 deletions src/test/compile-fail/missing_debug_impls.rs
@@ -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);

0 comments on commit 7021491

Please sign in to comment.