From bbe7a96bec86eead5b6411856b92cfa012947195 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 11 Aug 2023 03:13:35 +0000 Subject: [PATCH] Record binder for bare trait object in LifetimeCollectVisitor --- .../src/lifetime_collector.rs | 17 +++++++- ...esh-lifetime-from-bare-trait-obj-114664.rs | 22 ++++++++++ ...lifetime-from-bare-trait-obj-114664.stderr | 42 +++++++++++++++++++ 3 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.rs create mode 100644 tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr diff --git a/compiler/rustc_ast_lowering/src/lifetime_collector.rs b/compiler/rustc_ast_lowering/src/lifetime_collector.rs index 0e0bdf1738918..6f75419c38765 100644 --- a/compiler/rustc_ast_lowering/src/lifetime_collector.rs +++ b/compiler/rustc_ast_lowering/src/lifetime_collector.rs @@ -1,7 +1,7 @@ use super::ResolverAstLoweringExt; use rustc_ast::visit::{self, BoundKind, LifetimeCtxt, Visitor}; use rustc_ast::{GenericBounds, Lifetime, NodeId, PathSegment, PolyTraitRef, Ty, TyKind}; -use rustc_hir::def::LifetimeRes; +use rustc_hir::def::{DefKind, LifetimeRes, Res}; use rustc_middle::span_bug; use rustc_middle::ty::ResolverAstLowering; use rustc_span::symbol::{kw, Ident}; @@ -77,7 +77,20 @@ impl<'ast> Visitor<'ast> for LifetimeCollectVisitor<'ast> { } fn visit_ty(&mut self, t: &'ast Ty) { - match t.kind { + match &t.kind { + TyKind::Path(None, _) => { + // We can sometimes encounter bare trait objects + // which are represented in AST as paths. + if let Some(partial_res) = self.resolver.get_partial_res(t.id) + && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res() + { + self.current_binders.push(t.id); + visit::walk_ty(self, t); + self.current_binders.pop(); + } else { + visit::walk_ty(self, t); + } + } TyKind::BareFn(_) => { self.current_binders.push(t.id); visit::walk_ty(self, t); diff --git a/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.rs b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.rs new file mode 100644 index 0000000000000..57d688492515b --- /dev/null +++ b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.rs @@ -0,0 +1,22 @@ +// edition:2015 +// check-pass +// issue: 114664 + +fn ice() -> impl AsRef { + //~^ WARN trait objects without an explicit `dyn` are deprecated + //~| WARN trait objects without an explicit `dyn` are deprecated + //~| WARN trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + Foo +} + +struct Foo; +impl AsRef for Foo { + fn as_ref(&self) -> &(dyn for<'a> Fn(&'a ()) + 'static) { + todo!() + } +} + +pub fn main() {} diff --git a/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr new file mode 100644 index 0000000000000..fad0b812d43dd --- /dev/null +++ b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr @@ -0,0 +1,42 @@ +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/fresh-lifetime-from-bare-trait-obj-114664.rs:5:24 + | +LL | fn ice() -> impl AsRef { + | ^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see + = note: `#[warn(bare_trait_objects)]` on by default +help: use `dyn` + | +LL | fn ice() -> impl AsRef { + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/fresh-lifetime-from-bare-trait-obj-114664.rs:5:24 + | +LL | fn ice() -> impl AsRef { + | ^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL | fn ice() -> impl AsRef { + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/fresh-lifetime-from-bare-trait-obj-114664.rs:5:24 + | +LL | fn ice() -> impl AsRef { + | ^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL | fn ice() -> impl AsRef { + | +++ + +warning: 3 warnings emitted +