Skip to content

Commit d0216b5

Browse files
committed
fn check_opaque_type_parameter_valid defer error
1 parent 097cd98 commit d0216b5

File tree

3 files changed

+61
-35
lines changed

3 files changed

+61
-35
lines changed

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -267,13 +267,13 @@ impl<'tcx> InferCtxt<'tcx> {
267267
return Ty::new_error(self.tcx, e);
268268
}
269269

270-
if let Err(guar) = check_opaque_type_parameter_valid(
270+
if let Err(err) = check_opaque_type_parameter_valid(
271271
self,
272272
opaque_type_key,
273273
instantiated_ty.span,
274274
DefiningScopeKind::MirBorrowck,
275275
) {
276-
return Ty::new_error(self.tcx, guar);
276+
return Ty::new_error(self.tcx, err.report(self));
277277
}
278278

279279
let definition_ty = instantiated_ty

compiler/rustc_hir_typeck/src/writeback.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -555,15 +555,16 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
555555
}
556556
}
557557

558-
if let Err(guar) = check_opaque_type_parameter_valid(
558+
if let Err(err) = check_opaque_type_parameter_valid(
559559
&self.fcx,
560560
opaque_type_key,
561561
hidden_type.span,
562562
DefiningScopeKind::HirTypeck,
563563
) {
564-
self.typeck_results
565-
.concrete_opaque_types
566-
.insert(opaque_type_key.def_id, ty::OpaqueHiddenType::new_error(tcx, guar));
564+
self.typeck_results.concrete_opaque_types.insert(
565+
opaque_type_key.def_id,
566+
ty::OpaqueHiddenType::new_error(tcx, err.report(self.fcx)),
567+
);
567568
}
568569

569570
let hidden_type = hidden_type.remap_generic_params_to_declaration_params(

compiler/rustc_trait_selection/src/opaque_types.rs

+54-29
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,49 @@ use crate::errors::NonGenericOpaqueTypeParam;
1313
use crate::regions::OutlivesEnvironmentBuildExt;
1414
use crate::traits::ObligationCtxt;
1515

16+
pub enum InvalidOpaqueTypeArgs<'tcx> {
17+
AlreadyReported(ErrorGuaranteed),
18+
NotAParam { opaque_type_key: OpaqueTypeKey<'tcx>, param_index: usize, span: Span },
19+
DuplicateParam { opaque_type_key: OpaqueTypeKey<'tcx>, param_indices: Vec<usize>, span: Span },
20+
}
21+
impl From<ErrorGuaranteed> for InvalidOpaqueTypeArgs<'_> {
22+
fn from(guar: ErrorGuaranteed) -> Self {
23+
InvalidOpaqueTypeArgs::AlreadyReported(guar)
24+
}
25+
}
26+
impl<'tcx> InvalidOpaqueTypeArgs<'tcx> {
27+
pub fn report(self, infcx: &InferCtxt<'tcx>) -> ErrorGuaranteed {
28+
let tcx = infcx.tcx;
29+
match self {
30+
InvalidOpaqueTypeArgs::AlreadyReported(guar) => guar,
31+
InvalidOpaqueTypeArgs::NotAParam { opaque_type_key, param_index, span } => {
32+
let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
33+
let opaque_param = opaque_generics.param_at(param_index, tcx);
34+
let kind = opaque_param.kind.descr();
35+
infcx.dcx().emit_err(NonGenericOpaqueTypeParam {
36+
arg: opaque_type_key.args[param_index],
37+
kind,
38+
span,
39+
param_span: tcx.def_span(opaque_param.def_id),
40+
})
41+
}
42+
InvalidOpaqueTypeArgs::DuplicateParam { opaque_type_key, param_indices, span } => {
43+
let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
44+
let descr = opaque_generics.param_at(param_indices[0], tcx).kind.descr();
45+
let spans: Vec<_> = param_indices
46+
.into_iter()
47+
.map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id))
48+
.collect();
49+
infcx
50+
.dcx()
51+
.struct_span_err(span, "non-defining opaque type use in defining scope")
52+
.with_span_note(spans, format!("{descr} used multiple times"))
53+
.emit()
54+
}
55+
}
56+
}
57+
}
58+
1659
/// Opaque type parameter validity check as documented in the [rustc-dev-guide chapter].
1760
///
1861
/// [rustc-dev-guide chapter]:
@@ -22,23 +65,19 @@ pub fn check_opaque_type_parameter_valid<'tcx>(
2265
opaque_type_key: OpaqueTypeKey<'tcx>,
2366
span: Span,
2467
defining_scope_kind: DefiningScopeKind,
25-
) -> Result<(), ErrorGuaranteed> {
68+
) -> Result<(), InvalidOpaqueTypeArgs<'tcx>> {
2669
let tcx = infcx.tcx;
27-
let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
2870
let opaque_env = LazyOpaqueTyEnv::new(tcx, opaque_type_key.def_id);
2971
let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default();
3072

3173
// Avoid duplicate errors in case the opaque has already been malformed in
3274
// HIR typeck.
3375
if let DefiningScopeKind::MirBorrowck = defining_scope_kind {
34-
if let Err(guar) = infcx
76+
infcx
3577
.tcx
3678
.type_of_opaque_hir_typeck(opaque_type_key.def_id)
3779
.instantiate_identity()
38-
.error_reported()
39-
{
40-
return Err(guar);
41-
}
80+
.error_reported()?;
4281
}
4382

4483
for (i, arg) in opaque_type_key.iter_captured_args(tcx) {
@@ -64,32 +103,18 @@ pub fn check_opaque_type_parameter_valid<'tcx>(
64103
}
65104
} else {
66105
// Prevent `fn foo() -> Foo<u32>` from being defining.
67-
let opaque_param = opaque_generics.param_at(i, tcx);
68-
let kind = opaque_param.kind.descr();
69-
70106
opaque_env.param_is_error(i)?;
71-
72-
return Err(infcx.dcx().emit_err(NonGenericOpaqueTypeParam {
73-
arg,
74-
kind,
75-
span,
76-
param_span: tcx.def_span(opaque_param.def_id),
77-
}));
107+
return Err(InvalidOpaqueTypeArgs::NotAParam { opaque_type_key, param_index: i, span });
78108
}
79109
}
80110

81-
for (_, indices) in seen_params {
82-
if indices.len() > 1 {
83-
let descr = opaque_generics.param_at(indices[0], tcx).kind.descr();
84-
let spans: Vec<_> = indices
85-
.into_iter()
86-
.map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id))
87-
.collect();
88-
return Err(infcx
89-
.dcx()
90-
.struct_span_err(span, "non-defining opaque type use in defining scope")
91-
.with_span_note(spans, format!("{descr} used multiple times"))
92-
.emit());
111+
for (_, param_indices) in seen_params {
112+
if param_indices.len() > 1 {
113+
return Err(InvalidOpaqueTypeArgs::DuplicateParam {
114+
opaque_type_key,
115+
param_indices,
116+
span,
117+
});
93118
}
94119
}
95120

0 commit comments

Comments
 (0)