about summary refs log tree commit diff
path: root/compiler/rustc_resolve/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-07-11 17:09:37 +0000
committerbors <bors@rust-lang.org>2022-07-11 17:09:37 +0000
commit38b72154ded23847cd08a796d0c6708b5efac265 (patch)
tree6250bc421ddfbb5a6e85c2e4bdb5a4cb28b24b73 /compiler/rustc_resolve/src
parent9fb32dc924653e35950f17c8d91793c9ca983d03 (diff)
parent21a12e8ab78f7e67a4ddc1d13d289a496f2f619d (diff)
downloadrust-38b72154ded23847cd08a796d0c6708b5efac265.tar.gz
rust-38b72154ded23847cd08a796d0c6708b5efac265.zip
Auto merge of #98637 - cjgillot:bare-trait-anon-lt, r=petrochenkov
Create fresh lifetime parameters for bare fn trait too

The current code fails to account for the equivalence between `dyn FnMut(&mut u8)` and bare `FnMut(&mut u8)`, and treated them differently.

This PR introduces a special case for `Fn` traits, which are always fully resolved.

Fixes #98616
Fixes #98726
This will require a beta-backport, as beta contains that bug.

r? `@petrochenkov`
Diffstat (limited to 'compiler/rustc_resolve/src')
-rw-r--r--compiler/rustc_resolve/src/late.rs24
1 files changed, 24 insertions, 0 deletions
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index f37acca3d9f..098b5a0c92e 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -611,6 +611,30 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
             TyKind::Path(ref qself, ref path) => {
                 self.diagnostic_metadata.current_type_path = Some(ty);
                 self.smart_resolve_path(ty.id, qself.as_ref(), path, PathSource::Type);
+
+                // Check whether we should interpret this as a bare trait object.
+                if qself.is_none()
+                    && let Some(partial_res) = self.r.partial_res_map.get(&ty.id)
+                    && partial_res.unresolved_segments() == 0
+                    && let Res::Def(DefKind::Trait | DefKind::TraitAlias, _) = partial_res.base_res()
+                {
+                    // This path is actually a bare trait object.  In case of a bare `Fn`-trait
+                    // object with anonymous lifetimes, we need this rib to correctly place the
+                    // synthetic lifetimes.
+                    let span = ty.span.shrink_to_lo().to(path.span.shrink_to_lo());
+                    self.with_generic_param_rib(
+                        &[],
+                        NormalRibKind,
+                        LifetimeRibKind::Generics {
+                            binder: ty.id,
+                            kind: LifetimeBinderKind::PolyTrait,
+                            span,
+                        },
+                        |this| this.visit_path(&path, ty.id),
+                    );
+                    self.diagnostic_metadata.current_type_path = prev_ty;
+                    return;
+                }
             }
             TyKind::ImplicitSelf => {
                 let self_ty = Ident::with_dummy_span(kw::SelfUpper);