summary refs log tree commit diff
path: root/compiler/rustc_ast_lowering
diff options
context:
space:
mode:
authorLeón Orell Valerian Liehr <me@fmease.dev>2024-10-27 06:21:24 +0100
committerLeón Orell Valerian Liehr <me@fmease.dev>2024-10-27 07:41:52 +0100
commit442f39582d2aec5026c8d75079a75f58579059e4 (patch)
tree53a1e7f582cb9c6a9048527d40413a5e99650835 /compiler/rustc_ast_lowering
parent6faf0bd3e561f1a0c81f3eafe0ce0e688385d70e (diff)
downloadrust-442f39582d2aec5026c8d75079a75f58579059e4.tar.gz
rust-442f39582d2aec5026c8d75079a75f58579059e4.zip
Move an impl-Trait check from AST validation to AST lowering
Diffstat (limited to 'compiler/rustc_ast_lowering')
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs19
1 files changed, 16 insertions, 3 deletions
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index 258655de486..6a0f03c8b31 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -34,7 +34,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         modifiers: Option<ast::TraitBoundModifiers>,
     ) -> hir::QPath<'hir> {
         let qself_position = qself.as_ref().map(|q| q.position);
-        let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx));
+        let qself = qself
+            .as_ref()
+            // Reject cases like `<impl Trait>::Assoc` and `<impl Trait as Trait>::Assoc`.
+            .map(|q| self.lower_ty(&q.ty, ImplTraitContext::Disallowed(ImplTraitPosition::Path)));
 
         let partial_res =
             self.resolver.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err));
@@ -75,6 +78,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             None
         };
 
+        // Only permit `impl Trait` in the final segment. E.g., we permit `Option<impl Trait>`,
+        // `option::Option<T>::Xyz<impl Trait>` and reject `option::Option<impl Trait>::Xyz`.
+        let itctx = |i| {
+            if i + 1 == p.segments.len() {
+                itctx
+            } else {
+                ImplTraitContext::Disallowed(ImplTraitPosition::Path)
+            }
+        };
+
         let path_span_lo = p.span.shrink_to_lo();
         let proj_start = p.segments.len() - unresolved_segments;
         let path = self.arena.alloc(hir::Path {
@@ -121,7 +134,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         segment,
                         param_mode,
                         generic_args_mode,
-                        itctx,
+                        itctx(i),
                         bound_modifier_allowed_features.clone(),
                     )
                 },
@@ -185,7 +198,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 segment,
                 param_mode,
                 generic_args_mode,
-                itctx,
+                itctx(i),
                 None,
             ));
             let qpath = hir::QPath::TypeRelative(ty, hir_segment);