提交 70214915 编写于 作者: S Steven Fackler

Add a missing fmt::Debug impl lint

Closes #20855
上级 d1519231
......@@ -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 @@ fn check_item(&mut self, cx: &Context, item: &ast::Item) {
}
}
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 @@ pub fn register_builtin(&mut self, sess: Option<&Session>) {
RawPointerDerive,
MissingDoc,
Stability,
MissingDebugImplementations,
);
add_lint_group!(sess, "bad_style",
......
......@@ -328,4 +328,6 @@ pub fn collect_language_items(krate: &ast::Crate,
IteratorItem, "iterator", iterator;
StackExhaustedLangItem, "stack_exhausted", stack_exhausted;
DebugTraitLangItem, "debug_trait", debug_trait;
}
// 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);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册