2 use rustc_middle::ty::{self, AdtSizedConstraint, Ty};
4 pub(super) trait Value<'tcx>: Sized {
5 fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self;
8 impl<'tcx, T> Value<'tcx> for T {
9 default fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> T {
10 tcx.sess.abort_if_errors();
11 bug!("Value::from_cycle_error called without errors");
15 impl<'tcx> Value<'tcx> for Ty<'_> {
16 fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self {
17 // SAFETY: This is never called when `Self` is not `Ty<'tcx>`.
18 // FIXME: Represent the above fact in the trait system somehow.
19 unsafe { std::mem::transmute::<Ty<'tcx>, Ty<'_>>(tcx.ty_error()) }
23 impl<'tcx> Value<'tcx> for ty::SymbolName<'_> {
24 fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self {
25 // SAFETY: This is never called when `Self` is not `SymbolName<'tcx>`.
26 // FIXME: Represent the above fact in the trait system somehow.
28 std::mem::transmute::<ty::SymbolName<'tcx>, ty::SymbolName<'_>>(ty::SymbolName::new(
35 impl<'tcx> Value<'tcx> for AdtSizedConstraint<'_> {
36 fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self {
37 // SAFETY: This is never called when `Self` is not `AdtSizedConstraint<'tcx>`.
38 // FIXME: Represent the above fact in the trait system somehow.
40 std::mem::transmute::<AdtSizedConstraint<'tcx>, AdtSizedConstraint<'_>>(
41 AdtSizedConstraint(tcx.intern_type_list(&[tcx.ty_error()])),
47 impl<'tcx> Value<'tcx> for ty::Binder<'_, ty::FnSig<'_>> {
48 fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self {
49 let err = tcx.ty_error();
50 // FIXME(compiler-errors): It would be nice if we could get the
51 // query key, so we could at least generate a fn signature that
52 // has the right arity.
53 let fn_sig = ty::Binder::dummy(tcx.mk_fn_sig(
57 rustc_hir::Unsafety::Normal,
58 rustc_target::spec::abi::Abi::Rust,
61 // SAFETY: This is never called when `Self` is not `ty::Binder<'tcx, ty::FnSig<'tcx>>`.
62 // FIXME: Represent the above fact in the trait system somehow.
63 unsafe { std::mem::transmute::<ty::PolyFnSig<'tcx>, ty::Binder<'_, ty::FnSig<'_>>>(fn_sig) }