delegation: Do not crash on qpaths without a trait

This commit is contained in:
Vadim Petrochenkov 2024-06-22 19:14:16 +03:00
parent ac47dbad50
commit 0a265957dd
5 changed files with 45 additions and 2 deletions

View File

@ -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

View File

@ -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)]

View File

@ -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>();
};

View File

@ -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() {}

View File

@ -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