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