mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Explain that in paths generics can't be set on both the enum and the variant
``` error[E0109]: type arguments are not allowed on enum `Enum` and tuple variant `TSVariant` --> $DIR/enum-variant-generic-args.rs:54:12 | LL | Enum::<()>::TSVariant::<()>(()); | ---- ^^ --------- ^^ type argument not allowed | | | | | not allowed on tuple variant `TSVariant` | not allowed on enum `Enum` | = note: generic arguments are not allowed on both an enum and its variant's path segments simultaneously; they are only valid in one place or the other help: remove the generics arguments from one of the path segments | LL - Enum::<()>::TSVariant::<()>(()); LL + Enum::<()>::TSVariant(()); | ``` Fix #93993.
This commit is contained in:
parent
06a24e98c6
commit
1b98d0ed13
@ -614,9 +614,10 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
|
||||
if !infer_replacements.is_empty() {
|
||||
diag.multipart_suggestion(
|
||||
format!(
|
||||
"try replacing `_` with the type{} in the corresponding trait method signature",
|
||||
rustc_errors::pluralize!(infer_replacements.len()),
|
||||
),
|
||||
"try replacing `_` with the type{} in the corresponding trait method \
|
||||
signature",
|
||||
rustc_errors::pluralize!(infer_replacements.len()),
|
||||
),
|
||||
infer_replacements,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
|
@ -6,7 +6,7 @@ use rustc_errors::{
|
||||
Applicability, Diag, ErrorGuaranteed, MultiSpan, listify, pluralize, struct_span_code_err,
|
||||
};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def::{CtorOf, DefKind, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::fast_reject::{TreatParams, simplify_type};
|
||||
@ -1027,7 +1027,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
&self,
|
||||
segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone,
|
||||
args_visitors: impl Iterator<Item = &'a hir::GenericArg<'a>> + Clone,
|
||||
err_extend: GenericsArgsErrExtend<'_>,
|
||||
err_extend: GenericsArgsErrExtend<'a>,
|
||||
) -> ErrorGuaranteed {
|
||||
#[derive(PartialEq, Eq, Hash)]
|
||||
enum ProhibitGenericsArg {
|
||||
@ -1047,23 +1047,27 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
};
|
||||
});
|
||||
|
||||
let segments: Vec<_> = match err_extend {
|
||||
GenericsArgsErrExtend::DefVariant(segments) => segments.iter().collect(),
|
||||
_ => segments.collect(),
|
||||
};
|
||||
let types_and_spans: Vec<_> = segments
|
||||
.clone()
|
||||
.iter()
|
||||
.flat_map(|segment| {
|
||||
if segment.args().args.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some((
|
||||
match segment.res {
|
||||
hir::def::Res::PrimTy(ty) => {
|
||||
Res::PrimTy(ty) => {
|
||||
format!("{} `{}`", segment.res.descr(), ty.name())
|
||||
}
|
||||
hir::def::Res::Def(_, def_id)
|
||||
Res::Def(_, def_id)
|
||||
if let Some(name) = self.tcx().opt_item_name(def_id) =>
|
||||
{
|
||||
format!("{} `{name}`", segment.res.descr())
|
||||
}
|
||||
hir::def::Res::Err => "this type".to_string(),
|
||||
Res::Err => "this type".to_string(),
|
||||
_ => segment.res.descr().to_string(),
|
||||
},
|
||||
segment.ident.span,
|
||||
@ -1074,11 +1078,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
let this_type = listify(&types_and_spans, |(t, _)| t.to_string())
|
||||
.expect("expected one segment to deny");
|
||||
|
||||
let arg_spans: Vec<Span> = segments
|
||||
.clone()
|
||||
.flat_map(|segment| segment.args().args)
|
||||
.map(|arg| arg.span())
|
||||
.collect();
|
||||
let arg_spans: Vec<Span> =
|
||||
segments.iter().flat_map(|segment| segment.args().args).map(|arg| arg.span()).collect();
|
||||
|
||||
let mut kinds = Vec::with_capacity(4);
|
||||
prohibit_args.iter().for_each(|arg| match arg {
|
||||
@ -1103,7 +1104,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
for (what, span) in types_and_spans {
|
||||
err.span_label(span, format!("not allowed on {what}"));
|
||||
}
|
||||
generics_args_err_extend(self.tcx(), segments, &mut err, err_extend);
|
||||
generics_args_err_extend(self.tcx(), segments.into_iter(), &mut err, err_extend);
|
||||
err.emit()
|
||||
}
|
||||
|
||||
@ -1400,7 +1401,7 @@ pub enum GenericsArgsErrExtend<'tcx> {
|
||||
},
|
||||
SelfTyParam(Span),
|
||||
Param(DefId),
|
||||
DefVariant,
|
||||
DefVariant(&'tcx [hir::PathSegment<'tcx>]),
|
||||
None,
|
||||
}
|
||||
|
||||
@ -1408,7 +1409,7 @@ fn generics_args_err_extend<'a>(
|
||||
tcx: TyCtxt<'_>,
|
||||
segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone,
|
||||
err: &mut Diag<'_>,
|
||||
err_extend: GenericsArgsErrExtend<'_>,
|
||||
err_extend: GenericsArgsErrExtend<'a>,
|
||||
) {
|
||||
match err_extend {
|
||||
GenericsArgsErrExtend::EnumVariant { qself, assoc_segment, adt_def } => {
|
||||
@ -1496,6 +1497,32 @@ fn generics_args_err_extend<'a>(
|
||||
];
|
||||
err.multipart_suggestion_verbose(msg, suggestion, Applicability::MaybeIncorrect);
|
||||
}
|
||||
GenericsArgsErrExtend::DefVariant(segments) => {
|
||||
let args: Vec<Span> = segments
|
||||
.iter()
|
||||
.filter_map(|segment| match segment.res {
|
||||
Res::Def(
|
||||
DefKind::Ctor(CtorOf::Variant, _) | DefKind::Variant | DefKind::Enum,
|
||||
_,
|
||||
) => segment.args().span_ext().map(|s| s.with_lo(segment.ident.span.hi())),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
if args.len() > 1
|
||||
&& let Some(span) = args.into_iter().last()
|
||||
{
|
||||
let msg = "generic arguments are not allowed on both an enum and its variant's \
|
||||
path segments simultaneously; they are only valid in one place or the \
|
||||
other";
|
||||
err.note(msg);
|
||||
err.span_suggestion_verbose(
|
||||
span,
|
||||
"remove the generics arguments from one of the path segments",
|
||||
String::new(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
GenericsArgsErrExtend::PrimTy(prim_ty) => {
|
||||
let name = prim_ty.name_str();
|
||||
for segment in segments {
|
||||
@ -1512,9 +1539,6 @@ fn generics_args_err_extend<'a>(
|
||||
GenericsArgsErrExtend::OpaqueTy => {
|
||||
err.note("`impl Trait` types can't have type parameters");
|
||||
}
|
||||
GenericsArgsErrExtend::DefVariant => {
|
||||
err.note("enum variants can't have type parameters");
|
||||
}
|
||||
GenericsArgsErrExtend::Param(def_id) => {
|
||||
let span = tcx.def_ident_span(def_id).unwrap();
|
||||
let kind = tcx.def_descr(def_id);
|
||||
|
@ -1694,7 +1694,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
pub fn prohibit_generic_args<'a>(
|
||||
&self,
|
||||
segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone,
|
||||
err_extend: GenericsArgsErrExtend<'_>,
|
||||
err_extend: GenericsArgsErrExtend<'a>,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let args_visitors = segments.clone().flat_map(|segment| segment.args().args);
|
||||
let mut result = Ok(());
|
||||
@ -1911,7 +1911,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
path.segments.iter().enumerate().filter_map(|(index, seg)| {
|
||||
if !indices.contains(&index) { Some(seg) } else { None }
|
||||
}),
|
||||
GenericsArgsErrExtend::DefVariant,
|
||||
GenericsArgsErrExtend::DefVariant(&path.segments),
|
||||
);
|
||||
|
||||
let GenericPathSegment(def_id, index) = generic_segments.last().unwrap();
|
||||
|
@ -1043,12 +1043,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
let mut user_self_ty = None;
|
||||
let mut is_alias_variant_ctor = false;
|
||||
let mut err_extend = GenericsArgsErrExtend::None;
|
||||
match res {
|
||||
Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) if let Some(self_ty) = self_ty => {
|
||||
let adt_def = self_ty.normalized.ty_adt_def().unwrap();
|
||||
user_self_ty =
|
||||
Some(UserSelfTy { impl_def_id: adt_def.did(), self_ty: self_ty.raw });
|
||||
is_alias_variant_ctor = true;
|
||||
err_extend = GenericsArgsErrExtend::DefVariant(segments);
|
||||
}
|
||||
Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
|
||||
err_extend = GenericsArgsErrExtend::DefVariant(segments);
|
||||
}
|
||||
Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
|
||||
let assoc_item = tcx.associated_item(def_id);
|
||||
@ -1095,7 +1100,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
segments.iter().enumerate().filter_map(|(index, seg)| {
|
||||
if !indices.contains(&index) || is_alias_variant_ctor { Some(seg) } else { None }
|
||||
}),
|
||||
GenericsArgsErrExtend::None,
|
||||
err_extend,
|
||||
);
|
||||
|
||||
if let Res::Local(hid) = res {
|
||||
|
@ -52,7 +52,7 @@ fn main() {
|
||||
// Tuple struct variant
|
||||
|
||||
Enum::<()>::TSVariant::<()>(());
|
||||
//~^ ERROR type arguments are not allowed on tuple variant `TSVariant` [E0109]
|
||||
//~^ ERROR type arguments are not allowed on enum `Enum` and tuple variant `TSVariant` [E0109]
|
||||
|
||||
Alias::TSVariant::<()>(());
|
||||
//~^ ERROR type arguments are not allowed on this type [E0109]
|
||||
@ -70,7 +70,7 @@ fn main() {
|
||||
// Struct variant
|
||||
|
||||
Enum::<()>::SVariant::<()> { v: () };
|
||||
//~^ ERROR type arguments are not allowed on variant `SVariant` [E0109]
|
||||
//~^ ERROR type arguments are not allowed on enum `Enum` and variant `SVariant` [E0109]
|
||||
|
||||
Alias::SVariant::<()> { v: () };
|
||||
//~^ ERROR type arguments are not allowed on this type [E0109]
|
||||
@ -88,7 +88,7 @@ fn main() {
|
||||
// Unit variant
|
||||
|
||||
Enum::<()>::UVariant::<()>;
|
||||
//~^ ERROR type arguments are not allowed on unit variant `UVariant` [E0109]
|
||||
//~^ ERROR type arguments are not allowed on enum `Enum` and unit variant `UVariant` [E0109]
|
||||
|
||||
Alias::UVariant::<()>;
|
||||
//~^ ERROR type arguments are not allowed on this type [E0109]
|
||||
|
@ -278,13 +278,21 @@ LL | Self::<()>::UVariant::<()>;
|
||||
| |
|
||||
| not allowed on this type
|
||||
|
||||
error[E0109]: type arguments are not allowed on tuple variant `TSVariant`
|
||||
--> $DIR/enum-variant-generic-args.rs:54:29
|
||||
error[E0109]: type arguments are not allowed on enum `Enum` and tuple variant `TSVariant`
|
||||
--> $DIR/enum-variant-generic-args.rs:54:12
|
||||
|
|
||||
LL | Enum::<()>::TSVariant::<()>(());
|
||||
| --------- ^^ type argument not allowed
|
||||
| |
|
||||
| not allowed on tuple variant `TSVariant`
|
||||
| ---- ^^ --------- ^^ type argument not allowed
|
||||
| | |
|
||||
| | not allowed on tuple variant `TSVariant`
|
||||
| not allowed on enum `Enum`
|
||||
|
|
||||
= note: generic arguments are not allowed on both an enum and its variant's path segments simultaneously; they are only valid in one place or the other
|
||||
help: remove the generics arguments from one of the path segments
|
||||
|
|
||||
LL - Enum::<()>::TSVariant::<()>(());
|
||||
LL + Enum::<()>::TSVariant(());
|
||||
|
|
||||
|
||||
error[E0109]: type arguments are not allowed on this type
|
||||
--> $DIR/enum-variant-generic-args.rs:57:24
|
||||
@ -346,15 +354,21 @@ LL | AliasFixed::<()>::TSVariant::<()>(());
|
||||
| |
|
||||
| not allowed on this type
|
||||
|
||||
error[E0109]: type arguments are not allowed on variant `SVariant`
|
||||
--> $DIR/enum-variant-generic-args.rs:72:28
|
||||
error[E0109]: type arguments are not allowed on enum `Enum` and variant `SVariant`
|
||||
--> $DIR/enum-variant-generic-args.rs:72:12
|
||||
|
|
||||
LL | Enum::<()>::SVariant::<()> { v: () };
|
||||
| -------- ^^ type argument not allowed
|
||||
| |
|
||||
| not allowed on variant `SVariant`
|
||||
| ---- ^^ -------- ^^ type argument not allowed
|
||||
| | |
|
||||
| | not allowed on variant `SVariant`
|
||||
| not allowed on enum `Enum`
|
||||
|
|
||||
= note: generic arguments are not allowed on both an enum and its variant's path segments simultaneously; they are only valid in one place or the other
|
||||
help: remove the generics arguments from one of the path segments
|
||||
|
|
||||
LL - Enum::<()>::SVariant::<()> { v: () };
|
||||
LL + Enum::<()>::SVariant { v: () };
|
||||
|
|
||||
= note: enum variants can't have type parameters
|
||||
|
||||
error[E0109]: type arguments are not allowed on this type
|
||||
--> $DIR/enum-variant-generic-args.rs:75:23
|
||||
@ -444,13 +458,21 @@ LL - AliasFixed::<()>::SVariant::<()> { v: () };
|
||||
LL + AliasFixed::<()>::SVariant { v: () };
|
||||
|
|
||||
|
||||
error[E0109]: type arguments are not allowed on unit variant `UVariant`
|
||||
--> $DIR/enum-variant-generic-args.rs:90:28
|
||||
error[E0109]: type arguments are not allowed on enum `Enum` and unit variant `UVariant`
|
||||
--> $DIR/enum-variant-generic-args.rs:90:12
|
||||
|
|
||||
LL | Enum::<()>::UVariant::<()>;
|
||||
| -------- ^^ type argument not allowed
|
||||
| |
|
||||
| not allowed on unit variant `UVariant`
|
||||
| ---- ^^ -------- ^^ type argument not allowed
|
||||
| | |
|
||||
| | not allowed on unit variant `UVariant`
|
||||
| not allowed on enum `Enum`
|
||||
|
|
||||
= note: generic arguments are not allowed on both an enum and its variant's path segments simultaneously; they are only valid in one place or the other
|
||||
help: remove the generics arguments from one of the path segments
|
||||
|
|
||||
LL - Enum::<()>::UVariant::<()>;
|
||||
LL + Enum::<()>::UVariant;
|
||||
|
|
||||
|
||||
error[E0109]: type arguments are not allowed on this type
|
||||
--> $DIR/enum-variant-generic-args.rs:93:23
|
||||
|
Loading…
Reference in New Issue
Block a user