about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-06-23 22:39:01 +0200
committerGitHub <noreply@github.com>2024-06-23 22:39:01 +0200
commit2c0311dbbeea4d91ea6d3b722a668f9feb7b935b (patch)
treecf199d521f3a615d36d0086454a5ee633e161cf3
parenta9959bd1ab39b7362acf508baca56990d084210d (diff)
parent0a265957ddebf3517e5d1105541ba7931d1974bb (diff)
downloadrust-2c0311dbbeea4d91ea6d3b722a668f9feb7b935b.tar.gz
rust-2c0311dbbeea4d91ea6d3b722a668f9feb7b935b.zip
Rollup merge of #126837 - petrochenkov:delegfix, r=compiler-errors
delegation: Do not crash on qpaths without a trait

Fixes https://github.com/rust-lang/rust/issues/126742
-rw-r--r--compiler/rustc_expand/messages.ftl3
-rw-r--r--compiler/rustc_expand/src/errors.rs7
-rw-r--r--compiler/rustc_expand/src/expand.rs12
-rw-r--r--tests/ui/delegation/glob-traitless-qpath.rs11
-rw-r--r--tests/ui/delegation/glob-traitless-qpath.stderr14
5 files changed, 45 insertions, 2 deletions
diff --git a/compiler/rustc_expand/messages.ftl b/compiler/rustc_expand/messages.ftl
index 6113580491e..cc0b110d2bc 100644
--- a/compiler/rustc_expand/messages.ftl
+++ b/compiler/rustc_expand/messages.ftl
@@ -61,6 +61,9 @@ expand_feature_removed =
 expand_glob_delegation_outside_impls =
     glob delegation is only supported in impls
 
+expand_glob_delegation_traitless_qpath =
+    qualified path without a trait in glob delegation
+
 expand_helper_attribute_name_invalid =
     `{$name}` cannot be a name of derive helper attribute
 
diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs
index c883121fb40..0be7403f25b 100644
--- a/compiler/rustc_expand/src/errors.rs
+++ b/compiler/rustc_expand/src/errors.rs
@@ -449,6 +449,13 @@ pub(crate) struct GlobDelegationOutsideImpls {
     pub span: Span,
 }
 
+#[derive(Diagnostic)]
+#[diag(expand_glob_delegation_traitless_qpath)]
+pub(crate) struct GlobDelegationTraitlessQpath {
+    #[primary_span]
+    pub span: Span,
+}
+
 // This used to be the `proc_macro_back_compat` lint (#83125). It was later
 // turned into a hard error.
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 716bfc8c26b..a331d83aab0 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -1,8 +1,9 @@
 use crate::base::*;
 use crate::config::StripUnconfigured;
 use crate::errors::{
-    EmptyDelegationMac, GlobDelegationOutsideImpls, IncompleteParse, RecursionLimitReached,
-    RemoveExprNotSupported, RemoveNodeNotSupported, UnsupportedKeyValue, WrongFragmentKind,
+    EmptyDelegationMac, GlobDelegationOutsideImpls, GlobDelegationTraitlessQpath, IncompleteParse,
+    RecursionLimitReached, RemoveExprNotSupported, RemoveNodeNotSupported, UnsupportedKeyValue,
+    WrongFragmentKind,
 };
 use crate::mbe::diagnostics::annotate_err_with_kind;
 use crate::module::{mod_dir_path, parse_external_mod, DirOwnership, ParsedExternalMod};
@@ -1989,6 +1990,8 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
                 }
                 None if let Some((deleg, item)) = node.delegation() => {
                     let Some(suffixes) = &deleg.suffixes else {
+                        let traitless_qself =
+                            matches!(&deleg.qself, Some(qself) if qself.position == 0);
                         let item = match node.to_annotatable() {
                             Annotatable::ImplItem(item) => item,
                             ann @ (Annotatable::Item(_)
@@ -2000,6 +2003,11 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
                             }
                             _ => unreachable!(),
                         };
+                        if traitless_qself {
+                            let span = item.span;
+                            self.cx.dcx().emit_err(GlobDelegationTraitlessQpath { span });
+                            return Default::default();
+                        }
                         return self.collect_glob_delegation(item, Node::KIND).make_ast::<Node>();
                     };
 
diff --git a/tests/ui/delegation/glob-traitless-qpath.rs b/tests/ui/delegation/glob-traitless-qpath.rs
new file mode 100644
index 00000000000..abf4b3180ed
--- /dev/null
+++ b/tests/ui/delegation/glob-traitless-qpath.rs
@@ -0,0 +1,11 @@
+#![feature(fn_delegation)]
+#![allow(incomplete_features)]
+
+struct S;
+
+impl S {
+    reuse <u8>::*; //~ ERROR qualified path without a trait in glob delegation
+    reuse <()>::*; //~ ERROR qualified path without a trait in glob delegation
+}
+
+fn main() {}
diff --git a/tests/ui/delegation/glob-traitless-qpath.stderr b/tests/ui/delegation/glob-traitless-qpath.stderr
new file mode 100644
index 00000000000..e3257de347a
--- /dev/null
+++ b/tests/ui/delegation/glob-traitless-qpath.stderr
@@ -0,0 +1,14 @@
+error: qualified path without a trait in glob delegation
+  --> $DIR/glob-traitless-qpath.rs:7:5
+   |
+LL |     reuse <u8>::*;
+   |     ^^^^^^^^^^^^^^
+
+error: qualified path without a trait in glob delegation
+  --> $DIR/glob-traitless-qpath.rs:8:5
+   |
+LL |     reuse <()>::*;
+   |     ^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+