]> git.proxmox.com Git - rustc.git/blob - compiler/rustc_infer/src/infer/opaque_types/table.rs
New upstream version 1.65.0+dfsg1
[rustc.git] / compiler / rustc_infer / src / infer / opaque_types / table.rs
1 use rustc_data_structures::undo_log::UndoLogs;
2 use rustc_hir::OpaqueTyOrigin;
3 use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty};
4 use rustc_span::DUMMY_SP;
5
6 use crate::infer::{InferCtxtUndoLogs, UndoLog};
7
8 use super::{OpaqueTypeDecl, OpaqueTypeMap};
9
10 #[derive(Default, Debug, Clone)]
11 pub struct OpaqueTypeStorage<'tcx> {
12 // Opaque types found in explicit return types and their
13 // associated fresh inference variable. Writeback resolves these
14 // variables to get the concrete type, which can be used to
15 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
16 pub opaque_types: OpaqueTypeMap<'tcx>,
17 }
18
19 impl<'tcx> OpaqueTypeStorage<'tcx> {
20 #[instrument(level = "debug")]
21 pub(crate) fn remove(&mut self, key: OpaqueTypeKey<'tcx>, idx: Option<OpaqueHiddenType<'tcx>>) {
22 if let Some(idx) = idx {
23 self.opaque_types.get_mut(&key).unwrap().hidden_type = idx;
24 } else {
25 match self.opaque_types.remove(&key) {
26 None => bug!("reverted opaque type inference that was never registered: {:?}", key),
27 Some(_) => {}
28 }
29 }
30 }
31
32 #[instrument(level = "debug", ret)]
33 pub fn take_opaque_types(&mut self) -> OpaqueTypeMap<'tcx> {
34 std::mem::take(&mut self.opaque_types)
35 }
36
37 #[inline]
38 pub(crate) fn with_log<'a>(
39 &'a mut self,
40 undo_log: &'a mut InferCtxtUndoLogs<'tcx>,
41 ) -> OpaqueTypeTable<'a, 'tcx> {
42 OpaqueTypeTable { storage: self, undo_log }
43 }
44 }
45
46 impl<'tcx> Drop for OpaqueTypeStorage<'tcx> {
47 fn drop(&mut self) {
48 if !self.opaque_types.is_empty() {
49 ty::tls::with(|tcx| {
50 tcx.sess.delay_span_bug(DUMMY_SP, &format!("{:?}", self.opaque_types))
51 });
52 }
53 }
54 }
55
56 pub struct OpaqueTypeTable<'a, 'tcx> {
57 storage: &'a mut OpaqueTypeStorage<'tcx>,
58
59 undo_log: &'a mut InferCtxtUndoLogs<'tcx>,
60 }
61
62 impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> {
63 #[instrument(skip(self), level = "debug")]
64 pub(crate) fn register(
65 &mut self,
66 key: OpaqueTypeKey<'tcx>,
67 hidden_type: OpaqueHiddenType<'tcx>,
68 origin: OpaqueTyOrigin,
69 ) -> Option<Ty<'tcx>> {
70 if let Some(decl) = self.storage.opaque_types.get_mut(&key) {
71 let prev = std::mem::replace(&mut decl.hidden_type, hidden_type);
72 self.undo_log.push(UndoLog::OpaqueTypes(key, Some(prev)));
73 return Some(prev.ty);
74 }
75 let decl = OpaqueTypeDecl { hidden_type, origin };
76 self.storage.opaque_types.insert(key, decl);
77 self.undo_log.push(UndoLog::OpaqueTypes(key, None));
78 None
79 }
80 }