diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index e1605959922..70f03e02f46 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -192,6 +192,13 @@ declare_lint! { "lifetimes or labels named `'_` were erroneously allowed" } +declare_lint! { + pub RESOLVE_TRAIT_ON_DEFAULTED_UNIT, + Warn, + "attempt to resolve a trait on an expression whose type cannot be inferred but which \ + currently defaults to ()" +} + declare_lint! { pub SAFE_EXTERN_STATICS, Warn, @@ -272,6 +279,7 @@ impl LintPass for HardwiredLints { SUPER_OR_SELF_IN_GLOBAL_PATH, HR_LIFETIME_IN_ASSOC_TYPE, LIFETIME_UNDERSCORE, + RESOLVE_TRAIT_ON_DEFAULTED_UNIT, SAFE_EXTERN_STATICS, PATTERNS_IN_FNS_WITHOUT_BODY, EXTRA_REQUIREMENT_IN_IMPL, diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index d5efc8f1893..41f3f825c3d 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -52,6 +52,7 @@ use std::mem; use std::rc::Rc; use syntax::abi::Abi; use hir; +use lint; use util::nodemap::FxHashMap; struct InferredObligationsSnapshotVecDelegate<'tcx> { @@ -455,13 +456,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } if raise_warning { - let sess = tcx.sess; - let span = obligation.cause.span; - let mut warn = sess.struct_span_warn(span, "code relies on type inference rules \ - which are likely to change"); - warn.span_label(span, &"the type of this expression may change from () \ - to ! in a future version of Rust"); - warn.emit(); + 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")); } } Ok(ret) diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 18067cb8673..81ba49f56f0 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -220,6 +220,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { id: LintId::of(LIFETIME_UNDERSCORE), reference: "issue #36892 ", }, + FutureIncompatibleInfo { + id: LintId::of(RESOLVE_TRAIT_ON_DEFAULTED_UNIT), + reference: "issue #39216 ", + }, FutureIncompatibleInfo { id: LintId::of(SAFE_EXTERN_STATICS), reference: "issue #36247 ", diff --git a/src/test/compile-fail/defaulted-unit-warning.rs b/src/test/compile-fail/defaulted-unit-warning.rs new file mode 100644 index 00000000000..7a15ac025ef --- /dev/null +++ b/src/test/compile-fail/defaulted-unit-warning.rs @@ -0,0 +1,26 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![deny(resolve_trait_on_defaulted_unit)] + +trait Deserialize { + fn deserialize() -> Result +} + +fn doit() -> Result<(), String> { + let _ = Deserialize::deserialize()?; + //~^ ERROR attempt to resolve a trait + Ok(()) +} + +fn main() { + doit(); +} +