Skip to content

Commit

Permalink
Record binder for bare trait object in LifetimeCollectVisitor
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Aug 11, 2023
1 parent a9b2c6a commit bbe7a96
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 2 deletions.
17 changes: 15 additions & 2 deletions compiler/rustc_ast_lowering/src/lifetime_collector.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -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);
Expand Down
22 changes: 22 additions & 0 deletions tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// edition:2015
// check-pass
// issue: 114664

fn ice() -> impl AsRef<Fn(&())> {
//~^ 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<dyn Fn(&())> for Foo {
fn as_ref(&self) -> &(dyn for<'a> Fn(&'a ()) + 'static) {
todo!()
}
}

pub fn main() {}
Original file line number Diff line number Diff line change
@@ -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<Fn(&())> {
| ^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: use `dyn`
|
LL | fn ice() -> impl AsRef<dyn Fn(&())> {
| +++

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<Fn(&())> {
| ^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
LL | fn ice() -> impl AsRef<dyn Fn(&())> {
| +++

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<Fn(&())> {
| ^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
|
LL | fn ice() -> impl AsRef<dyn Fn(&())> {
| +++

warning: 3 warnings emitted

0 comments on commit bbe7a96

Please sign in to comment.