Skip to content

Commit 6df1ffe

Browse files
committed
Preserve ErrorGuaranteed when comparing two opaque types that are both in their defining scope
1 parent bb78dba commit 6df1ffe

File tree

2 files changed

+29
-6
lines changed

2 files changed

+29
-6
lines changed

compiler/rustc_infer/src/infer/opaque_types/mod.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,20 +140,40 @@ impl<'tcx> InferCtxt<'tcx> {
140140
return None;
141141
}
142142

143-
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }) = *b.kind() {
143+
if let ty::Alias(ty::Opaque, b) = *b.kind() {
144144
// We could accept this, but there are various ways to handle this situation, and we don't
145145
// want to make a decision on it right now. Likely this case is so super rare anyway, that
146146
// no one encounters it in practice.
147147
// It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`,
148148
// where it is of no concern, so we only check for TAITs.
149-
if self.can_define_opaque_ty(b_def_id)
150-
&& self.tcx.is_type_alias_impl_trait(b_def_id)
149+
if self.can_define_opaque_ty(b.def_id)
150+
&& self.tcx.is_type_alias_impl_trait(b.def_id)
151151
{
152-
self.tcx.dcx().emit_err(OpaqueHiddenTypeDiag {
152+
let guar = self.tcx.dcx().emit_err(OpaqueHiddenTypeDiag {
153153
span: cause.span,
154-
hidden_type: self.tcx.def_span(b_def_id),
154+
hidden_type: self.tcx.def_span(b.def_id),
155155
opaque_type: self.tcx.def_span(def_id),
156156
});
157+
let mut obligations = vec![];
158+
return Some(
159+
try {
160+
self.insert_hidden_type(
161+
OpaqueTypeKey { def_id, args },
162+
&cause,
163+
param_env,
164+
Ty::new_error(self.tcx, guar),
165+
&mut obligations,
166+
)?;
167+
self.insert_hidden_type(
168+
OpaqueTypeKey { def_id: b.def_id.expect_local(), args: b.args },
169+
&cause,
170+
param_env,
171+
Ty::new_error(self.tcx, guar),
172+
&mut obligations,
173+
)?;
174+
InferOk { value: (), obligations }
175+
},
176+
);
157177
}
158178
}
159179
Some(self.register_hidden_type(

compiler/rustc_infer/src/infer/opaque_types/table.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use rustc_data_structures::undo_log::UndoLogs;
2-
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty};
2+
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TypeVisitableExt};
33

44
use crate::infer::snapshot::undo_log::{InferCtxtUndoLogs, UndoLog};
55

@@ -59,6 +59,9 @@ impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> {
5959
hidden_type: OpaqueHiddenType<'tcx>,
6060
) -> Option<Ty<'tcx>> {
6161
if let Some(decl) = self.storage.opaque_types.get_mut(&key) {
62+
if decl.hidden_type.ty.references_error() {
63+
return Some(decl.hidden_type.ty);
64+
}
6265
let prev = std::mem::replace(&mut decl.hidden_type, hidden_type);
6366
self.undo_log.push(UndoLog::OpaqueTypes(key, Some(prev)));
6467
return Some(prev.ty);

0 commit comments

Comments
 (0)