Skip to content

Commit d3dae85

Browse files
Return all opaques in typeck results
1 parent e9e1bbc commit d3dae85

File tree

5 files changed

+76
-23
lines changed

5 files changed

+76
-23
lines changed

compiler/rustc_hir_analysis/src/collect/type_of.rs

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -569,12 +569,17 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
569569
Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: self.tcx.ty_error(guar) });
570570
return;
571571
}
572-
let Some(&typeck_hidden_ty) = tables.concrete_opaque_types.get(&self.def_id) else {
572+
573+
let mut constrained_during_typeck = false;
574+
for (key, typeck_hidden_ty) in &tables.concrete_opaque_types {
575+
if key.def_id == self.def_id {
576+
constrained_during_typeck = true;
577+
self.typeck_types.push(*typeck_hidden_ty);
578+
}
579+
}
580+
if !constrained_during_typeck {
573581
debug!("no constraints in typeck results");
574582
return;
575-
};
576-
if self.typeck_types.iter().all(|prev| prev.ty != typeck_hidden_ty.ty) {
577-
self.typeck_types.push(typeck_hidden_ty);
578583
}
579584

580585
// Use borrowck to get the type with unerased regions.
@@ -678,10 +683,11 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
678683
// Only check against typeck if we didn't already error
679684
if !hidden.ty.references_error() {
680685
for concrete_type in locator.typeck_types {
681-
if tcx.erase_regions(concrete_type.ty) != tcx.erase_regions(hidden.ty)
686+
if concrete_type.ty != tcx.erase_regions(hidden.ty)
682687
&& !(concrete_type, hidden).references_error()
683688
{
684-
hidden.report_mismatch(&concrete_type, tcx);
689+
let reported = hidden.report_mismatch(&concrete_type, tcx);
690+
return tcx.ty_error(reported);
685691
}
686692
}
687693
}
@@ -786,15 +792,24 @@ fn find_opaque_ty_constraints_for_rpit(
786792
// the `concrete_opaque_types` table.
787793
tcx.ty_error(guar)
788794
} else {
789-
table.concrete_opaque_types.get(&def_id).map(|ty| ty.ty).unwrap_or_else(|| {
790-
// We failed to resolve the opaque type or it
791-
// resolves to itself. We interpret this as the
792-
// no values of the hidden type ever being constructed,
793-
// so we can just make the hidden type be `!`.
794-
// For backwards compatibility reasons, we fall back to
795-
// `()` until we the diverging default is changed.
796-
tcx.mk_diverging_default()
797-
})
795+
table
796+
.concrete_opaque_types
797+
.iter()
798+
.find(|(key, _)| {
799+
// For backwards compatibility, we choose the first matching
800+
// opaque type definition
801+
key.def_id == def_id
802+
})
803+
.map(|(_, ty)| ty.ty)
804+
.unwrap_or_else(|| {
805+
// We failed to resolve the opaque type or it
806+
// resolves to itself. We interpret this as the
807+
// no values of the hidden type ever being constructed,
808+
// so we can just make the hidden type be `!`.
809+
// For backwards compatibility reasons, we fall back to
810+
// `()` until we the diverging default is changed.
811+
tcx.mk_diverging_default()
812+
})
798813
}
799814
})
800815
}

compiler/rustc_hir_typeck/src/writeback.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -579,13 +579,22 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
579579
continue;
580580
}
581581

582-
let hidden_type = hidden_type.remap_generic_params_to_declaration_params(
583-
opaque_type_key,
584-
self.fcx.infcx.tcx,
585-
true,
586-
);
587-
588-
self.typeck_results.concrete_opaque_types.insert(opaque_type_key.def_id, hidden_type);
582+
let hidden_type =
583+
self.tcx().erase_regions(hidden_type.remap_generic_params_to_declaration_params(
584+
opaque_type_key,
585+
self.fcx.infcx.tcx,
586+
true,
587+
));
588+
589+
if let Some(last_opaque_ty) =
590+
self.typeck_results.concrete_opaque_types.insert(opaque_type_key, hidden_type)
591+
{
592+
if last_opaque_ty.ty != self.tcx().erase_regions(hidden_type.ty)
593+
&& !(last_opaque_ty, hidden_type).references_error()
594+
{
595+
hidden_type.report_mismatch(&last_opaque_ty, self.tcx());
596+
}
597+
}
589598
}
590599
}
591600

compiler/rustc_middle/src/ty/typeck_results.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ pub struct TypeckResults<'tcx> {
155155
/// by this function. We also store the
156156
/// type here, so that mir-borrowck can use it as a hint for figuring out hidden types,
157157
/// even if they are only set in dead code (which doesn't show up in MIR).
158-
pub concrete_opaque_types: FxIndexMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,
158+
pub concrete_opaque_types: FxIndexMap<ty::OpaqueTypeKey<'tcx>, ty::OpaqueHiddenType<'tcx>>,
159159

160160
/// Tracks the minimum captures required for a closure;
161161
/// see `MinCaptureInformationMap` for more details.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![feature(type_alias_impl_trait)]
2+
3+
type Tait<'a> = impl Sized + 'a;
4+
5+
fn foo<'a, 'b>() {
6+
if false {
7+
if { return } {
8+
let y: Tait<'b> = 1i32;
9+
//~^ ERROR concrete type differs from previous defining opaque type use
10+
}
11+
}
12+
let x: Tait<'a> = ();
13+
}
14+
15+
fn main() {}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: concrete type differs from previous defining opaque type use
2+
--> $DIR/different_defining_uses_never_type-2.rs:8:31
3+
|
4+
LL | let y: Tait<'b> = 1i32;
5+
| ^^^^ expected `()`, got `i32`
6+
|
7+
note: previous use here
8+
--> $DIR/different_defining_uses_never_type-2.rs:12:23
9+
|
10+
LL | let x: Tait<'a> = ();
11+
| ^^
12+
13+
error: aborting due to previous error
14+

0 commit comments

Comments
 (0)