Skip to content

Commit 262079b

Browse files
Rollup merge of #134981 - estebank:issue-93993, r=BoxyUwU
Explain that in paths generics can't be set on both the enum and the variant ``` error[E0109]: type arguments are not allowed on tuple variant `TSVariant` --> $DIR/enum-variant-generic-args.rs:54:29 | LL | Enum::<()>::TSVariant::<()>(()); | --------- ^^ type argument not allowed | | | not allowed on tuple variant `TSVariant` | = 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::<()>(()); | LL - Enum::<()>::TSVariant::<()>(()); LL + Enum::<()>::TSVariant(()); | ``` Fix #93993.
2 parents 33d92df + 23daa8c commit 262079b

File tree

5 files changed

+70
-24
lines changed

5 files changed

+70
-24
lines changed

Diff for: compiler/rustc_hir_analysis/src/collect.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -614,9 +614,10 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
614614
if !infer_replacements.is_empty() {
615615
diag.multipart_suggestion(
616616
format!(
617-
"try replacing `_` with the type{} in the corresponding trait method signature",
618-
rustc_errors::pluralize!(infer_replacements.len()),
619-
),
617+
"try replacing `_` with the type{} in the corresponding trait method \
618+
signature",
619+
rustc_errors::pluralize!(infer_replacements.len()),
620+
),
620621
infer_replacements,
621622
Applicability::MachineApplicable,
622623
);

Diff for: compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs

+38-17
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_errors::{
66
Applicability, Diag, ErrorGuaranteed, MultiSpan, listify, pluralize, struct_span_code_err,
77
};
88
use rustc_hir as hir;
9-
use rustc_hir::def::{DefKind, Res};
9+
use rustc_hir::def::{CtorOf, DefKind, Res};
1010
use rustc_hir::def_id::DefId;
1111
use rustc_middle::bug;
1212
use rustc_middle::ty::fast_reject::{TreatParams, simplify_type};
@@ -1027,7 +1027,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
10271027
&self,
10281028
segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone,
10291029
args_visitors: impl Iterator<Item = &'a hir::GenericArg<'a>> + Clone,
1030-
err_extend: GenericsArgsErrExtend<'_>,
1030+
err_extend: GenericsArgsErrExtend<'a>,
10311031
) -> ErrorGuaranteed {
10321032
#[derive(PartialEq, Eq, Hash)]
10331033
enum ProhibitGenericsArg {
@@ -1047,23 +1047,24 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
10471047
};
10481048
});
10491049

