From 87b6d386541c6f7a409775296da1cda2da469c36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 29 Oct 2016 22:57:23 -0700 Subject: [PATCH] Don't hint to add lifetime on trait impl Don't provide hint to add lifetime on impl items that implement a trait. ```rust use std::str::FromStr; pub struct Foo<'a> { field: &'a str, } impl<'a> FromStr for Foo<'a> { type Err = (); fn from_str(path: &str) -> Result { Ok(Foo { field: path }) } } ``` would give the following hint: ```nocode help: consider using an explicit lifetime parameter as shown: fn from_str(path: &'a str) -> Result --> :9:5 | 9 | fn from_str(path: &str) -> Result { | ^ ``` which is never correct, since then there will be a lifetime mismatch between the impl and the trait. Remove this hint for impl items that implement a trait. --- src/librustc/infer/error_reporting.rs | 35 +++++++++++-------- ...time-inference-give-expl-lifetime-param.rs | 2 -- .../consider-using-explicit-lifetime.rs | 28 +++++++++++++++ .../consider-using-explicit-lifetime.stderr | 22 ++++++++++++ 4 files changed, 71 insertions(+), 16 deletions(-) create mode 100644 src/test/ui/lifetimes/consider-using-explicit-lifetime.rs create mode 100644 src/test/ui/lifetimes/consider-using-explicit-lifetime.stderr diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs index 47c0bc5fd60c5..75334a517fb3b 100644 --- a/src/librustc/infer/error_reporting.rs +++ b/src/librustc/infer/error_reporting.rs @@ -1052,21 +1052,28 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { match item.node { hir::ItemFn(ref fn_decl, unsafety, constness, _, ref gen, _) => { Some((fn_decl, gen, unsafety, constness, item.name, item.span)) - }, - _ => None + } + _ => None, } } ast_map::NodeImplItem(item) => { - match item.node { - hir::ImplItemKind::Method(ref sig, _) => { - Some((&sig.decl, - &sig.generics, - sig.unsafety, - sig.constness, - item.name, - item.span)) + let id = self.tcx.map.get_parent(item.id); + if let Some(ast_map::NodeItem(parent_scope)) = self.tcx.map.find(id) { + if let hir::ItemImpl(_, _, _, None, _, _) = parent_scope.node { + // this impl scope implements a trait, do not recomend + // using explicit lifetimes (#37363) + return; } - _ => None, + } + if let hir::ImplItemKind::Method(ref sig, _) = item.node { + Some((&sig.decl, + &sig.generics, + sig.unsafety, + sig.constness, + item.name, + item.span)) + } else { + None } }, ast_map::NodeTraitItem(item) => { @@ -1079,12 +1086,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { item.name, item.span)) } - _ => None + _ => None, } } - _ => None + _ => None, }, - None => None + None => None, }; let (fn_decl, generics, unsafety, constness, name, span) = node_inner.expect("expect item fn"); diff --git a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs index 6da87fca3f356..4323929e2e37a 100644 --- a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs +++ b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs @@ -49,8 +49,6 @@ struct Baz<'x> { impl<'a> Baz<'a> { fn baz2<'b>(&self, x: &isize) -> (&'b isize, &'b isize) { - //~^ HELP consider using an explicit lifetime parameter as shown: fn baz2<'b>(&self, x: &' - // FIXME #35038: The above suggestion is different on Linux and Mac. (self.bar, x) //~ ERROR E0312 //~^ ERROR E0312 } diff --git a/src/test/ui/lifetimes/consider-using-explicit-lifetime.rs b/src/test/ui/lifetimes/consider-using-explicit-lifetime.rs new file mode 100644 index 0000000000000..603f55af465f4 --- /dev/null +++ b/src/test/ui/lifetimes/consider-using-explicit-lifetime.rs @@ -0,0 +1,28 @@ +// 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. + +use std::str::FromStr; + +pub struct Foo<'a> { + field: &'a str, +} + +impl<'a> Foo<'a> { + fn bar(path: &str) -> Result { + Ok(Foo { field: path }) + } +} + +impl<'a> FromStr for Foo<'a> { + type Err = (); + fn from_str(path: &str) -> Result { + Ok(Foo { field: path }) + } +} diff --git a/src/test/ui/lifetimes/consider-using-explicit-lifetime.stderr b/src/test/ui/lifetimes/consider-using-explicit-lifetime.stderr new file mode 100644 index 0000000000000..353e251369a10 --- /dev/null +++ b/src/test/ui/lifetimes/consider-using-explicit-lifetime.stderr @@ -0,0 +1,22 @@ +error: main function not found + +error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements + --> $DIR/consider-using-explicit-lifetime.rs:19:12 + | +19 | Ok(Foo { field: path }) + | ^^^ + +error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements + --> $DIR/consider-using-explicit-lifetime.rs:26:12 + | +26 | Ok(Foo { field: path }) + | ^^^ + | +help: consider using an explicit lifetime parameter as shown: fn from_str(path: &'a str) -> Result + --> $DIR/consider-using-explicit-lifetime.rs:25:5 + | +25 | fn from_str(path: &str) -> Result { + | ^ + +error: aborting due to 2 previous errors +