Skip to content

Commit bbe7a96

Browse files
Record binder for bare trait object in LifetimeCollectVisitor
1 parent a9b2c6a commit bbe7a96

File tree

3 files changed

+79
-2
lines changed

3 files changed

+79
-2
lines changed

compiler/rustc_ast_lowering/src/lifetime_collector.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::ResolverAstLoweringExt;
22
use rustc_ast::visit::{self, BoundKind, LifetimeCtxt, Visitor};
33
use rustc_ast::{GenericBounds, Lifetime, NodeId, PathSegment, PolyTraitRef, Ty, TyKind};
4-
use rustc_hir::def::LifetimeRes;
4+
use rustc_hir::def::{DefKind, LifetimeRes, Res};
55
use rustc_middle::span_bug;
66
use rustc_middle::ty::ResolverAstLowering;
77
use rustc_span::symbol::{kw, Ident};
@@ -77,7 +77,20 @@ impl<'ast> Visitor<'ast> for LifetimeCollectVisitor<'ast> {
7777
}
7878

7979
fn visit_ty(&mut self, t: &'ast Ty) {
80-
match t.kind {
80+
match &t.kind {
81+
TyKind::Path(None, _) => {
82+
// We can sometimes encounter bare trait objects
83+
// which are represented in AST as paths.
84+
if let Some(partial_res) = self.resolver.get_partial_res(t.id)
85+
&& let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res()
86+
{
87+
self.current_binders.push(t.id);
88+
visit::walk_ty(self, t);
89+
self.current_binders.pop();
90+
} else {
91+
visit::walk_ty(self, t);
92+
}
93+
}
8194
TyKind::BareFn(_) => {
8295
self.current_binders.push(t.id);
8396
visit::walk_ty(self, t);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// edition:2015
2+
// check-pass
3+
// issue: 114664
4+
5+
fn ice() -> impl AsRef<Fn(&())> {
6+
//~^ WARN trait objects without an explicit `dyn` are deprecated
7+
//~| WARN trait objects without an explicit `dyn` are deprecated
8+
//~| WARN trait objects without an explicit `dyn` are deprecated
9+
//~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
10+
//~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
11+
//~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
12+
Foo
13+
}
14+
15+
struct Foo;
16+
impl AsRef<dyn Fn(&())> for Foo {
17+
fn as_ref(&self) -> &(dyn for<'a> Fn(&'a ()) + 'static) {
18+
todo!()
19+
}
20+
}
21+
22+
pub fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
warning: trait objects without an explicit `dyn` are deprecated
2+
--> $DIR/fresh-lifetime-from-bare-trait-obj-114664.rs:5:24
3+
|
4+
LL | fn ice() -> impl AsRef<Fn(&())> {
5+
| ^^^^^^^
6+
|
7+
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
8+
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
9+
= note: `#[warn(bare_trait_objects)]` on by default
10+
help: use `dyn`
11+
|
12+
LL | fn ice() -> impl AsRef<dyn Fn(&())> {
13+
| +++
14+
15+
warning: trait objects without an explicit `dyn` are deprecated
16+
--> $DIR/fresh-lifetime-from-bare-trait-obj-114664.rs:5:24
17+
|
18+
LL | fn ice() -> impl AsRef<Fn(&())> {
19+
| ^^^^^^^
20+
|
21+
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
22+
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
23+
help: use `dyn`
24+
|
25+
LL | fn ice() -> impl AsRef<dyn Fn(&())> {
26+
| +++
27+
28+
warning: trait objects without an explicit `dyn` are deprecated
29+
--> $DIR/fresh-lifetime-from-bare-trait-obj-114664.rs:5:24
30+
|
31+
LL | fn ice() -> impl AsRef<Fn(&())> {
32+
| ^^^^^^^
33+
|
34+
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
35+
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
36+
help: use `dyn`
37+
|
38+
LL | fn ice() -> impl AsRef<dyn Fn(&())> {
39+
| +++
40+
41+
warning: 3 warnings emitted
42+

0 commit comments

Comments
 (0)