1050+
let segments: Vec<_> = segments.collect();
10501051
let types_and_spans: Vec<_> = segments
1051-
.clone()
1052+
.iter()
10521053
.flat_map(|segment| {
10531054
if segment.args().args.is_empty() {
10541055
None
10551056
} else {
10561057
Some((
10571058
match segment.res {
1058-
hir::def::Res::PrimTy(ty) => {
1059+
Res::PrimTy(ty) => {
10591060
format!("{} `{}`", segment.res.descr(), ty.name())
10601061
}
1061-
hir::def::Res::Def(_, def_id)
1062+
Res::Def(_, def_id)
10621063
if let Some(name) = self.tcx().opt_item_name(def_id) =>
10631064
{
10641065
format!("{} `{name}`", segment.res.descr())
10651066
}
1066-
hir::def::Res::Err => "this type".to_string(),
1067+
Res::Err => "this type".to_string(),
10671068
_ => segment.res.descr().to_string(),
10681069
},
10691070
segment.ident.span,
@@ -1074,11 +1075,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
10741075
let this_type = listify(&types_and_spans, |(t, _)| t.to_string())
10751076
.expect("expected one segment to deny");
10761077

1077-
let arg_spans: Vec<Span> = segments
1078-
.clone()
1079-
.flat_map(|segment| segment.args().args)
1080-
.map(|arg| arg.span())
1081-
.collect();
1078+
let arg_spans: Vec<Span> =
1079+
segments.iter().flat_map(|segment| segment.args().args).map(|arg| arg.span()).collect();
10821080

10831081
let mut kinds = Vec::with_capacity(4);
10841082
prohibit_args.iter().for_each(|arg| match arg {
@@ -1103,7 +1101,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
11031101
for (what, span) in types_and_spans {
11041102
err.span_label(span, format!("not allowed on {what}"));
11051103
}
1106-
generics_args_err_extend(self.tcx(), segments, &mut err, err_extend);
1104+
generics_args_err_extend(self.tcx(), segments.into_iter(), &mut err, err_extend);
11071105
err.emit()
11081106
}
11091107

@@ -1400,15 +1398,15 @@ pub enum GenericsArgsErrExtend<'tcx> {
14001398
},
14011399
SelfTyParam(Span),
14021400
Param(DefId),
1403-
DefVariant,
1401+
DefVariant(&'tcx [hir::PathSegment<'tcx>]),
14041402
None,
14051403
}
14061404

14071405
fn generics_args_err_extend<'a>(
14081406
tcx: TyCtxt<'_>,
14091407
segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone,
14101408
err: &mut Diag<'_>,
1411-
err_extend: GenericsArgsErrExtend<'_>,
1409+
err_extend: GenericsArgsErrExtend<'a>,
14121410
) {
14131411
match err_extend {
14141412
GenericsArgsErrExtend::EnumVariant { qself, assoc_segment, adt_def } => {
@@ -1496,6 +1494,32 @@ fn generics_args_err_extend<'a>(
14961494
];
14971495
err.multipart_suggestion_verbose(msg, suggestion, Applicability::MaybeIncorrect);
14981496
}
1497+
GenericsArgsErrExtend::DefVariant(segments) => {
1498+
let args: Vec<Span> = segments
1499+
.iter()
1500+
.filter_map(|segment| match segment.res {
1501+
Res::Def(
1502+
DefKind::Ctor(CtorOf::Variant, _) | DefKind::Variant | DefKind::Enum,
1503+
_,
1504+
) => segment.args().span_ext().map(|s| s.with_lo(segment.ident.span.hi())),
1505+
_ => None,
1506+
})
1507+
.collect();
1508+
if args.len() > 1
1509+
&& let Some(span) = args.into_iter().last()
1510+
{
1511+
err.note(
1512+
"generic arguments are not allowed on both an enum and its variant's path \
1513+
segments simultaneously; they are only valid in one place or the other",
1514+
);
1515+
err.span_suggestion_verbose(
1516+
span,
1517+
"remove the generics arguments from one of the path segments",
1518+
String::new(),
1519+
Applicability::MaybeIncorrect,
1520+
);
1521+
}
1522+
}
14991523
GenericsArgsErrExtend::PrimTy(prim_ty) => {
15001524
let name = prim_ty.name_str();
15011525
for segment in segments {
@@ -1512,9 +1536,6 @@ fn generics_args_err_extend<'a>(
15121536
GenericsArgsErrExtend::OpaqueTy => {
15131537
err.note("`impl Trait` types can't have type parameters");
15141538
}
1515-
GenericsArgsErrExtend::DefVariant => {
1516-
err.note("enum variants can't have type parameters");
1517-
}
15181539
GenericsArgsErrExtend::Param(def_id) => {
15191540
let span = tcx.def_ident_span(def_id).unwrap();
15201541
let kind = tcx.def_descr(def_id);

Diff for: compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1694,7 +1694,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
16941694
pub fn prohibit_generic_args<'a>(
16951695
&self,
16961696
segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone,
1697-
err_extend: GenericsArgsErrExtend<'_>,
1697+
err_extend: GenericsArgsErrExtend<'a>,
16981698
) -> Result<(), ErrorGuaranteed> {
16991699
let args_visitors = segments.clone().flat_map(|segment| segment.args().args);
17001700
let mut result = Ok(());
@@ -1911,7 +1911,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
19111911
path.segments.iter().enumerate().filter_map(|(index, seg)| {
19121912
if !indices.contains(&index) { Some(seg) } else { None }
19131913
}),
1914-
GenericsArgsErrExtend::DefVariant,
1914+
GenericsArgsErrExtend::DefVariant(&path.segments),
19151915
);
19161916

19171917
let GenericPathSegment(def_id, index) = generic_segments.last().unwrap();

Diff for: compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1043,12 +1043,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10431043

10441044
let mut user_self_ty = None;
10451045
let mut is_alias_variant_ctor = false;
1046+
let mut err_extend = GenericsArgsErrExtend::None;
10461047
match res {
10471048
Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) if let Some(self_ty) = self_ty => {
10481049
let adt_def = self_ty.normalized.ty_adt_def().unwrap();
10491050
user_self_ty =
10501051
Some(UserSelfTy { impl_def_id: adt_def.did(), self_ty: self_ty.raw });
10511052
is_alias_variant_ctor = true;
1053+
err_extend = GenericsArgsErrExtend::DefVariant(segments);
1054+
}
1055+
Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
1056+
err_extend = GenericsArgsErrExtend::DefVariant(segments);
10521057
}
10531058
Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
10541059
let assoc_item = tcx.associated_item(def_id);
@@ -1095,7 +1100,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10951100
segments.iter().enumerate().filter_map(|(index, seg)| {
10961101
if !indices.contains(&index) || is_alias_variant_ctor { Some(seg) } else { None }
10971102
}),
1098-
GenericsArgsErrExtend::None,
1103+
err_extend,
10991104
);
11001105

11011106
if let Res::Local(hid) = res {

Diff for: tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr

+20-1
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,13 @@ LL | Enum::<()>::TSVariant::<()>(());
285285
| --------- ^^ type argument not allowed
286286
| |
287287
| not allowed on tuple variant `TSVariant`
288+
|
289+
= 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
290+
help: remove the generics arguments from one of the path segments
291+
|
292+
LL - Enum::<()>::TSVariant::<()>(());
293+
LL + Enum::<()>::TSVariant(());
294+
|
288295

289296
error[E0109]: type arguments are not allowed on this type
290297
--> $DIR/enum-variant-generic-args.rs:57:24
@@ -354,7 +361,12 @@ LL | Enum::<()>::SVariant::<()> { v: () };
354361
| |
355362
| not allowed on variant `SVariant`
356363
|
357-
= note: enum variants can't have type parameters
364+
= 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
365+
help: remove the generics arguments from one of the path segments
366+
|
367+
LL - Enum::<()>::SVariant::<()> { v: () };
368+
LL + Enum::<()>::SVariant { v: () };
369+
|
358370

359371
error[E0109]: type arguments are not allowed on this type
360372
--> $DIR/enum-variant-generic-args.rs:75:23
@@ -451,6 +463,13 @@ LL | Enum::<()>::UVariant::<()>;
451463
| -------- ^^ type argument not allowed
452464
| |
453465
| not allowed on unit variant `UVariant`
466+
|
467+
= 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
468+
help: remove the generics arguments from one of the path segments
469+
|
470+
LL - Enum::<()>::UVariant::<()>;
471+
LL + Enum::<()>::UVariant;
472+
|
454473

455474
error[E0109]: type arguments are not allowed on this type
456475
--> $DIR/enum-variant-generic-args.rs:93:23

0 commit comments

Comments
 (0)