Add backcompat hack to support
```rust fn foo() -> impl MyTrait { panic!(); MyStruct } struct MyStruct; trait MyTrait {} impl MyTrait for MyStruct {} ```
This commit is contained in:
parent
edaf9625fb
commit
64c5b9a3d6
@ -30,6 +30,7 @@ use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
|
|||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
use rustc_data_structures::steal::Steal;
|
use rustc_data_structures::steal::Steal;
|
||||||
use rustc_data_structures::sync::{self, Lock, Lrc, WorkerLocal};
|
use rustc_data_structures::sync::{self, Lock, Lrc, WorkerLocal};
|
||||||
|
use rustc_data_structures::vec_map::VecMap;
|
||||||
use rustc_errors::ErrorReported;
|
use rustc_errors::ErrorReported;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
@ -464,9 +465,13 @@ pub struct TypeckResults<'tcx> {
|
|||||||
/// this field will be set to `Some(ErrorReported)`.
|
/// this field will be set to `Some(ErrorReported)`.
|
||||||
pub tainted_by_errors: Option<ErrorReported>,
|
pub tainted_by_errors: Option<ErrorReported>,
|
||||||
|
|
||||||
/// All the opaque types that are restricted to concrete types
|
/// All the opaque types that have hidden types set
|
||||||
/// by this function.
|
/// by this function. For return-position-impl-trait we also store the
|
||||||
pub concrete_opaque_types: FxHashSet<DefId>,
|
/// type here, so that mir-borrowck can figure out hidden types,
|
||||||
|
/// even if they are only set in dead code (which doesn't show up in MIR).
|
||||||
|
/// For type-alias-impl-trait, this map is only used to prevent query cycles,
|
||||||
|
/// so the hidden types are all `None`.
|
||||||
|
pub concrete_opaque_types: VecMap<DefId, Option<Ty<'tcx>>>,
|
||||||
|
|
||||||
/// Tracks the minimum captures required for a closure;
|
/// Tracks the minimum captures required for a closure;
|
||||||
/// see `MinCaptureInformationMap` for more details.
|
/// see `MinCaptureInformationMap` for more details.
|
||||||
|
@ -499,8 +499,14 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||||||
fn visit_opaque_types(&mut self) {
|
fn visit_opaque_types(&mut self) {
|
||||||
let opaque_types =
|
let opaque_types =
|
||||||
self.fcx.infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
|
self.fcx.infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
|
||||||
for (opaque_type_key, _) in opaque_types {
|
for (opaque_type_key, decl) in opaque_types {
|
||||||
self.typeck_results.concrete_opaque_types.insert(opaque_type_key.def_id);
|
let hidden_type = match decl.origin {
|
||||||
|
hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_) => {
|
||||||
|
Some(self.resolve(decl.hidden_type.ty, &decl.hidden_type.span))
|
||||||
|
}
|
||||||
|
hir::OpaqueTyOrigin::TyAlias => None,
|
||||||
|
};
|
||||||
|
self.typeck_results.concrete_opaque_types.insert(opaque_type_key.def_id, hidden_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,21 +389,22 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||||||
.get_value_matching(|(key, _)| key.def_id == def_id.to_def_id())
|
.get_value_matching(|(key, _)| key.def_id == def_id.to_def_id())
|
||||||
.copied()
|
.copied()
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
if let Some(ErrorReported) =
|
let table = tcx.typeck(owner);
|
||||||
tcx.typeck(owner).tainted_by_errors
|
if let Some(ErrorReported) = table.tainted_by_errors {
|
||||||
{
|
|
||||||
// Some error in the
|
// Some error in the
|
||||||
// owner fn prevented us from populating
|
// owner fn prevented us from populating
|
||||||
// the `concrete_opaque_types` table.
|
// the `concrete_opaque_types` table.
|
||||||
tcx.ty_error()
|
tcx.ty_error()
|
||||||
} else {
|
} else {
|
||||||
// We failed to resolve the opaque type or it
|
table.concrete_opaque_types.get(&def_id.to_def_id()).copied().unwrap_or_else(|| {
|
||||||
// resolves to itself. We interpret this as the
|
// We failed to resolve the opaque type or it
|
||||||
// no values of the hidden type ever being constructed,
|
// resolves to itself. We interpret this as the
|
||||||
// so we can just make the hidden type be `!`.
|
// no values of the hidden type ever being constructed,
|
||||||
// For backwards compatibility reasons, we fall back to
|
// so we can just make the hidden type be `!`.
|
||||||
// `()` until we the diverging default is changed.
|
// For backwards compatibility reasons, we fall back to
|
||||||
tcx.mk_diverging_default()
|
// `()` until we the diverging default is changed.
|
||||||
|
Some(tcx.mk_diverging_default())
|
||||||
|
}).expect("RPIT always have a hidden type from typeck")
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
debug!("concrete_ty = {:?}", concrete_ty);
|
debug!("concrete_ty = {:?}", concrete_ty);
|
||||||
@ -597,7 +598,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
|
|||||||
}
|
}
|
||||||
// Calling `mir_borrowck` can lead to cycle errors through
|
// Calling `mir_borrowck` can lead to cycle errors through
|
||||||
// const-checking, avoid calling it if we don't have to.
|
// const-checking, avoid calling it if we don't have to.
|
||||||
if !self.tcx.typeck(def_id).concrete_opaque_types.contains(&self.def_id) {
|
if self.tcx.typeck(def_id).concrete_opaque_types.get(&self.def_id).is_none() {
|
||||||
debug!("no constraints in typeck results");
|
debug!("no constraints in typeck results");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user