flux_middle/
builtin_assoc_refts.rs1use std::sync::OnceLock;
2
3use flux_arc_interner::List;
4use flux_common::bug;
5use flux_syntax::symbols::sym;
6use rustc_data_structures::unord::UnordMap;
7use rustc_hir::{LangItem, def_id::DefId};
8use rustc_span::DUMMY_SP;
9
10use crate::{
11 def_id::FluxDefId,
12 global_env::GlobalEnv,
13 rty::{self, AliasReft, AssocRefinements, AssocReft},
14};
15
16impl<'tcx> GlobalEnv<'_, 'tcx> {
17 #[allow(
18 clippy::disallowed_methods,
19 reason = "this file is the source of truth for builtin assoc refts def ids"
20 )]
21 pub fn builtin_assoc_refts(self, def_id: DefId) -> Option<AssocRefinements> {
22 static BUILTIN: OnceLock<UnordMap<DefId, AssocRefinements>> = OnceLock::new();
23
24 BUILTIN
25 .get_or_init(|| {
26 let tcx = self.tcx();
27
28 let mut map = UnordMap::default();
29
30 let sized_id = tcx.require_lang_item(LangItem::Sized, DUMMY_SP);
32 map.insert(
33 sized_id,
34 AssocRefinements {
35 items: List::from_arr([AssocReft::new(
36 FluxDefId::new(def_id, sym::size_of),
37 false,
38 tcx.def_span(sized_id),
39 )]),
40 },
41 );
42 map
43 })
44 .get(&def_id)
45 .cloned()
46 }
47
48 #[allow(
49 clippy::disallowed_methods,
50 reason = "this file is the source of truth for builtin assoc refts def ids"
51 )]
52 pub fn builtin_assoc_reft_sort(
53 self,
54 assoc_id: FluxDefId,
55 ) -> Option<rty::EarlyBinder<rty::FuncSort>> {
56 static BUILTIN: OnceLock<UnordMap<FluxDefId, rty::FuncSort>> = OnceLock::new();
57
58 BUILTIN
59 .get_or_init(|| {
60 let tcx = self.tcx();
61
62 let mut map = UnordMap::default();
63
64 let sized_id = tcx.require_lang_item(LangItem::Sized, DUMMY_SP);
66 map.insert(
67 FluxDefId::new(sized_id, sym::size_of),
68 rty::FuncSort::new(vec![], rty::Sort::Int),
69 );
70 map
71 })
72 .get(&assoc_id)
73 .cloned()
74 .map(rty::EarlyBinder)
75 }
76
77 pub fn builtin_assoc_reft_body(
78 self,
79 typing_env: rustc_middle::ty::TypingEnv<'tcx>,
80 alias_reft: &AliasReft,
81 ) -> rty::Lambda {
82 let tcx = self.tcx();
83
84 if tcx.is_lang_item(alias_reft.assoc_id.parent(), LangItem::Sized)
85 && alias_reft.assoc_id.name() == sym::size_of
86 {
87 let self_ty = alias_reft.to_rustc_trait_ref(tcx).self_ty();
88 let size = tcx
89 .layout_of(typing_env.as_query_input(self_ty))
90 .unwrap()
91 .size
92 .bytes();
93 let body = rty::Expr::constant(rty::Constant::from(size));
94 rty::Lambda::bind_with_vars(body, List::empty(), rty::Sort::Int)
95 } else {
96 bug!("invalid builtin assoc reft {:?}", alias_reft.assoc_id)
97 }
98 }
99}