Skip to content

Commit 64c5b9a

Browse files
committed
Add backcompat hack to support
```rust fn foo() -> impl MyTrait { panic!(); MyStruct } struct MyStruct; trait MyTrait {} impl MyTrait for MyStruct {} ```
1 parent edaf962 commit 64c5b9a

File tree

3 files changed

+28
-16
lines changed

3 files changed

+28
-16
lines changed

compiler/rustc_middle/src/ty/context.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
3030
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
3131
use rustc_data_structures::steal::Steal;
3232
use rustc_data_structures::sync::{self, Lock, Lrc, WorkerLocal};
33+
use rustc_data_structures::vec_map::VecMap;
3334
use rustc_errors::ErrorReported;
3435
use rustc_hir as hir;
3536
use rustc_hir::def::{DefKind, Res};
@@ -464,9 +465,13 @@ pub struct TypeckResults<'tcx> {
464465
/// this field will be set to `Some(ErrorReported)`.
465466
pub tainted_by_errors: Option<ErrorReported>,
466467

467-
/// All the opaque types that are restricted to concrete types
468-
/// by this function.
469-
pub concrete_opaque_types: FxHashSet<DefId>,
468+
/// All the opaque types that have hidden types set
469+
/// by this function. For return-position-impl-trait we also store the
470+
/// type here, so that mir-borrowck can figure out hidden types,
471+
/// even if they are only set in dead code (which doesn't show up in MIR).
472+
/// For type-alias-impl-trait, this map is only used to prevent query cycles,
473+
/// so the hidden types are all `None`.
474+
pub concrete_opaque_types: VecMap<DefId, Option<Ty<'tcx>>>,
470475

471476
/// Tracks the minimum captures required for a closure;
472477
/// see `MinCaptureInformationMap` for more details.

compiler/rustc_typeck/src/check/writeback.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -499,8 +499,14 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
499499
fn visit_opaque_types(&mut self) {
500500
let opaque_types =
501501
self.fcx.infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
502-
for (opaque_type_key, _) in opaque_types {
503-
self.typeck_results.concrete_opaque_types.insert(opaque_type_key.def_id);
502+
for (opaque_type_key, decl) in opaque_types {
503+
let hidden_type = match decl.origin {
504+
hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_) => {
505+
Some(self.resolve(decl.hidden_type.ty, &decl.hidden_type.span))
506+
}
507+
hir::OpaqueTyOrigin::TyAlias => None,
508+
};
509+
self.typeck_results.concrete_opaque_types.insert(opaque_type_key.def_id, hidden_type);
504510
}
505511
}
506512

compiler/rustc_typeck/src/collect/type_of.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -389,21 +389,22 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
389389
.get_value_matching(|(key, _)| key.def_id == def_id.to_def_id())
390390
.copied()
391391
.unwrap_or_else(|| {
392-
if let Some(ErrorReported) =
393-
tcx.typeck(owner).tainted_by_errors
394-
{
392+
let table = tcx.typeck(owner);
393+
if let Some(ErrorReported) = table.tainted_by_errors {
395394
// Some error in the
396395
// owner fn prevented us from populating
397396
// the `concrete_opaque_types` table.
398397
tcx.ty_error()
399398
} else {
400-
// We failed to resolve the opaque type or it
401-
// resolves to itself. We interpret this as the
402-
// no values of the hidden type ever being constructed,
403-
// so we can just make the hidden type be `!`.
404-
// For backwards compatibility reasons, we fall back to
405-
// `()` until we the diverging default is changed.
406-
tcx.mk_diverging_default()
399+
table.concrete_opaque_types.get(&def_id.to_def_id()).copied().unwrap_or_else(|| {
400+
// We failed to resolve the opaque type or it
401+
// resolves to itself. We interpret this as the
402+
// no values of the hidden type ever being constructed,
403+
// so we can just make the hidden type be `!`.
404+
// For backwards compatibility reasons, we fall back to
405+
// `()` until we the diverging default is changed.
406+
Some(tcx.mk_diverging_default())
407+
}).expect("RPIT always have a hidden type from typeck")
407408
}
408409
});
409410
debug!("concrete_ty = {:?}", concrete_ty);
@@ -597,7 +598,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
597598
}
598599
// Calling `mir_borrowck` can lead to cycle errors through
599600
// const-checking, avoid calling it if we don't have to.
600-
if !self.tcx.typeck(def_id).concrete_opaque_types.contains(&self.def_id) {
601+
if self.tcx.typeck(def_id).concrete_opaque_types.get(&self.def_id).is_none() {
601602
debug!("no constraints in typeck results");
602603
return;
603604
}

0 commit comments

Comments
 (0)