diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-08-12 12:06:36 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-08-12 12:06:36 +0200 |
| commit | a12c329b35c8d7d49ec9c703ad7928b502c5fbb9 (patch) | |
| tree | 3d9757b482d967ee5a1b93d241a4b5924684554b | |
| parent | 83756d97a8aeb1d7a69b76f60c9b35ca60a87585 (diff) | |
| parent | bbe7a96bec86eead5b6411856b92cfa012947195 (diff) | |
| download | rust-a12c329b35c8d7d49ec9c703ad7928b502c5fbb9.tar.gz rust-a12c329b35c8d7d49ec9c703ad7928b502c5fbb9.zip | |
Rollup merge of #114667 - compiler-errors:issue-114664, r=davidtwco
Record binder for bare trait object in LifetimeCollectVisitor The `LifetimeCollectVisitor` had a bug where it was not recording the binder of bate trait objects. This was uncovered in #114487, when I changed opaque type lowering to ICE if it encountered a captured fresh lifetime with no def-id to map back to: https://github.com/rust-lang/rust/pull/114487/files#diff-ad0c15bbde97a607d4758ec7eaf88248be5d6b8ae084dfc84127f81e3f7a9bb4R1585 Fixes #114664
3 files changed, 79 insertions, 2 deletions
diff --git a/compiler/rustc_ast_lowering/src/lifetime_collector.rs b/compiler/rustc_ast_lowering/src/lifetime_collector.rs index 0e0bdf17389..6f75419c387 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 00000000000..57d68849251 --- /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<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() {} 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 00000000000..fad0b812d43 --- /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<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 + |
