1pub mod struct_compat;
12use std::{borrow::Borrow, iter};
13
14use flux_common::{
15 bug,
16 dbg::{self, SpanTrace},
17 iter::IterExt,
18 result::ResultExt as _,
19 span_bug,
20};
21use flux_middle::{
22 THEORY_FUNCS,
23 def_id::{FluxDefId, MaybeExternId},
24 fhir::{self, FhirId, FluxOwnerId, QPathExpr},
25 global_env::GlobalEnv,
26 queries::{QueryErr, QueryResult},
27 query_bug,
28 rty::{
29 self, AssocReft, BoundReftKind, ESpan, INNERMOST, InternalFuncKind, List, RefineArgsExt,
30 WfckResults,
31 fold::TypeFoldable,
32 refining::{self, Refine, Refiner},
33 },
34};
35use flux_rustc_bridge::{
36 ToRustc,
37 lowering::{Lower, UnsupportedErr},
38};
39use itertools::Itertools;
40use rustc_data_structures::{
41 fx::{FxHashMap, FxIndexMap},
42 unord::UnordMap,
43};
44use rustc_errors::Diagnostic;
45use rustc_hash::FxHashSet;
46use rustc_hir::{self as hir, BodyId, OwnerId, Safety, def::DefKind, def_id::DefId};
47use rustc_index::IndexVec;
48use rustc_middle::{
49 middle::resolve_bound_vars::ResolvedArg,
50 ty::{self, AssocItem, AssocTag, BoundVar, TyCtxt},
51};
52use rustc_span::{
53 DUMMY_SP, ErrorGuaranteed, Span, Symbol,
54 symbol::{Ident, kw},
55};
56use rustc_trait_selection::traits;
57use rustc_type_ir::DebruijnIndex;
58
59#[repr(transparent)]
62pub struct ConvCtxt<P>(P);
63
64pub(crate) struct AfterSortck<'a, 'genv, 'tcx> {
65 genv: GlobalEnv<'genv, 'tcx>,
66 wfckresults: &'a WfckResults,
67 next_sort_index: u32,
68 next_type_index: u32,
69 next_region_index: u32,
70 next_const_index: u32,
71}
72
73pub trait ConvPhase<'genv, 'tcx>: Sized {
77 const EXPAND_TYPE_ALIASES: bool;
79
80 const HAS_ELABORATED_INFORMATION: bool;
83
84 type Results: WfckResultsProvider;
85
86 fn genv(&self) -> GlobalEnv<'genv, 'tcx>;
87
88 fn owner(&self) -> FluxOwnerId;
89
90 fn next_sort_vid(&mut self) -> rty::SortVid;
91
92 fn next_type_vid(&mut self) -> rty::TyVid;
93
94 fn next_region_vid(&mut self) -> rty::RegionVid;
95
96 fn next_const_vid(&mut self) -> rty::ConstVid;
97
98 fn results(&self) -> &Self::Results;
99
100 fn insert_node_sort(&mut self, fhir_id: FhirId, sort: rty::Sort);
106
107 fn insert_path_args(&mut self, fhir_id: FhirId, args: rty::GenericArgs);
110
111 fn insert_alias_reft_sort(&mut self, fhir_id: FhirId, fsort: rty::FuncSort);
114
115 fn into_conv_ctxt(self) -> ConvCtxt<Self> {
116 ConvCtxt(self)
117 }
118
119 fn as_conv_ctxt(&mut self) -> &mut ConvCtxt<Self> {
120 unsafe { std::mem::transmute(self) }
122 }
123}
124
125pub trait WfckResultsProvider: Sized {
128 fn bin_op_sort(&self, fhir_id: FhirId) -> rty::Sort;
129
130 fn coercions_for(&self, fhir_id: FhirId) -> &[rty::Coercion];
131
132 fn field_proj(&self, fhir_id: FhirId) -> rty::FieldProj;
133
134 fn record_ctor(&self, fhir_id: FhirId) -> DefId;
135
136 fn param_sort(&self, param_id: fhir::ParamId) -> rty::Sort;
137
138 fn node_sort(&self, fhir_id: FhirId) -> rty::Sort;
139
140 fn node_sort_args(&self, fhir_id: FhirId) -> List<rty::SortArg>;
141}
142
143impl<'genv, 'tcx> ConvPhase<'genv, 'tcx> for AfterSortck<'_, 'genv, 'tcx> {
144 const EXPAND_TYPE_ALIASES: bool = true;
145 const HAS_ELABORATED_INFORMATION: bool = true;
146
147 type Results = WfckResults;
148
149 fn genv(&self) -> GlobalEnv<'genv, 'tcx> {
150 self.genv
151 }
152
153 fn owner(&self) -> FluxOwnerId {
154 self.wfckresults.owner
155 }
156
157 fn next_sort_vid(&mut self) -> rty::SortVid {
158 self.next_sort_index = self.next_sort_index.checked_add(1).unwrap();
159 rty::SortVid::from_u32(self.next_sort_index - 1)
160 }
161
162 fn next_type_vid(&mut self) -> rty::TyVid {
163 self.next_type_index = self.next_type_index.checked_add(1).unwrap();
164 rty::TyVid::from_u32(self.next_type_index - 1)
165 }
166
167 fn next_region_vid(&mut self) -> rty::RegionVid {
168 self.next_region_index = self.next_region_index.checked_add(1).unwrap();
169 rty::RegionVid::from_u32(self.next_region_index - 1)
170 }
171
172 fn next_const_vid(&mut self) -> rty::ConstVid {
173 self.next_const_index = self.next_const_index.checked_add(1).unwrap();
174 rty::ConstVid::from_u32(self.next_const_index - 1)
175 }
176
177 fn results(&self) -> &Self::Results {
178 self.wfckresults
179 }
180
181 fn insert_node_sort(&mut self, _: FhirId, _: rty::Sort) {}
182
183 fn insert_path_args(&mut self, _: FhirId, _: rty::GenericArgs) {}
184
185 fn insert_alias_reft_sort(&mut self, _: FhirId, _: rty::FuncSort) {}
186}
187
188impl WfckResultsProvider for WfckResults {
189 fn bin_op_sort(&self, fhir_id: FhirId) -> rty::Sort {
190 self.bin_op_sorts()
191 .get(fhir_id)
192 .cloned()
193 .unwrap_or_else(|| bug!("binary operation without elaborated sort `{fhir_id:?}`"))
194 }
195
196 fn coercions_for(&self, fhir_id: FhirId) -> &[rty::Coercion] {
197 self.coercions().get(fhir_id).map_or(&[][..], Vec::as_slice)
198 }
199
200 fn field_proj(&self, fhir_id: FhirId) -> rty::FieldProj {
201 *self
202 .field_projs()
203 .get(fhir_id)
204 .unwrap_or_else(|| bug!("field projection without elaboration `{fhir_id:?}`"))
205 }
206
207 fn record_ctor(&self, fhir_id: FhirId) -> DefId {
208 *self
209 .record_ctors()
210 .get(fhir_id)
211 .unwrap_or_else(|| bug!("unelaborated record constructor `{fhir_id:?}`"))
212 }
213
214 fn param_sort(&self, param_id: fhir::ParamId) -> rty::Sort {
215 self.param_sorts()
216 .get(¶m_id)
217 .unwrap_or_else(|| bug!("unresolved sort for param `{param_id:?}`"))
218 .clone()
219 }
220
221 fn node_sort(&self, fhir_id: FhirId) -> rty::Sort {
222 self.node_sorts()
223 .get(fhir_id)
224 .unwrap_or_else(|| bug!("node without elaborated sort for `{fhir_id:?}`"))
225 .clone()
226 }
227
228 fn node_sort_args(&self, fhir_id: FhirId) -> List<rty::SortArg> {
229 self.fn_app_sorts()
230 .get(fhir_id)
231 .unwrap_or_else(|| bug!("fn-app node without elaborated sort_args for `{fhir_id:?}`"))
232 .clone()
233 }
234}
235
236#[derive(Debug)]
237pub(crate) struct Env {
238 layers: Vec<Layer>,
239 early_params: FxIndexMap<fhir::ParamId, Symbol>,
240}
241
242#[derive(Debug, Clone)]
243struct Layer {
244 map: FxIndexMap<fhir::ParamId, ParamEntry>,
245 kind: LayerKind,
246}
247
248#[derive(Debug, Clone, Copy)]
253enum LayerKind {
254 List {
255 bound_regions: u32,
259 },
260 Coalesce(DefId),
261}
262
263#[derive(Debug, Clone)]
264struct ParamEntry {
265 name: Symbol,
266 sort: rty::Sort,
267 mode: rty::InferMode,
268}
269
270#[derive(Debug)]
271struct LookupResult<'a> {
272 kind: LookupResultKind<'a>,
273 var_span: Span,
275}
276
277#[derive(Debug)]
278enum LookupResultKind<'a> {
279 Bound {
280 debruijn: DebruijnIndex,
281 entry: &'a ParamEntry,
282 kind: LayerKind,
283 index: u32,
285 },
286 EarlyParam {
287 name: Symbol,
288 index: u32,
290 },
291}
292
293pub(crate) fn conv_adt_sort_def(
294 genv: GlobalEnv,
295 def_id: MaybeExternId,
296 kind: &fhir::RefinementKind,
297) -> QueryResult<rty::AdtSortDef> {
298 let wfckresults = &WfckResults::new(OwnerId { def_id: def_id.local_id() });
299 let mut cx = AfterSortck::new(genv, wfckresults).into_conv_ctxt();
300 match kind {
301 fhir::RefinementKind::Refined(refined_by) => {
302 let params = refined_by
303 .sort_params
304 .iter()
305 .map(|def_id| def_id_to_param_ty(genv, *def_id))
306 .collect();
307 let fields = refined_by
308 .fields
309 .iter()
310 .map(|(name, sort)| -> QueryResult<_> { Ok((*name, cx.conv_sort(sort)?)) })
311 .try_collect_vec()?;
312 let variants = IndexVec::from([rty::AdtSortVariant::new(fields)]);
313 let def_id = def_id.resolved_id();
314 Ok(rty::AdtSortDef::new(def_id, params, variants, false, true))
315 }
316 fhir::RefinementKind::Reflected => {
317 let enum_def_id = def_id.resolved_id();
318 let mut variants = IndexVec::new();
319 for variant in genv.tcx().adt_def(enum_def_id).variants() {
320 if let Some(field) = variant.fields.iter().next() {
321 let span = genv.tcx().def_span(field.did);
322 let err = genv
323 .sess()
324 .emit_err(errors::FieldsOnReflectedEnumVariant::new(span));
325 Err(err)?;
326 }
327 variants.push(rty::AdtSortVariant::new(vec![]));
328 }
329 Ok(rty::AdtSortDef::new(enum_def_id, vec![], variants, true, false))
330 }
331 }
332}
333
334pub(crate) fn conv_generics(
335 genv: GlobalEnv,
336 generics: &fhir::Generics,
337 def_id: MaybeExternId,
338 is_trait: bool,
339) -> rty::Generics {
340 let opt_self = is_trait.then(|| {
341 let kind = rty::GenericParamDefKind::Base { has_default: false };
342 rty::GenericParamDef { index: 0, name: kw::SelfUpper, def_id: def_id.resolved_id(), kind }
343 });
344 let rust_generics = genv.tcx().generics_of(def_id.resolved_id());
345 let params = {
346 opt_self
347 .into_iter()
348 .chain(rust_generics.own_params.iter().flat_map(|rust_param| {
349 let param = generics
351 .params
352 .iter()
353 .find(|param| param.def_id.resolved_id() == rust_param.def_id)?;
354 Some(rty::GenericParamDef {
355 kind: conv_generic_param_kind(¶m.kind),
356 def_id: param.def_id.resolved_id(),
357 index: rust_param.index,
358 name: rust_param.name,
359 })
360 }))
361 .collect_vec()
362 };
363
364 let rust_generics = genv.tcx().generics_of(def_id.resolved_id());
365 rty::Generics {
366 own_params: List::from_vec(params),
367 parent: rust_generics.parent,
368 parent_count: rust_generics.parent_count,
369 has_self: rust_generics.has_self,
370 }
371}
372
373pub(crate) fn conv_refinement_generics(
374 params: &[fhir::RefineParam],
375 wfckresults: &WfckResults,
376) -> QueryResult<List<rty::RefineParam>> {
377 params
378 .iter()
379 .map(|param| {
380 let sort = wfckresults.param_sort(param.id);
381 let mode = rty::InferMode::from_param_kind(param.kind);
382 Ok(rty::RefineParam { sort, name: param.name, mode })
383 })
384 .try_collect()
385}
386
387fn conv_generic_param_kind(kind: &fhir::GenericParamKind) -> rty::GenericParamDefKind {
388 match kind {
389 fhir::GenericParamKind::Type { default } => {
390 rty::GenericParamDefKind::Base { has_default: default.is_some() }
391 }
392 fhir::GenericParamKind::Lifetime => rty::GenericParamDefKind::Lifetime,
393 fhir::GenericParamKind::Const { .. } => {
394 rty::GenericParamDefKind::Const { has_default: false }
395 }
396 }
397}
398
399pub(crate) fn conv_default_type_parameter(
400 genv: GlobalEnv,
401 def_id: MaybeExternId,
402 ty: &fhir::Ty,
403 wfckresults: &WfckResults,
404) -> QueryResult<rty::TyOrBase> {
405 let mut env = Env::new(&[]);
406 let idx = genv.def_id_to_param_index(def_id.resolved_id());
407 let owner = ty_param_owner(genv, def_id.resolved_id());
408 let param = genv.generics_of(owner)?.param_at(idx as usize, genv)?;
409 let mut cx = AfterSortck::new(genv, wfckresults).into_conv_ctxt();
410 let rty_ty = cx.conv_ty(&mut env, ty)?;
411 cx.try_to_ty_or_base(param.kind, ty.span, &rty_ty)
412}
413
414impl<'a, 'genv, 'tcx> AfterSortck<'a, 'genv, 'tcx> {
415 pub(crate) fn new(genv: GlobalEnv<'genv, 'tcx>, wfckresults: &'a WfckResults) -> Self {
416 Self {
417 genv,
418 wfckresults,
419 next_sort_index: 1,
422 next_type_index: 1,
423 next_region_index: 0,
424 next_const_index: 0,
425 }
426 }
427}
428
429impl<'genv, 'tcx: 'genv, P: ConvPhase<'genv, 'tcx>> ConvCtxt<P> {
431 fn genv(&self) -> GlobalEnv<'genv, 'tcx> {
432 self.0.genv()
433 }
434
435 fn tcx(&self) -> TyCtxt<'tcx> {
436 self.0.genv().tcx()
437 }
438
439 fn owner(&self) -> FluxOwnerId {
440 self.0.owner()
441 }
442
443 fn results(&self) -> &P::Results {
444 self.0.results()
445 }
446
447 fn next_sort_vid(&mut self) -> rty::SortVid {
448 self.0.next_sort_vid()
449 }
450
451 fn next_type_vid(&mut self) -> rty::TyVid {
452 self.0.next_type_vid()
453 }
454
455 fn next_region_vid(&mut self) -> rty::RegionVid {
456 self.0.next_region_vid()
457 }
458
459 fn next_const_vid(&mut self) -> rty::ConstVid {
460 self.0.next_const_vid()
461 }
462}
463
464fn variant_idx(tcx: TyCtxt, variant_def_id: DefId) -> rty::VariantIdx {
465 let enum_def_id = tcx.parent(variant_def_id);
466 tcx.adt_def(enum_def_id)
467 .variant_index_with_id(variant_def_id)
468}
469
470impl<'genv, 'tcx: 'genv, P: ConvPhase<'genv, 'tcx>> ConvCtxt<P> {
472 pub(crate) fn conv_qualifier(
473 &mut self,
474 qualifier: &fhir::Qualifier,
475 ) -> QueryResult<rty::Qualifier> {
476 let mut env = Env::new(&[]);
477 env.push_layer(Layer::list(self.results(), 0, qualifier.args));
478 let body = self.conv_expr(&mut env, &qualifier.expr)?;
479 let body = rty::Binder::bind_with_vars(body, env.pop_layer().into_bound_vars(self.genv())?);
480 Ok(rty::Qualifier { def_id: qualifier.def_id, body, kind: qualifier.kind })
481 }
482
483 pub(crate) fn conv_defn(
484 &mut self,
485 func: &fhir::SpecFunc,
486 ) -> QueryResult<Option<rty::Binder<rty::Expr>>> {
487 if let Some(body) = &func.body {
488 let mut env = Env::new(&[]);
489 env.push_layer(Layer::list(self.results(), 0, func.args));
490 let expr = self.conv_expr(&mut env, body)?;
491 let body =
492 rty::Binder::bind_with_vars(expr, env.pop_layer().into_bound_vars(self.genv())?);
493 Ok(Some(body))
494 } else {
495 Ok(None)
496 }
497 }
498
499 pub(crate) fn conv_primop_prop(
500 &mut self,
501 primop_prop: &fhir::PrimOpProp,
502 ) -> QueryResult<rty::PrimOpProp> {
503 let mut env = Env::new(&[]);
504 env.push_layer(Layer::list(self.results(), 0, primop_prop.args));
505 let body = self.conv_expr(&mut env, &primop_prop.body)?;
506 let body = rty::Binder::bind_with_vars(body, env.pop_layer().into_bound_vars(self.genv())?);
507 let op = match primop_prop.op {
508 fhir::BinOp::BitAnd => rty::BinOp::BitAnd(rty::Sort::Int),
509 fhir::BinOp::BitOr => rty::BinOp::BitOr(rty::Sort::Int),
510 fhir::BinOp::BitXor => rty::BinOp::BitXor(rty::Sort::Int),
511 fhir::BinOp::BitShl => rty::BinOp::BitShl(rty::Sort::Int),
512 fhir::BinOp::BitShr => rty::BinOp::BitShr(rty::Sort::Int),
513 _ => {
514 span_bug!(
515 primop_prop.span,
516 "unexpected binary operator in primitive property: {:?}",
517 primop_prop.op
518 )
519 }
520 };
521 Ok(rty::PrimOpProp { def_id: primop_prop.def_id, op, body })
522 }
523}
524
525impl<'genv, 'tcx: 'genv, P: ConvPhase<'genv, 'tcx>> ConvCtxt<P> {
527 pub(crate) fn conv_constant_expr(&mut self, expr: &fhir::Expr) -> QueryResult<rty::Expr> {
528 let mut env = Env::new(&[]);
529 self.conv_expr(&mut env, expr)
530 }
531
532 pub(crate) fn conv_enum_variants(
533 &mut self,
534 enum_id: MaybeExternId,
535 enum_def: &fhir::EnumDef,
536 ) -> QueryResult<Vec<rty::PolyVariant>> {
537 let reflected = enum_def.refinement.is_reflected();
538 enum_def
539 .variants
540 .iter()
541 .map(|variant| self.conv_enum_variant(enum_id, variant, reflected))
542 .try_collect_vec()
543 }
544
545 fn conv_enum_variant(
546 &mut self,
547 enum_id: MaybeExternId,
548 variant: &fhir::VariantDef,
549 reflected: bool,
550 ) -> QueryResult<rty::PolyVariant> {
551 let mut env = Env::new(&[]);
552 env.push_layer(Layer::list(self.results(), 0, variant.params));
553
554 let fields = variant
556 .fields
557 .iter()
558 .map(|field| self.conv_ty(&mut env, &field.ty))
559 .try_collect()?;
560
561 let adt_def = self.genv().adt_def(enum_id)?;
562 let idxs = if reflected {
563 let enum_def_id = enum_id.resolved_id();
564 let idx = variant_idx(self.tcx(), variant.def_id.to_def_id());
565 rty::Expr::ctor_enum(enum_def_id, idx)
566 } else {
567 self.conv_expr(&mut env, &variant.ret.idx)?
568 };
569 let variant = rty::VariantSig::new(
570 adt_def,
571 rty::GenericArg::identity_for_item(self.genv(), enum_id.resolved_id())?,
572 fields,
573 idxs,
574 List::empty(),
575 );
576
577 Ok(rty::Binder::bind_with_vars(variant, env.pop_layer().into_bound_vars(self.genv())?))
578 }
579
580 pub(crate) fn conv_struct_variant(
581 &mut self,
582 struct_id: MaybeExternId,
583 struct_def: &fhir::StructDef,
584 ) -> QueryResult<rty::Opaqueness<rty::PolyVariant>> {
585 let mut env = Env::new(&[]);
586 env.push_layer(Layer::list(self.results(), 0, struct_def.params));
587
588 if let fhir::StructKind::Transparent { fields } = &struct_def.kind {
589 let adt_def = self.genv().adt_def(struct_id)?;
590
591 let fields = fields
592 .iter()
593 .map(|field_def| self.conv_ty(&mut env, &field_def.ty))
594 .try_collect()?;
595
596 let vars = env.pop_layer().into_bound_vars(self.genv())?;
597 let idx = rty::Expr::ctor_struct(
598 struct_id.resolved_id(),
599 (0..vars.len())
600 .map(|idx| {
601 rty::Expr::bvar(
602 INNERMOST,
603 BoundVar::from_usize(idx),
604 rty::BoundReftKind::Anon,
605 )
606 })
607 .collect(),
608 );
609
610 let requires = adt_def
611 .invariants()
612 .iter_identity()
613 .map(|inv| inv.apply(&idx))
614 .collect();
615
616 let variant = rty::VariantSig::new(
617 adt_def,
618 rty::GenericArg::identity_for_item(self.genv(), struct_id.resolved_id())?,
619 fields,
620 idx,
621 requires,
622 );
623 let variant = rty::Binder::bind_with_vars(variant, vars);
624 Ok(rty::Opaqueness::Transparent(variant))
625 } else {
626 Ok(rty::Opaqueness::Opaque)
627 }
628 }
629
630 pub(crate) fn conv_type_alias(
631 &mut self,
632 ty_alias_id: MaybeExternId,
633 ty_alias: &fhir::TyAlias,
634 ) -> QueryResult<rty::TyCtor> {
635 let generics = self
636 .genv()
637 .fhir_get_generics(ty_alias_id.local_id())?
638 .unwrap();
639
640 let mut env = Env::new(generics.refinement_params);
641
642 if let Some(index) = &ty_alias.index {
643 env.push_layer(Layer::list(self.results(), 0, std::slice::from_ref(index)));
644 let ty = self.conv_ty(&mut env, &ty_alias.ty)?;
645
646 Ok(rty::Binder::bind_with_vars(ty, env.pop_layer().into_bound_vars(self.genv())?))
647 } else {
648 let ctor = self
649 .conv_ty(&mut env, &ty_alias.ty)?
650 .shallow_canonicalize()
651 .as_ty_or_base()
652 .as_base()
653 .ok_or_else(|| self.emit(errors::InvalidBaseInstance::new(ty_alias.span)))?;
654 Ok(ctor.to_ty_ctor())
655 }
656 }
657
658 pub(crate) fn conv_fn_sig(
659 &mut self,
660 fn_id: MaybeExternId,
661 fn_sig: &fhir::FnSig,
662 ) -> QueryResult<rty::PolyFnSig> {
663 let decl = &fn_sig.decl;
664 let header = fn_sig.header;
665
666 let late_bound_regions =
667 refining::refine_bound_variables(&self.genv().lower_late_bound_vars(fn_id.local_id())?);
668
669 let generics = self.genv().fhir_get_generics(fn_id.local_id())?.unwrap();
670 let mut env = Env::new(generics.refinement_params);
671 env.push_layer(Layer::list(self.results(), late_bound_regions.len() as u32, &[]));
672
673 let body_id = self.tcx().hir_node_by_def_id(fn_id.local_id()).body_id();
674 let fn_sig = self.conv_fn_decl(&mut env, header.safety(), header.abi, decl, body_id)?;
675
676 let vars = late_bound_regions
677 .iter()
678 .chain(env.pop_layer().into_bound_vars(self.genv())?.iter())
679 .cloned()
680 .collect();
681
682 Ok(rty::PolyFnSig::bind_with_vars(fn_sig, vars))
683 }
684
685 pub(crate) fn conv_generic_predicates(
686 &mut self,
687 def_id: MaybeExternId,
688 generics: &fhir::Generics,
689 ) -> QueryResult<rty::EarlyBinder<rty::GenericPredicates>> {
690 let env = &mut Env::new(generics.refinement_params);
691
692 let predicates = if let Some(fhir_predicates) = generics.predicates {
693 let mut clauses = vec![];
694 for pred in fhir_predicates {
695 let span = pred.bounded_ty.span;
696 let bounded_ty = self.conv_ty(env, &pred.bounded_ty)?;
697 for clause in self.conv_generic_bounds(env, span, bounded_ty, pred.bounds)? {
698 clauses.push(clause);
699 }
700 }
701 self.match_clauses(def_id, &clauses)?
702 } else {
703 self.genv()
704 .lower_predicates_of(def_id)?
705 .refine(&Refiner::default_for_item(self.genv(), def_id.resolved_id())?)?
706 };
707 Ok(rty::EarlyBinder(predicates))
708 }
709
710 fn match_clauses(
711 &self,
712 def_id: MaybeExternId,
713 refined_clauses: &[rty::Clause],
714 ) -> QueryResult<rty::GenericPredicates> {
715 let tcx = self.genv().tcx();
716 let predicates = tcx.predicates_of(def_id);
717 let unrefined_clauses = predicates.predicates;
718
719 let mut map = UnordMap::default();
722 for (j, clause) in refined_clauses.iter().enumerate() {
723 let clause = clause.to_rustc(tcx);
724 let Some((i, _)) = unrefined_clauses.iter().find_position(|it| it.0 == clause) else {
725 self.emit_fail_to_match_predicates(def_id)?;
726 };
727 if map.insert(i, j).is_some() {
728 self.emit_fail_to_match_predicates(def_id)?;
729 }
730 }
731
732 let refiner = Refiner::default_for_item(self.genv(), def_id.resolved_id())?;
735 let mut clauses = vec![];
736 for (i, (clause, span)) in unrefined_clauses.iter().enumerate() {
737 let clause = if let Some(j) = map.get(&i) {
738 refined_clauses[*j].clone()
739 } else {
740 clause
741 .lower(tcx)
742 .map_err(|reason| {
743 let err = UnsupportedErr::new(reason).with_span(*span);
744 QueryErr::unsupported(def_id.resolved_id(), err)
745 })?
746 .refine(&refiner)?
747 };
748 clauses.push(clause);
749 }
750
751 Ok(rty::GenericPredicates {
752 parent: predicates.parent,
753 predicates: List::from_vec(clauses),
754 })
755 }
756
757 fn emit_fail_to_match_predicates(&self, def_id: MaybeExternId) -> Result<!, ErrorGuaranteed> {
758 let span = self.tcx().def_span(def_id.resolved_id());
759 Err(self.emit(errors::FailToMatchPredicates { span }))
760 }
761
762 pub(crate) fn conv_opaque_ty(
763 &mut self,
764 opaque_ty: &fhir::OpaqueTy,
765 ) -> QueryResult<rty::Clauses> {
766 let def_id = opaque_ty.def_id;
767 let parent = self.tcx().local_parent(def_id.local_id());
768 let refparams = &self
769 .genv()
770 .fhir_get_generics(parent)?
771 .unwrap()
772 .refinement_params;
773
774 let env = &mut Env::new(refparams);
775
776 let args = rty::GenericArg::identity_for_item(self.genv(), def_id.resolved_id())?;
777 let alias_ty = rty::AliasTy::new(def_id.resolved_id(), args, env.to_early_param_args());
778 let self_ty = rty::BaseTy::opaque(alias_ty).to_ty();
779 Ok(self
781 .conv_generic_bounds(env, DUMMY_SP, self_ty, opaque_ty.bounds)?
782 .into_iter()
783 .collect())
784 }
785
786 pub(crate) fn conv_assoc_reft_body(
787 &mut self,
788 params: &[fhir::RefineParam],
789 body: &fhir::Expr,
790 output: &fhir::Sort,
791 ) -> QueryResult<rty::Lambda> {
792 let mut env = Env::new(&[]);
793 env.push_layer(Layer::list(self.results(), 0, params));
794 let expr = self.conv_expr(&mut env, body)?;
795 let output = self.conv_sort(output)?;
796 let inputs = env.pop_layer().into_bound_vars(self.genv())?;
797 Ok(rty::Lambda::bind_with_vars(expr, inputs, output))
798 }
799}
800
801impl<'genv, 'tcx: 'genv, P: ConvPhase<'genv, 'tcx>> ConvCtxt<P> {
803 pub(crate) fn conv_sort(&mut self, sort: &fhir::Sort) -> QueryResult<rty::Sort> {
804 let sort = match sort {
805 fhir::Sort::Path(path) => self.conv_sort_path(path)?,
806 fhir::Sort::BitVec(size) => rty::Sort::BitVec(rty::BvSize::Fixed(*size)),
807 fhir::Sort::Loc => rty::Sort::Loc,
808 fhir::Sort::Func(fsort) => rty::Sort::Func(self.conv_poly_func_sort(fsort)?),
809 fhir::Sort::SortOf(bty) => {
810 let rty::TyOrCtor::Ctor(ty_ctor) = self.conv_bty(&mut Env::empty(), bty, None)?
811 else {
812 return Err(self.emit(errors::RefinedUnrefinableType::new(bty.span)))?;
814 };
815 ty_ctor.sort()
816 }
817 fhir::Sort::Infer => rty::Sort::Infer(self.next_sort_vid()),
818 fhir::Sort::Err(_) => rty::Sort::Err,
819 };
820 Ok(sort)
821 }
822
823 fn conv_poly_func_sort(&mut self, sort: &fhir::PolyFuncSort) -> QueryResult<rty::PolyFuncSort> {
824 let params = iter::repeat_n(rty::SortParamKind::Sort, sort.params).collect();
825 Ok(rty::PolyFuncSort::new(params, self.conv_func_sort(&sort.fsort)?))
826 }
827
828 fn conv_func_sort(&mut self, fsort: &fhir::FuncSort) -> QueryResult<rty::FuncSort> {
829 let inputs = fsort
830 .inputs()
831 .iter()
832 .map(|sort| self.conv_sort(sort))
833 .try_collect()?;
834 Ok(rty::FuncSort::new(inputs, self.conv_sort(fsort.output())?))
835 }
836
837 fn conv_sort_path(&mut self, path: &fhir::SortPath) -> QueryResult<rty::Sort> {
838 let ctor = match path.res {
839 fhir::SortRes::PrimSort(fhir::PrimSort::Int) => {
840 self.check_prim_sort_generics(path, fhir::PrimSort::Int)?;
841 return Ok(rty::Sort::Int);
842 }
843 fhir::SortRes::PrimSort(fhir::PrimSort::Bool) => {
844 self.check_prim_sort_generics(path, fhir::PrimSort::Bool)?;
845 return Ok(rty::Sort::Bool);
846 }
847 fhir::SortRes::PrimSort(fhir::PrimSort::Real) => {
848 self.check_prim_sort_generics(path, fhir::PrimSort::Real)?;
849 return Ok(rty::Sort::Real);
850 }
851 fhir::SortRes::PrimSort(fhir::PrimSort::Char) => {
852 self.check_prim_sort_generics(path, fhir::PrimSort::Char)?;
853 return Ok(rty::Sort::Char);
854 }
855 fhir::SortRes::PrimSort(fhir::PrimSort::Str) => {
856 self.check_prim_sort_generics(path, fhir::PrimSort::Str)?;
857 return Ok(rty::Sort::Str);
858 }
859 fhir::SortRes::SortParam(n) => return Ok(rty::Sort::Var(rty::ParamSort::from(n))),
860 fhir::SortRes::TyParam(def_id) => {
861 if !path.args.is_empty() {
862 let err = errors::GenericsOnSortTyParam::new(
863 path.segments.last().unwrap().span,
864 path.args.len(),
865 );
866 Err(self.emit(err))?;
867 }
868 return Ok(rty::Sort::Param(def_id_to_param_ty(self.genv(), def_id)));
869 }
870 fhir::SortRes::SelfParam { .. } => {
871 if !path.args.is_empty() {
872 let err = errors::GenericsOnSelf::new(
873 path.segments.last().unwrap().span,
874 path.args.len(),
875 );
876 Err(self.emit(err))?;
877 }
878 return Ok(rty::Sort::Param(rty::SELF_PARAM_TY));
879 }
880 fhir::SortRes::SelfAlias { alias_to } => {
881 if !path.args.is_empty() {
882 let err = errors::GenericsOnSelf::new(
883 path.segments.last().unwrap().span,
884 path.args.len(),
885 );
886 Err(self.emit(err))?;
887 }
888 return Ok(self
889 .genv()
890 .sort_of_self_ty_alias(alias_to)?
891 .unwrap_or(rty::Sort::Err));
892 }
893 fhir::SortRes::SelfParamAssoc { trait_id, ident } => {
894 let res = fhir::Res::SelfTyParam { trait_: trait_id };
895 let assoc_segment =
896 fhir::PathSegment { args: &[], constraints: &[], ident, res: fhir::Res::Err };
897 let mut env = Env::empty();
898 let alias_ty =
899 self.conv_type_relative_type_path(&mut env, ident.span, res, &assoc_segment)?;
900 return Ok(rty::Sort::Alias(rty::AliasKind::Projection, alias_ty));
901 }
902 fhir::SortRes::PrimSort(fhir::PrimSort::Set) => {
903 self.check_prim_sort_generics(path, fhir::PrimSort::Set)?;
904 rty::SortCtor::Set
905 }
906 fhir::SortRes::PrimSort(fhir::PrimSort::Map) => {
907 self.check_prim_sort_generics(path, fhir::PrimSort::Map)?;
908 rty::SortCtor::Map
909 }
910 fhir::SortRes::User(def_id) => {
911 self.check_user_defined_sort_param_count(path, def_id)?;
912 rty::SortCtor::User(def_id)
913 }
914 fhir::SortRes::Adt(def_id) => {
915 let sort_def = self.genv().adt_sort_def_of(def_id)?;
916 if path.args.len() != sort_def.param_count() {
917 let err = errors::IncorrectGenericsOnSort::new(
918 self.genv(),
919 def_id,
920 path.segments.last().unwrap().span,
921 path.args.len(),
922 sort_def.param_count(),
923 );
924 Err(self.emit(err))?;
925 }
926 rty::SortCtor::Adt(sort_def)
927 }
928 };
929 let args = path.args.iter().map(|t| self.conv_sort(t)).try_collect()?;
930
931 Ok(rty::Sort::app(ctor, args))
932 }
933
934 fn check_user_defined_sort_param_count(
935 &mut self,
936 path: &fhir::SortPath<'_>,
937 def_id: FluxDefId,
938 ) -> QueryResult {
939 let expected_param_count = self.genv().sort_decl_param_count(def_id);
940 if path.args.len() != expected_param_count {
941 let err = errors::IncorrectGenericsOnUserDefinedOpaqueSort::new(
942 path.segments.last().unwrap().span,
943 def_id.name(),
944 expected_param_count,
945 path.args.len(),
946 );
947 Err(self.emit(err))?;
948 }
949 Ok(())
950 }
951
952 fn check_prim_sort_generics(
953 &mut self,
954 path: &fhir::SortPath<'_>,
955 prim_sort: fhir::PrimSort,
956 ) -> QueryResult {
957 if path.args.len() != prim_sort.generics() {
958 let err = errors::GenericsOnPrimitiveSort::new(
959 path.segments.last().unwrap().span,
960 prim_sort.name_str(),
961 path.args.len(),
962 prim_sort.generics(),
963 );
964 Err(self.emit(err))?;
965 }
966 Ok(())
967 }
968}
969
970impl<'genv, 'tcx: 'genv, P: ConvPhase<'genv, 'tcx>> ConvCtxt<P> {
972 fn conv_fn_decl(
973 &mut self,
974 env: &mut Env,
975 safety: Safety,
976 abi: rustc_abi::ExternAbi,
977 decl: &fhir::FnDecl,
978 body_id: Option<BodyId>,
979 ) -> QueryResult<rty::FnSig> {
980 let mut requires = vec![];
981 for req in decl.requires {
982 requires.push(self.conv_requires(env, req)?);
983 }
984
985 let mut inputs = vec![];
986 let params =
987 if let Some(body_id) = body_id { self.tcx().hir_body(body_id).params } else { &[] };
988 for (i, ty) in decl.inputs.iter().enumerate() {
989 let ty = if let Some(param) = params.get(i)
990 && let hir::PatKind::Binding(_, _, ident, _) = param.pat.kind
991 {
992 self.conv_ty_with_name(env, ty, ident.name)?
993 } else {
994 self.conv_ty(env, ty)?
995 };
996 inputs.push(ty);
997 }
998
999 let output = self.conv_fn_output(env, &decl.output)?;
1000
1001 Ok(rty::FnSig::new(safety, abi, requires.into(), inputs.into(), output))
1002 }
1003
1004 fn conv_requires(
1005 &mut self,
1006 env: &mut Env,
1007 requires: &fhir::Requires,
1008 ) -> QueryResult<rty::Expr> {
1009 if requires.params.is_empty() {
1010 self.conv_expr(env, &requires.pred)
1011 } else {
1012 env.push_layer(Layer::list(self.results(), 0, requires.params));
1013 let pred = self.conv_expr(env, &requires.pred)?;
1014 let sorts = env.pop_layer().into_bound_vars(self.genv())?;
1015 Ok(rty::Expr::forall(rty::Binder::bind_with_vars(pred, sorts)))
1016 }
1017 }
1018
1019 fn conv_ensures(
1020 &mut self,
1021 env: &mut Env,
1022 ensures: &fhir::Ensures,
1023 ) -> QueryResult<rty::Ensures> {
1024 match ensures {
1025 fhir::Ensures::Type(loc, ty) => {
1026 Ok(rty::Ensures::Type(self.conv_loc(env, *loc)?, self.conv_ty(env, ty)?))
1027 }
1028 fhir::Ensures::Pred(pred) => Ok(rty::Ensures::Pred(self.conv_expr(env, pred)?)),
1029 }
1030 }
1031
1032 fn conv_fn_output(
1033 &mut self,
1034 env: &mut Env,
1035 output: &fhir::FnOutput,
1036 ) -> QueryResult<rty::Binder<rty::FnOutput>> {
1037 env.push_layer(Layer::list(self.results(), 0, output.params));
1038
1039 let ret = self.conv_ty(env, &output.ret)?;
1040
1041 let ensures: List<rty::Ensures> = output
1042 .ensures
1043 .iter()
1044 .map(|ens| self.conv_ensures(env, ens))
1045 .try_collect()?;
1046 let output = rty::FnOutput::new(ret, ensures);
1047
1048 let vars = env.pop_layer().into_bound_vars(self.genv())?;
1049 Ok(rty::Binder::bind_with_vars(output, vars))
1050 }
1051
1052 fn conv_generic_bounds(
1053 &mut self,
1054 env: &mut Env,
1055 bounded_ty_span: Span,
1056 bounded_ty: rty::Ty,
1057 bounds: fhir::GenericBounds,
1058 ) -> QueryResult<Vec<rty::Clause>> {
1059 let mut clauses = vec![];
1060 for bound in bounds {
1061 match bound {
1062 fhir::GenericBound::Trait(poly_trait_ref) => {
1063 match poly_trait_ref.modifiers {
1064 fhir::TraitBoundModifier::None => {
1065 self.conv_poly_trait_ref(
1066 env,
1067 bounded_ty_span,
1068 &bounded_ty,
1069 poly_trait_ref,
1070 &mut clauses,
1071 )?;
1072 }
1073 fhir::TraitBoundModifier::Maybe => {
1074 }
1078 }
1079 }
1080 fhir::GenericBound::Outlives(lft) => {
1081 let re = self.conv_lifetime(env, *lft, bounded_ty_span);
1082 clauses.push(rty::Clause::new(
1083 List::empty(),
1084 rty::ClauseKind::TypeOutlives(rty::OutlivesPredicate(
1085 bounded_ty.clone(),
1086 re,
1087 )),
1088 ));
1089 }
1090 }
1091 }
1092 Ok(clauses)
1093 }
1094
1095 fn conv_poly_trait_ref(
1097 &mut self,
1098 env: &mut Env,
1099 span: Span,
1100 bounded_ty: &rty::Ty,
1101 poly_trait_ref: &fhir::PolyTraitRef,
1102 clauses: &mut Vec<rty::Clause>,
1103 ) -> QueryResult {
1104 let generic_params = &poly_trait_ref.bound_generic_params;
1105 let layer =
1106 Layer::list(self.results(), generic_params.len() as u32, poly_trait_ref.refine_params);
1107 env.push_layer(layer);
1108
1109 let trait_id = poly_trait_ref.trait_def_id();
1110 let generics = self.genv().generics_of(trait_id)?;
1111 let trait_segment = poly_trait_ref.trait_ref.last_segment();
1112
1113 let self_param = generics.param_at(0, self.genv())?;
1114 let mut args = vec![
1115 self.try_to_ty_or_base(self_param.kind, span, bounded_ty)?
1116 .into(),
1117 ];
1118 self.conv_generic_args_into(env, trait_id, trait_segment, &mut args)?;
1119
1120 let vars = env.top_layer().to_bound_vars(self.genv())?;
1121 let poly_trait_ref = rty::Binder::bind_with_vars(
1122 rty::TraitRef { def_id: trait_id, args: args.into() },
1123 vars,
1124 );
1125
1126 clauses.push(
1127 poly_trait_ref
1128 .clone()
1129 .map(|trait_ref| {
1130 rty::ClauseKind::Trait(rty::TraitPredicate { trait_ref: trait_ref.clone() })
1131 })
1132 .into(),
1133 );
1134
1135 for cstr in trait_segment.constraints {
1136 self.conv_assoc_item_constraint(env, &poly_trait_ref, cstr, clauses)?;
1137 }
1138
1139 env.pop_layer();
1140
1141 Ok(())
1142 }
1143
1144 fn conv_assoc_item_constraint(
1145 &mut self,
1146 env: &mut Env,
1147 poly_trait_ref: &rty::PolyTraitRef,
1148 constraint: &fhir::AssocItemConstraint,
1149 clauses: &mut Vec<rty::Clause>,
1150 ) -> QueryResult {
1151 let tcx = self.tcx();
1152
1153 let candidate = self.probe_single_bound_for_assoc_item(
1154 || traits::supertraits(tcx, poly_trait_ref.to_rustc(tcx)),
1155 constraint.ident,
1156 AssocTag::Type,
1157 )?;
1158 let assoc_item_id = AssocTag::Type
1159 .trait_defines_item_named(self.genv(), candidate.def_id(), constraint.ident)?
1160 .unwrap()
1161 .def_id;
1162
1163 let fhir::AssocItemConstraintKind::Equality { term } = &constraint.kind;
1164 let span = term.span;
1165 let term = self.conv_ty(env, term)?;
1166 let term = self.ty_to_subset_ty_ctor(span, &term)?;
1167
1168 let clause = poly_trait_ref
1169 .clone()
1170 .map(|trait_ref| {
1171 let args = trait_ref.args;
1173 let refine_args = List::empty();
1174 let projection_ty = rty::AliasTy { def_id: assoc_item_id, args, refine_args };
1175
1176 rty::ClauseKind::Projection(rty::ProjectionPredicate { projection_ty, term })
1177 })
1178 .into();
1179
1180 clauses.push(clause);
1181 Ok(())
1182 }
1183
1184 fn conv_ty_with_name(
1185 &mut self,
1186 env: &mut Env,
1187 ty: &fhir::Ty,
1188 name: Symbol,
1189 ) -> QueryResult<rty::Ty> {
1190 if let fhir::TyKind::BaseTy(bty) = &ty.kind {
1191 Ok(self.conv_bty(env, bty, Some(name))?.to_ty())
1192 } else {
1193 self.conv_ty(env, ty)
1194 }
1195 }
1196
1197 fn conv_ty(&mut self, env: &mut Env, ty: &fhir::Ty) -> QueryResult<rty::Ty> {
1198 match &ty.kind {
1199 fhir::TyKind::BaseTy(bty) => Ok(self.conv_bty(env, bty, None)?.to_ty()),
1200 fhir::TyKind::Indexed(bty, idx) => {
1201 let fhir_id = bty.fhir_id;
1202 let rty::TyOrCtor::Ctor(ty_ctor) = self.conv_bty(env, bty, None)? else {
1203 return Err(self.emit(errors::RefinedUnrefinableType::new(bty.span)))?;
1204 };
1205 let idx = self.conv_expr(env, idx)?;
1206 self.0.insert_node_sort(fhir_id, ty_ctor.sort());
1207 Ok(ty_ctor.replace_bound_reft(&idx))
1208 }
1209 fhir::TyKind::Exists(params, ty) => {
1210 let layer = Layer::list(self.results(), 0, params);
1211 env.push_layer(layer);
1212 let ty = self.conv_ty(env, ty)?;
1213 let sorts = env.pop_layer().into_bound_vars(self.genv())?;
1214 if sorts.is_empty() {
1215 Ok(ty.shift_out_escaping(1))
1216 } else {
1217 Ok(rty::Ty::exists(rty::Binder::bind_with_vars(ty, sorts)))
1218 }
1219 }
1220 fhir::TyKind::StrgRef(lft, loc, ty) => {
1221 let re = self.conv_lifetime(env, *lft, ty.span);
1222 let loc = self.conv_loc(env, **loc)?;
1223 let ty = self.conv_ty(env, ty)?;
1224 Ok(rty::Ty::strg_ref(re, loc, ty))
1225 }
1226 fhir::TyKind::Ref(lft, fhir::MutTy { ty, mutbl }) => {
1227 let region = self.conv_lifetime(env, *lft, ty.span);
1228 Ok(rty::Ty::mk_ref(region, self.conv_ty(env, ty)?, *mutbl))
1229 }
1230 fhir::TyKind::BareFn(bare_fn) => {
1231 let mut env = Env::empty();
1232 env.push_layer(Layer::list(
1233 self.results(),
1234 bare_fn.generic_params.len() as u32,
1235 &[],
1236 ));
1237 let fn_sig =
1238 self.conv_fn_decl(&mut env, bare_fn.safety, bare_fn.abi, bare_fn.decl, None)?;
1239 let vars = bare_fn
1240 .generic_params
1241 .iter()
1242 .map(|param| self.param_as_bound_var(param))
1243 .try_collect()?;
1244 let poly_fn_sig = rty::Binder::bind_with_vars(fn_sig, vars);
1245 Ok(rty::BaseTy::FnPtr(poly_fn_sig).to_ty())
1246 }
1247 fhir::TyKind::Tuple(tys) => {
1248 let tys: List<rty::Ty> =
1249 tys.iter().map(|ty| self.conv_ty(env, ty)).try_collect()?;
1250 Ok(rty::Ty::tuple(tys))
1251 }
1252 fhir::TyKind::Array(ty, len) => {
1253 Ok(rty::Ty::array(self.conv_ty(env, ty)?, self.conv_const_arg(*len)))
1254 }
1255 fhir::TyKind::Never => Ok(rty::Ty::never()),
1256 fhir::TyKind::Constr(pred, ty) => {
1257 let pred = self.conv_expr(env, pred)?;
1258 Ok(rty::Ty::constr(pred, self.conv_ty(env, ty)?))
1259 }
1260 fhir::TyKind::RawPtr(ty, mutability) => {
1261 Ok(rty::Ty::indexed(
1262 rty::BaseTy::RawPtr(self.conv_ty(env, ty)?, *mutability),
1263 rty::Expr::unit(),
1264 ))
1265 }
1266 fhir::TyKind::OpaqueDef(opaque_ty) => self.conv_opaque_def(env, opaque_ty, ty.span),
1267 fhir::TyKind::TraitObject(trait_bounds, lft, syn) => {
1268 if matches!(syn, rustc_ast::TraitObjectSyntax::Dyn) {
1269 self.conv_trait_object(env, trait_bounds, *lft, ty.span)
1270 } else {
1271 span_bug!(ty.span, "dyn* traits not supported yet")
1272 }
1273 }
1274 fhir::TyKind::Infer => Ok(rty::Ty::infer(self.next_type_vid())),
1275 fhir::TyKind::Err(err) => Err(QueryErr::Emitted(*err)),
1276 }
1277 }
1278
1279 fn conv_opaque_def(
1281 &mut self,
1282 env: &mut Env,
1283 opaque_ty: &fhir::OpaqueTy,
1284 span: Span,
1285 ) -> QueryResult<rty::Ty> {
1286 let def_id = opaque_ty.def_id;
1287
1288 if P::HAS_ELABORATED_INFORMATION {
1289 let lifetimes = self.tcx().opaque_captured_lifetimes(def_id.local_id());
1290
1291 let generics = self.tcx().generics_of(opaque_ty.def_id);
1292
1293 let offset = generics.parent_count;
1294
1295 let args = rty::GenericArg::for_item(self.genv(), def_id.resolved_id(), |param, _| {
1296 if let Some(i) = (param.index as usize).checked_sub(offset) {
1297 let (lifetime, _) = lifetimes[i];
1298 rty::GenericArg::Lifetime(self.conv_resolved_lifetime(env, lifetime, span))
1299 } else {
1300 rty::GenericArg::from_param_def(param)
1301 }
1302 })?;
1303 let reft_args = rty::RefineArgs::identity_for_item(self.genv(), def_id.resolved_id())?;
1304 let alias_ty = rty::AliasTy::new(def_id.resolved_id(), args, reft_args);
1305 Ok(rty::BaseTy::opaque(alias_ty).to_ty())
1306 } else {
1307 self.conv_opaque_ty(opaque_ty)?;
1311
1312 let alias_ty = rty::AliasTy::new(def_id.resolved_id(), List::empty(), List::empty());
1315 Ok(rty::BaseTy::opaque(alias_ty).to_ty())
1316 }
1317 }
1318
1319 fn conv_trait_object(
1320 &mut self,
1321 env: &mut Env,
1322 trait_bounds: &[fhir::PolyTraitRef],
1323 lifetime: fhir::Lifetime,
1324 span: Span,
1325 ) -> QueryResult<rty::Ty> {
1326 let mut bounds = vec![];
1333 let dummy_self = rty::Ty::trait_object_dummy_self();
1334 for trait_bound in trait_bounds.iter().rev() {
1335 self.conv_poly_trait_ref(env, trait_bound.span, &dummy_self, trait_bound, &mut bounds)?;
1336 }
1337
1338 let mut trait_bounds = vec![];
1340 let mut projection_bounds = vec![];
1341 for pred in bounds {
1342 let bound_pred = pred.kind();
1343 let vars = bound_pred.vars().clone();
1344 match bound_pred.skip_binder() {
1345 rty::ClauseKind::Trait(trait_pred) => {
1346 trait_bounds.push(rty::Binder::bind_with_vars(trait_pred.trait_ref, vars));
1347 }
1348 rty::ClauseKind::Projection(proj) => {
1349 projection_bounds.push(rty::Binder::bind_with_vars(proj, vars));
1350 }
1351 rty::ClauseKind::RegionOutlives(_) => {}
1352 rty::ClauseKind::TypeOutlives(_) => {}
1353 rty::ClauseKind::ConstArgHasType(..) => {
1354 bug!("did not expect {pred:?} clause in object bounds");
1355 }
1356 }
1357 }
1358
1359 let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) = trait_bounds
1361 .into_iter()
1362 .partition(|trait_ref| self.tcx().trait_is_auto(trait_ref.def_id()));
1363
1364 {
1366 let mut duplicates = FxHashSet::default();
1367 auto_traits.retain(|trait_ref| duplicates.insert(trait_ref.def_id()));
1368 }
1369
1370 let regular_trait_predicates = regular_traits.into_iter().map(|poly_trait_ref| {
1371 poly_trait_ref.map(|trait_ref| {
1372 let args = trait_ref.args.iter().skip(1).cloned().collect();
1374 rty::ExistentialPredicate::Trait(rty::ExistentialTraitRef {
1375 def_id: trait_ref.def_id,
1376 args,
1377 })
1378 })
1379 });
1380
1381 let auto_trait_predicates = auto_traits.into_iter().map(|trait_def| {
1382 rty::Binder::dummy(rty::ExistentialPredicate::AutoTrait(trait_def.def_id()))
1383 });
1384
1385 let existential_projections = projection_bounds.into_iter().map(|bound| {
1386 bound.map(|proj| {
1387 let args = proj.projection_ty.args.iter().skip(1).cloned().collect();
1389 rty::ExistentialPredicate::Projection(rty::ExistentialProjection {
1390 def_id: proj.projection_ty.def_id,
1391 args,
1392 term: proj.term.clone(),
1393 })
1394 })
1395 });
1396
1397 let existential_predicates = {
1398 let mut v = regular_trait_predicates
1399 .chain(existential_projections)
1400 .chain(auto_trait_predicates)
1401 .collect_vec();
1402 v.sort_by(|a, b| {
1403 a.as_ref()
1404 .skip_binder()
1405 .stable_cmp(self.tcx(), b.as_ref().skip_binder())
1406 });
1407 List::from_vec(v)
1408 };
1409
1410 let region = self.conv_lifetime(env, lifetime, span);
1411 Ok(rty::Ty::dynamic(existential_predicates, region))
1412 }
1413
1414 pub(crate) fn conv_bty(
1415 &mut self,
1416 env: &mut Env,
1417 bty: &fhir::BaseTy,
1418 name: Option<Symbol>,
1419 ) -> QueryResult<rty::TyOrCtor> {
1420 match &bty.kind {
1421 fhir::BaseTyKind::Path(fhir::QPath::Resolved(qself, path)) => {
1422 self.conv_qpath(env, *qself, path, name)
1423 }
1424 fhir::BaseTyKind::Path(fhir::QPath::TypeRelative(qself, segment)) => {
1425 let qself_res =
1426 if let Some(path) = qself.as_path() { path.res } else { fhir::Res::Err };
1427 let alias_ty = self
1428 .conv_type_relative_type_path(env, qself.span, qself_res, segment)?
1429 .shift_in_escaping(1);
1430 let bty = rty::BaseTy::Alias(rty::AliasKind::Projection, alias_ty);
1431 let sort = bty.sort();
1432 let ty = rty::Ty::indexed(bty, rty::Expr::nu());
1433 Ok(rty::TyOrCtor::Ctor(rty::Binder::bind_with_sort(ty, sort)))
1434 }
1435 fhir::BaseTyKind::Slice(ty) => {
1436 let bty = rty::BaseTy::Slice(self.conv_ty(env, ty)?).shift_in_escaping(1);
1437 let sort = bty.sort();
1438 let ty = rty::Ty::indexed(bty, rty::Expr::nu());
1439 Ok(rty::TyOrCtor::Ctor(rty::Binder::bind_with_sort(ty, sort)))
1440 }
1441 fhir::BaseTyKind::Err(err) => Err(QueryErr::Emitted(*err)),
1442 }
1443 }
1444
1445 fn conv_type_relative_path<Tag: AssocItemTag>(
1446 &mut self,
1447 tag: Tag,
1448 qself_span: Span,
1449 qself_res: fhir::Res,
1450 assoc_ident: Ident,
1451 ) -> QueryResult<(Tag::AssocItem<'tcx>, rty::TraitRef)> {
1452 let tcx = self.tcx();
1453
1454 let bound = match qself_res {
1455 fhir::Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true } => {
1456 let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else {
1457 span_bug!(qself_span, "expected cycle error");
1459 };
1460
1461 self.probe_single_bound_for_assoc_item(
1462 || {
1463 traits::supertraits(
1464 tcx,
1465 ty::Binder::dummy(trait_ref.instantiate_identity()),
1466 )
1467 },
1468 assoc_ident,
1469 tag,
1470 )?
1471 }
1472 fhir::Res::Def(DefKind::TyParam, param_id)
1473 | fhir::Res::SelfTyParam { trait_: param_id } => {
1474 let predicates = type_param_predicates(tcx, param_id);
1475 self.probe_single_bound_for_assoc_item(
1476 || {
1477 tag.transitive_bounds_that_define_assoc_item(
1478 self.genv(),
1479 predicates.map(|pred| pred.map_bound(|t| t.trait_ref)),
1480 assoc_ident,
1481 )
1482 },
1483 assoc_ident,
1484 tag,
1485 )?
1486 }
1487 _ => self.report_assoc_item_not_found(assoc_ident.span, tag)?,
1488 };
1489
1490 let Some(trait_ref) = bound.no_bound_vars() else {
1491 Err(self.emit(
1499 query_bug!("associated path with uninferred generic parameters")
1500 .at(assoc_ident.span),
1501 ))?
1502 };
1503
1504 let trait_ref = trait_ref
1505 .lower(tcx)
1506 .map_err(|err| QueryErr::unsupported(trait_ref.def_id, err.into_err()))?
1507 .refine(&self.refiner()?)?;
1508
1509 let assoc_item = tag
1510 .trait_defines_item_named(self.genv(), trait_ref.def_id, assoc_ident)?
1511 .unwrap();
1512
1513 Ok((assoc_item, trait_ref))
1514 }
1515
1516 fn conv_type_relative_type_path(
1517 &mut self,
1518 env: &mut Env,
1519 qself_span: Span,
1520 qself_res: fhir::Res,
1521 assoc_segment: &fhir::PathSegment,
1522 ) -> QueryResult<rty::AliasTy> {
1523 let (assoc_item, trait_ref) = self.conv_type_relative_path(
1524 AssocTag::Type,
1525 qself_span,
1526 qself_res,
1527 assoc_segment.ident,
1528 )?;
1529
1530 let assoc_id = assoc_item.def_id;
1531 let mut args = trait_ref.args.to_vec();
1532 self.conv_generic_args_into(env, assoc_id, assoc_segment, &mut args)?;
1533
1534 let args = List::from_vec(args);
1535 let refine_args = List::empty();
1536 let alias_ty = rty::AliasTy { args, refine_args, def_id: assoc_id };
1537 Ok(alias_ty)
1538 }
1539
1540 fn conv_type_relative_const_path(
1541 &mut self,
1542 fhir_expr: &fhir::Expr,
1543 qself: &rty::Ty,
1544 assoc: Ident,
1545 ) -> QueryResult<rty::Expr> {
1546 let tcx = self.genv().tcx();
1547
1548 let mut candidates = vec![];
1549 if let Some(simplified_type) = qself.simplify_type() {
1550 candidates = tcx
1551 .incoherent_impls(simplified_type)
1552 .iter()
1553 .filter_map(|impl_id| {
1554 tcx.associated_items(impl_id).find_by_ident_and_kind(
1555 tcx,
1556 assoc,
1557 AssocTag::Const,
1558 *impl_id,
1559 )
1560 })
1561 .collect_vec();
1562 }
1563 let (expr, sort) = match &candidates[..] {
1564 [candidate] => self.conv_const(fhir_expr.span, candidate.def_id)?,
1565 [] => self.report_assoc_item_not_found(fhir_expr.span, AssocTag::Const)?,
1566 _ => self.report_ambiguous_assoc_item(fhir_expr.span, AssocTag::Const, assoc)?,
1567 };
1568 self.0.insert_node_sort(fhir_expr.fhir_id, sort);
1569 Ok(expr)
1570 }
1571
1572 fn refiner(&self) -> QueryResult<Refiner<'genv, 'tcx>> {
1574 match self.owner() {
1575 FluxOwnerId::Rust(owner_id) => {
1576 let def_id = self.genv().maybe_extern_id(owner_id.def_id);
1577 Refiner::default_for_item(self.genv(), def_id.resolved_id())
1578 }
1579 FluxOwnerId::Flux(_) => Err(query_bug!("cannot refine types insicde flux item")),
1580 }
1581 }
1582
1583 fn probe_single_bound_for_assoc_item<I, Tag: AssocItemTag>(
1584 &self,
1585 all_candidates: impl FnOnce() -> I,
1586 assoc_name: Ident,
1587 tag: Tag,
1588 ) -> QueryResult<ty::PolyTraitRef<'tcx>>
1589 where
1590 I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
1591 {
1592 let mut matching_candidates = vec![];
1593 for candidate in all_candidates() {
1594 if tag
1595 .trait_defines_item_named(self.genv(), candidate.def_id(), assoc_name)?
1596 .is_some()
1597 {
1598 matching_candidates.push(candidate);
1599 }
1600 }
1601
1602 let Some(bound) = matching_candidates.pop() else {
1603 self.report_assoc_item_not_found(assoc_name.span, tag)?;
1604 };
1605
1606 if !matching_candidates.is_empty() {
1607 self.report_ambiguous_assoc_item(assoc_name.span, tag, assoc_name)?;
1608 }
1609
1610 Ok(bound)
1611 }
1612
1613 fn conv_lifetime(&mut self, env: &Env, lft: fhir::Lifetime, span: Span) -> rty::Region {
1614 let res = match lft {
1615 fhir::Lifetime::Hole(_) => return rty::Region::ReVar(self.next_region_vid()),
1616 fhir::Lifetime::Resolved(res) => res,
1617 };
1618 self.conv_resolved_lifetime(env, res, span)
1619 }
1620
1621 fn conv_resolved_lifetime(&mut self, env: &Env, res: ResolvedArg, span: Span) -> rty::Region {
1622 let tcx = self.tcx();
1623 let lifetime_name = |def_id| tcx.item_name(def_id);
1624 match res {
1625 ResolvedArg::StaticLifetime => rty::ReStatic,
1626 ResolvedArg::EarlyBound(def_id) => {
1627 let index = self.genv().def_id_to_param_index(def_id.to_def_id());
1628 let name = lifetime_name(def_id.to_def_id());
1629 rty::ReEarlyParam(rty::EarlyParamRegion { index, name })
1630 }
1631 ResolvedArg::LateBound(_, index, def_id) => {
1632 let Some(depth) = env.depth().checked_sub(1) else {
1633 span_bug!(span, "late-bound variable at depth 0")
1634 };
1635 let kind = rty::BoundRegionKind::Named(def_id.to_def_id());
1636 let var = BoundVar::from_u32(index);
1637 let bound_region = rty::BoundRegion { var, kind };
1638 rty::ReBound(rty::DebruijnIndex::from_usize(depth), bound_region)
1639 }
1640 ResolvedArg::Free(scope, id) => {
1641 let kind = rty::LateParamRegionKind::Named(id.to_def_id());
1642 rty::ReLateParam(rty::LateParamRegion { scope: scope.to_def_id(), kind })
1643 }
1644 ResolvedArg::Error(_) => bug!("lifetime resolved to an error"),
1645 }
1646 }
1647
1648 fn conv_const_arg(&mut self, cst: fhir::ConstArg) -> rty::Const {
1649 match cst.kind {
1650 fhir::ConstArgKind::Lit(lit) => rty::Const::from_usize(self.tcx(), lit),
1651 fhir::ConstArgKind::Param(def_id) => {
1652 rty::Const {
1653 kind: rty::ConstKind::Param(def_id_to_param_const(self.genv(), def_id)),
1654 }
1655 }
1656 fhir::ConstArgKind::Infer => {
1657 rty::Const {
1658 kind: rty::ConstKind::Infer(ty::InferConst::Var(self.next_const_vid())),
1659 }
1660 }
1661 }
1662 }
1663
1664 fn conv_qpath(
1665 &mut self,
1666 env: &mut Env,
1667 qself: Option<&fhir::Ty>,
1668 path: &fhir::Path,
1669 name: Option<Symbol>,
1670 ) -> QueryResult<rty::TyOrCtor> {
1671 let bty = match path.res {
1672 fhir::Res::PrimTy(prim_ty) => {
1673 self.check_prim_ty_generics(path, prim_ty)?;
1674 prim_ty_to_bty(prim_ty)
1675 }
1676 fhir::Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, did) => {
1677 let adt_def = self.genv().adt_def(did)?;
1678 let args = self.conv_generic_args(env, did, path.last_segment())?;
1679 rty::BaseTy::adt(adt_def, args)
1680 }
1681 fhir::Res::Def(DefKind::TyParam, def_id) => {
1682 let owner_id = ty_param_owner(self.genv(), def_id);
1683 let param_ty = def_id_to_param_ty(self.genv(), def_id);
1684 self.check_ty_param_generics(path, param_ty)?;
1685 let param = self
1686 .genv()
1687 .generics_of(owner_id)?
1688 .param_at(param_ty.index as usize, self.genv())?;
1689 match param.kind {
1690 rty::GenericParamDefKind::Type { .. } => {
1691 return Ok(rty::TyOrCtor::Ty(rty::Ty::param(param_ty)));
1692 }
1693 rty::GenericParamDefKind::Base { .. } => rty::BaseTy::Param(param_ty),
1694 _ => return Err(query_bug!("unexpected param kind")),
1695 }
1696 }
1697 fhir::Res::SelfTyParam { trait_ } => {
1698 self.check_self_ty_generics(path)?;
1699 let param = &self.genv().generics_of(trait_)?.own_params[0];
1700 match param.kind {
1701 rty::GenericParamDefKind::Type { .. } => {
1702 return Ok(rty::TyOrCtor::Ty(rty::Ty::param(rty::SELF_PARAM_TY)));
1703 }
1704 rty::GenericParamDefKind::Base { .. } => rty::BaseTy::Param(rty::SELF_PARAM_TY),
1705 _ => return Err(query_bug!("unexpected param kind")),
1706 }
1707 }
1708 fhir::Res::SelfTyAlias { alias_to, .. } => {
1709 self.check_self_ty_generics(path)?;
1710 if P::EXPAND_TYPE_ALIASES {
1711 return Ok(self.genv().type_of(alias_to)?.instantiate_identity());
1712 } else {
1713 rty::BaseTy::Alias(
1714 rty::AliasKind::Free,
1715 rty::AliasTy {
1716 def_id: alias_to,
1717 args: List::empty(),
1718 refine_args: List::empty(),
1719 },
1720 )
1721 }
1722 }
1723 fhir::Res::Def(DefKind::AssocTy, assoc_id) => {
1724 let trait_id = self.tcx().trait_of_assoc(assoc_id).unwrap();
1725
1726 let [.., trait_segment, assoc_segment] = path.segments else {
1727 span_bug!(path.span, "expected at least two segments");
1728 };
1729
1730 let Some(qself) = qself else {
1731 self.report_ambiguous_assoc_item(
1732 path.span,
1733 AssocTag::Type,
1734 assoc_segment.ident,
1735 )?
1736 };
1737
1738 let trait_generics = self.genv().generics_of(trait_id)?;
1739 let qself =
1740 self.conv_ty_to_generic_arg(env, &trait_generics.own_params[0], qself)?;
1741 let mut args = vec![qself];
1742 self.conv_generic_args_into(env, trait_id, trait_segment, &mut args)?;
1743 self.conv_generic_args_into(env, assoc_id, assoc_segment, &mut args)?;
1744 let args = List::from_vec(args);
1745
1746 let refine_args = List::empty();
1747 let alias_ty = rty::AliasTy { args, refine_args, def_id: assoc_id };
1748 rty::BaseTy::Alias(rty::AliasKind::Projection, alias_ty)
1749 }
1750 fhir::Res::Def(DefKind::TyAlias, def_id) => {
1751 self.check_refinement_generics(path, def_id)?;
1752 let args = self.conv_generic_args(env, def_id, path.last_segment())?;
1753 self.0.insert_path_args(path.fhir_id, args.clone());
1754 let refine_args = path
1755 .refine
1756 .iter()
1757 .map(|expr| self.conv_expr(env, expr))
1758 .try_collect_vec()?;
1759
1760 if P::EXPAND_TYPE_ALIASES {
1761 let tcx = self.tcx();
1762 return Ok(self
1763 .genv()
1764 .type_of(def_id)?
1765 .instantiate(tcx, &args, &refine_args));
1766 } else {
1767 rty::BaseTy::Alias(
1768 rty::AliasKind::Free,
1769 rty::AliasTy { def_id, args, refine_args: List::from(refine_args) },
1770 )
1771 }
1772 }
1773 fhir::Res::Def(DefKind::ForeignTy, def_id) => {
1774 self.check_foreign_ty_generics(path)?;
1775 rty::BaseTy::Foreign(def_id)
1776 }
1777 fhir::Res::Def(kind, def_id) => self.report_expected_type(path.span, kind, def_id)?,
1778 fhir::Res::Param(..) | fhir::Res::GlobalFunc(..) | fhir::Res::Err => {
1779 span_bug!(path.span, "unexpected resolution in conv_ty_ctor: {:?}", path.res)
1780 }
1781 };
1782 let sort = bty.sort();
1783 let bty = bty.shift_in_escaping(1);
1784 let kind = match name {
1785 Some(name) => BoundReftKind::Named(name),
1786 None => BoundReftKind::Anon,
1787 };
1788 let var = rty::BoundVariableKind::Refine(sort, rty::InferMode::EVar, kind);
1789 let ctor = rty::Binder::bind_with_vars(
1790 rty::Ty::indexed(bty, rty::Expr::nu()),
1791 List::singleton(var),
1792 );
1793 Ok(rty::TyOrCtor::Ctor(ctor))
1794 }
1795
1796 fn param_as_bound_var(
1797 &mut self,
1798 param: &fhir::GenericParam,
1799 ) -> QueryResult<rty::BoundVariableKind> {
1800 let def_id = param.def_id.resolved_id();
1801 match param.kind {
1802 fhir::GenericParamKind::Lifetime => {
1803 Ok(rty::BoundVariableKind::Region(rty::BoundRegionKind::Named(def_id)))
1804 }
1805 fhir::GenericParamKind::Const { .. } | fhir::GenericParamKind::Type { .. } => {
1806 Err(query_bug!(def_id, "unsupported param kind `{:?}`", param.kind))
1807 }
1808 }
1809 }
1810
1811 fn conv_generic_args(
1812 &mut self,
1813 env: &mut Env,
1814 def_id: DefId,
1815 segment: &fhir::PathSegment,
1816 ) -> QueryResult<List<rty::GenericArg>> {
1817 let mut into = vec![];
1818 self.conv_generic_args_into(env, def_id, segment, &mut into)?;
1819 Ok(List::from(into))
1820 }
1821
1822 fn conv_generic_args_into(
1823 &mut self,
1824 env: &mut Env,
1825 def_id: DefId,
1826 segment: &fhir::PathSegment,
1827 into: &mut Vec<rty::GenericArg>,
1828 ) -> QueryResult {
1829 let generics = self.genv().generics_of(def_id)?;
1830
1831 self.check_generic_arg_count(&generics, def_id, segment)?;
1832
1833 let len = into.len();
1834 for (idx, arg) in segment.args.iter().enumerate() {
1835 let param = generics.param_at(idx + len, self.genv())?;
1836 match arg {
1837 fhir::GenericArg::Lifetime(lft) => {
1838 into.push(rty::GenericArg::Lifetime(self.conv_lifetime(
1839 env,
1840 *lft,
1841 segment.ident.span,
1842 )));
1843 }
1844 fhir::GenericArg::Type(ty) => {
1845 into.push(self.conv_ty_to_generic_arg(env, ¶m, ty)?);
1846 }
1847 fhir::GenericArg::Const(cst) => {
1848 into.push(rty::GenericArg::Const(self.conv_const_arg(*cst)));
1849 }
1850 fhir::GenericArg::Infer => {
1851 into.push(self.conv_generic_arg_hole(env, param, segment.ident.span)?);
1852 }
1853 }
1854 }
1855 self.fill_generic_args_defaults(def_id, into)
1856 }
1857
1858 fn conv_generic_arg_hole(
1859 &mut self,
1860 env: &mut Env,
1861 param: rty::GenericParamDef,
1862 span: Span,
1863 ) -> QueryResult<rty::GenericArg> {
1864 match param.kind {
1865 rty::GenericParamDefKind::Type { .. } | rty::GenericParamDefKind::Base { .. } => {
1866 let ty = fhir::Ty { kind: fhir::TyKind::Infer, span };
1867 Ok(self.conv_ty_to_generic_arg(env, ¶m, &ty)?)
1868 }
1869 rty::GenericParamDefKind::Const { .. } => {
1870 let cst = fhir::ConstArg { kind: fhir::ConstArgKind::Infer, span };
1871 Ok(rty::GenericArg::Const(self.conv_const_arg(cst)))
1872 }
1873 rty::GenericParamDefKind::Lifetime => {
1874 let re = rty::Region::ReVar(self.next_region_vid());
1875 Ok(rty::GenericArg::Lifetime(re))
1876 }
1877 }
1878 }
1879
1880 fn check_generic_arg_count(
1881 &mut self,
1882 generics: &rty::Generics,
1883 def_id: DefId,
1884 segment: &fhir::PathSegment,
1885 ) -> QueryResult {
1886 let found = segment.args.len();
1887 let mut param_count = generics.own_params.len();
1888
1889 if let DefKind::Trait = self.genv().def_kind(def_id) {
1891 param_count -= 1;
1892 }
1893
1894 let min = param_count - generics.own_default_count();
1895 let max = param_count;
1896 if min == max && found != min {
1897 Err(self.emit(errors::GenericArgCountMismatch::new(
1898 self.genv(),
1899 def_id,
1900 segment,
1901 min,
1902 )))?;
1903 }
1904 if found < min {
1905 Err(self.emit(errors::TooFewGenericArgs::new(self.genv(), def_id, segment, min)))?;
1906 }
1907 if found > max {
1908 Err(self.emit(errors::TooManyGenericArgs::new(self.genv(), def_id, segment, min)))?;
1909 }
1910 Ok(())
1911 }
1912
1913 fn fill_generic_args_defaults(
1914 &mut self,
1915 def_id: DefId,
1916 into: &mut Vec<rty::GenericArg>,
1917 ) -> QueryResult {
1918 let generics = self.genv().generics_of(def_id)?;
1919 for param in generics.own_params.iter().skip(into.len()) {
1920 debug_assert!(matches!(
1921 param.kind,
1922 rty::GenericParamDefKind::Type { has_default: true }
1923 | rty::GenericParamDefKind::Base { has_default: true }
1924 ));
1925 let span = self.tcx().def_span(param.def_id);
1926 let ty = self
1929 .genv()
1930 .type_of(param.def_id)?
1931 .instantiate(self.tcx(), into, &[])
1932 .to_ty();
1933 into.push(self.try_to_ty_or_base(param.kind, span, &ty)?.into());
1934 }
1935 Ok(())
1936 }
1937
1938 fn conv_ty_to_generic_arg(
1939 &mut self,
1940 env: &mut Env,
1941 param: &rty::GenericParamDef,
1942 ty: &fhir::Ty,
1943 ) -> QueryResult<rty::GenericArg> {
1944 let rty_ty = self.conv_ty(env, ty)?;
1945 Ok(self.try_to_ty_or_base(param.kind, ty.span, &rty_ty)?.into())
1946 }
1947
1948 fn try_to_ty_or_base(
1949 &mut self,
1950 kind: rty::GenericParamDefKind,
1951 span: Span,
1952 ty: &rty::Ty,
1953 ) -> QueryResult<rty::TyOrBase> {
1954 match kind {
1955 rty::GenericParamDefKind::Type { .. } => Ok(rty::TyOrBase::Ty(ty.clone())),
1956 rty::GenericParamDefKind::Base { .. } => {
1957 Ok(rty::TyOrBase::Base(self.ty_to_subset_ty_ctor(span, ty)?))
1958 }
1959 _ => span_bug!(span, "unexpected param kind `{kind:?}`"),
1960 }
1961 }
1962
1963 fn ty_to_subset_ty_ctor(&mut self, span: Span, ty: &rty::Ty) -> QueryResult<rty::SubsetTyCtor> {
1964 let ctor = if let rty::TyKind::Infer(vid) = ty.kind() {
1965 let sort_vid =
1967 if vid.as_u32() == 0 { rty::SortVid::from_u32(0) } else { self.next_sort_vid() };
1968 rty::SubsetTyCtor::bind_with_sort(
1969 rty::SubsetTy::trivial(rty::BaseTy::Infer(*vid), rty::Expr::nu()),
1970 rty::Sort::Infer(sort_vid),
1971 )
1972 } else {
1973 ty.shallow_canonicalize()
1974 .as_ty_or_base()
1975 .as_base()
1976 .ok_or_else(|| self.emit(errors::InvalidBaseInstance::new(span)))?
1977 };
1978 Ok(ctor)
1979 }
1980
1981 #[track_caller]
1982 fn emit(&self, err: impl Diagnostic<'genv>) -> ErrorGuaranteed {
1983 self.genv().sess().emit_err(err)
1984 }
1985
1986 fn report_assoc_item_not_found<Tag: AssocItemTag>(
1987 &self,
1988 span: Span,
1989 assoc_tag: Tag,
1990 ) -> Result<!, ErrorGuaranteed> {
1991 Err(self.emit(errors::AssocItemNotFound { span, tag: assoc_tag.descr() }))?
1992 }
1993
1994 fn report_ambiguous_assoc_item<Tag: AssocItemTag>(
1995 &self,
1996 span: Span,
1997 assoc_tag: Tag,
1998 assoc_name: Ident,
1999 ) -> Result<!, ErrorGuaranteed> {
2000 Err(self.emit(errors::AmbiguousAssocItem {
2001 span,
2002 name: assoc_name,
2003 tag: assoc_tag.descr(),
2004 }))?
2005 }
2006
2007 #[track_caller]
2008 fn report_expected_type(
2009 &self,
2010 span: Span,
2011 kind: DefKind,
2012 def_id: DefId,
2013 ) -> Result<!, ErrorGuaranteed> {
2014 Err(self.emit(errors::ExpectedType {
2015 span,
2016 def_descr: self.tcx().def_kind_descr(kind, def_id),
2017 name: self.tcx().def_path_str(def_id),
2018 }))?
2019 }
2020}
2021
2022impl<'genv, 'tcx: 'genv, P: ConvPhase<'genv, 'tcx>> ConvCtxt<P> {
2024 fn check_refinement_generics(&mut self, path: &fhir::Path, def_id: DefId) -> QueryResult {
2025 let generics = self.genv().refinement_generics_of(def_id)?;
2026 if generics.count() != path.refine.len() {
2027 let err = errors::RefineArgMismatch {
2028 span: path.span,
2029 expected: generics.count(),
2030 found: path.refine.len(),
2031 kind: self.tcx().def_descr(def_id),
2032 };
2033 Err(self.emit(err))?;
2034 }
2035 Ok(())
2036 }
2037
2038 fn check_prim_ty_generics(
2039 &mut self,
2040 path: &fhir::Path<'_>,
2041 prim_ty: rustc_hir::PrimTy,
2042 ) -> QueryResult {
2043 if !path.last_segment().args.is_empty() {
2044 let err = errors::GenericsOnPrimTy { span: path.span, name: prim_ty.name_str() };
2045 Err(self.emit(err))?;
2046 }
2047 Ok(())
2048 }
2049
2050 fn check_ty_param_generics(
2051 &mut self,
2052 path: &fhir::Path<'_>,
2053 param_ty: rty::ParamTy,
2054 ) -> QueryResult {
2055 if !path.last_segment().args.is_empty() {
2056 let err = errors::GenericsOnTyParam { span: path.span, name: param_ty.name };
2057 Err(self.emit(err))?;
2058 }
2059 Ok(())
2060 }
2061
2062 fn check_self_ty_generics(&mut self, path: &fhir::Path<'_>) -> QueryResult {
2063 if !path.last_segment().args.is_empty() {
2064 let err = errors::GenericsOnSelfTy { span: path.span };
2065 Err(self.emit(err))?;
2066 }
2067 Ok(())
2068 }
2069
2070 fn check_foreign_ty_generics(&mut self, path: &fhir::Path<'_>) -> QueryResult {
2071 if !path.last_segment().args.is_empty() {
2072 let err = errors::GenericsOnForeignTy { span: path.span };
2073 Err(self.emit(err))?;
2074 }
2075 Ok(())
2076 }
2077}
2078
2079fn prim_ty_to_bty(prim_ty: rustc_hir::PrimTy) -> rty::BaseTy {
2080 match prim_ty {
2081 rustc_hir::PrimTy::Int(int_ty) => rty::BaseTy::Int(int_ty),
2082 rustc_hir::PrimTy::Uint(uint_ty) => rty::BaseTy::Uint(uint_ty),
2083 rustc_hir::PrimTy::Float(float_ty) => rty::BaseTy::Float(float_ty),
2084 rustc_hir::PrimTy::Str => rty::BaseTy::Str,
2085 rustc_hir::PrimTy::Bool => rty::BaseTy::Bool,
2086 rustc_hir::PrimTy::Char => rty::BaseTy::Char,
2087 }
2088}
2089
2090impl<'genv, 'tcx: 'genv, P: ConvPhase<'genv, 'tcx>> ConvCtxt<P> {
2092 fn conv_lit(&self, lit: fhir::Lit, fhir_id: FhirId, span: Span) -> QueryResult<rty::Constant> {
2093 match lit {
2094 fhir::Lit::Int(n, kind) => {
2095 match kind {
2096 Some(fhir::NumLitKind::Int) => Ok(rty::Constant::from(n)),
2097 Some(fhir::NumLitKind::Real) => Ok(rty::Constant::Real(rty::Real(n))),
2098 None => {
2099 let sort = self.results().node_sort(fhir_id);
2100 if let rty::Sort::BitVec(bvsize) = sort {
2101 if let rty::BvSize::Fixed(size) = bvsize
2102 && (n == 0 || n.ilog2() < size)
2103 {
2104 Ok(rty::Constant::BitVec(n, size))
2105 } else {
2106 Err(self.emit(errors::InvalidBitVectorConstant::new(span, sort)))?
2107 }
2108 } else {
2109 Ok(rty::Constant::from(n))
2110 }
2111 }
2112 }
2113 }
2114 fhir::Lit::Bool(b) => Ok(rty::Constant::from(b)),
2115 fhir::Lit::Str(s) => Ok(rty::Constant::from(s)),
2116 fhir::Lit::Char(c) => Ok(rty::Constant::from(c)),
2117 }
2118 }
2119
2120 fn conv_expr(&mut self, env: &mut Env, expr: &fhir::Expr) -> QueryResult<rty::Expr> {
2121 let fhir_id = expr.fhir_id;
2122 let espan = ESpan::new(expr.span);
2123 let expr = match expr.kind {
2124 fhir::ExprKind::Var(QPathExpr::Resolved(path, _)) => self.conv_path_expr(env, path)?,
2125 fhir::ExprKind::Var(QPathExpr::TypeRelative(qself, assoc)) => {
2126 let qself = self.conv_ty(env, qself)?;
2127 self.conv_type_relative_const_path(expr, &qself, assoc)?
2128 }
2129 fhir::ExprKind::Literal(lit) => {
2130 rty::Expr::constant(self.conv_lit(lit, fhir_id, expr.span)?).at(espan)
2131 }
2132 fhir::ExprKind::BinaryOp(op, e1, e2) => {
2133 rty::Expr::binary_op(
2134 self.conv_bin_op(op, expr.fhir_id),
2135 self.conv_expr(env, e1)?,
2136 self.conv_expr(env, e2)?,
2137 )
2138 .at(espan)
2139 }
2140 fhir::ExprKind::UnaryOp(op, e) => {
2141 rty::Expr::unary_op(conv_un_op(op), self.conv_expr(env, e)?).at(espan)
2142 }
2143
2144 fhir::ExprKind::PrimApp(op, e1, e2) => {
2145 rty::Expr::prim_val(
2146 self.conv_primop_val(op),
2147 self.conv_expr(env, e1)?,
2148 self.conv_expr(env, e2)?,
2149 )
2150 .at(espan)
2151 }
2152 fhir::ExprKind::App(func, args) => {
2153 let sort_args = self.results().node_sort_args(fhir_id);
2154 rty::Expr::app(self.conv_func(env, &func)?, sort_args, self.conv_exprs(env, args)?)
2155 .at(espan)
2156 }
2157 fhir::ExprKind::Alias(alias, args) => {
2158 let args = args
2159 .iter()
2160 .map(|arg| self.conv_expr(env, arg))
2161 .try_collect()?;
2162 let alias = self.conv_alias_reft(env, expr.fhir_id, &alias)?;
2163 rty::Expr::alias(alias, args).at(espan)
2164 }
2165 fhir::ExprKind::IfThenElse(p, e1, e2) => {
2166 rty::Expr::ite(
2167 self.conv_expr(env, p)?,
2168 self.conv_expr(env, e1)?,
2169 self.conv_expr(env, e2)?,
2170 )
2171 .at(espan)
2172 }
2173 fhir::ExprKind::Dot(base, _) => {
2174 let proj = self.results().field_proj(fhir_id);
2175 rty::Expr::field_proj(self.conv_expr(env, base)?, proj)
2176 }
2177 fhir::ExprKind::Abs(params, body) => {
2178 env.push_layer(Layer::list(self.results(), 0, params));
2179 let pred = self.conv_expr(env, body)?;
2180 let vars = env.pop_layer().into_bound_vars(self.genv())?;
2181 let output = self.results().node_sort(body.fhir_id);
2182 let lam = rty::Lambda::bind_with_vars(pred, vars, output);
2183 rty::Expr::abs(lam)
2184 }
2185 fhir::ExprKind::Block(decls, body) => {
2186 for decl in decls {
2187 env.push_layer(Layer::list(self.results(), 0, &[decl.param]));
2188 }
2189 let mut body = self.conv_expr(env, body)?;
2190 for decl in decls.iter().rev() {
2191 let vars = env.pop_layer().into_bound_vars(self.genv())?;
2192 let init = self.conv_expr(env, &decl.init)?;
2193 body = rty::Expr::let_(init, rty::Binder::bind_with_vars(body, vars));
2194 }
2195 body
2196 }
2197 fhir::ExprKind::BoundedQuant(kind, param, rng, body) => {
2198 env.push_layer(Layer::list(self.results(), 0, &[param]));
2199 let pred = self.conv_expr(env, body)?;
2200 let vars = env.pop_layer().into_bound_vars(self.genv())?;
2201 let body = rty::Binder::bind_with_vars(pred, vars);
2202 rty::Expr::bounded_quant(kind, rng, body)
2203 }
2204 fhir::ExprKind::Record(flds) => {
2205 let def_id = self.results().record_ctor(expr.fhir_id);
2206 let flds = flds
2207 .iter()
2208 .map(|expr| self.conv_expr(env, expr))
2209 .try_collect()?;
2210 rty::Expr::ctor_struct(def_id, flds)
2211 }
2212 fhir::ExprKind::SetLiteral(elems) => {
2213 let elems = elems
2214 .iter()
2215 .map(|expr| self.conv_expr(env, expr))
2216 .try_collect()?;
2217 rty::Expr::set(elems)
2218 }
2219 fhir::ExprKind::Constructor(path, exprs, spread) => {
2220 let def_id = if let Some(path) = path {
2221 match path.res {
2222 fhir::Res::Def(DefKind::Enum | DefKind::Struct, def_id) => def_id,
2223 _ => span_bug!(path.span, "unexpected path in constructor"),
2224 }
2225 } else {
2226 self.results().record_ctor(expr.fhir_id)
2227 };
2228 let assns = self.conv_constructor_exprs(def_id, env, exprs, &spread)?;
2229 rty::Expr::ctor_struct(def_id, assns)
2230 }
2231 fhir::ExprKind::Err(err) => Err(QueryErr::Emitted(err))?,
2232 };
2233 Ok(self.add_coercions(expr, fhir_id))
2234 }
2235
2236 fn conv_loc(&mut self, env: &mut Env, loc: fhir::PathExpr) -> QueryResult<rty::Path> {
2237 Ok(self
2238 .conv_path_expr(env, loc)?
2239 .to_path()
2240 .unwrap_or_else(|| span_bug!(loc.span, "expected path, found `{loc:?}`")))
2241 }
2242
2243 fn conv_path_expr(&mut self, env: &mut Env, path: fhir::PathExpr) -> QueryResult<rty::Expr> {
2244 let genv = self.genv();
2245 let tcx = self.genv().tcx();
2246 let espan = ESpan::new(path.span);
2247 let (expr, sort) = match path.res {
2248 fhir::Res::Param(_, id) => (env.lookup(&path).to_expr(), self.results().param_sort(id)),
2249 fhir::Res::Def(DefKind::Const, def_id) => {
2250 self.hyperlink(path.span, tcx.def_ident_span(def_id));
2251 let (expr, sort) = self.conv_const(path.span, def_id)?;
2252 (expr.at(espan), sort)
2253 }
2254 fhir::Res::Def(DefKind::Ctor(..), ctor_id) => {
2255 let Some(sort) = genv.sort_of_def_id(ctor_id).emit(&genv)? else {
2256 span_bug!(path.span, "unexpected variant {ctor_id:?}")
2257 };
2258
2259 let variant_id = self.tcx().parent(ctor_id);
2260 let enum_id = self.tcx().parent(variant_id);
2261 self.hyperlink(path.span, tcx.def_ident_span(variant_id));
2262 let idx = variant_idx(self.tcx(), variant_id);
2263 (rty::Expr::ctor_enum(enum_id, idx), sort)
2264 }
2265 fhir::Res::Def(DefKind::ConstParam, def_id) => {
2266 self.hyperlink(path.span, tcx.def_ident_span(def_id));
2267 let sort = rty::Sort::Int;
2269 (rty::Expr::const_generic(def_id_to_param_const(genv, def_id)).at(espan), sort)
2270 }
2271 _ => {
2272 Err(self.emit(errors::InvalidRes { span: path.span, res_descr: path.res.descr() }))?
2273 }
2274 };
2275 self.0.insert_node_sort(path.fhir_id, sort);
2276 Ok(expr)
2277 }
2278
2279 fn conv_const(&self, span: Span, def_id: DefId) -> QueryResult<(rty::Expr, rty::Sort)> {
2280 match self.genv().constant_info(def_id)? {
2281 rty::ConstantInfo::Uninterpreted => {
2282 Err(self.emit(errors::ConstantAnnotationNeeded::new(span)))?
2283 }
2284 rty::ConstantInfo::Interpreted(_, sort) => {
2285 Ok((rty::Expr::const_def_id(def_id).at(ESpan::new(span)), sort))
2286 }
2287 }
2288 }
2289
2290 fn conv_constructor_exprs(
2291 &mut self,
2292 struct_def_id: DefId,
2293 env: &mut Env,
2294 exprs: &[fhir::FieldExpr],
2295 spread: &Option<&fhir::Spread>,
2296 ) -> QueryResult<List<rty::Expr>> {
2297 let spread = spread
2298 .map(|spread| self.conv_expr(env, &spread.expr))
2299 .transpose()?;
2300 let mut field_exprs_by_name: FxHashMap<Symbol, rty::Expr> = exprs
2301 .iter()
2302 .map(|field_expr| -> QueryResult<_> {
2303 Ok((field_expr.ident.name, self.conv_expr(env, &field_expr.expr)?))
2304 })
2305 .try_collect()?;
2306
2307 if !P::HAS_ELABORATED_INFORMATION {
2308 return Ok(List::default());
2309 };
2310
2311 let adt_def = self.genv().adt_sort_def_of(struct_def_id)?;
2312 let struct_variant = adt_def.struct_variant();
2313 let mut assns = Vec::new();
2314 for (idx, field_name) in struct_variant.field_names().iter().enumerate() {
2315 if let Some(expr) = field_exprs_by_name.remove(field_name) {
2316 assns.push(expr);
2317 } else if let Some(spread) = &spread {
2318 let proj = rty::FieldProj::Adt { def_id: struct_def_id, field: idx as u32 };
2319 assns.push(rty::Expr::field_proj(spread, proj));
2320 }
2321 }
2322 Ok(List::from_vec(assns))
2323 }
2324
2325 fn conv_exprs(&mut self, env: &mut Env, exprs: &[fhir::Expr]) -> QueryResult<List<rty::Expr>> {
2326 exprs.iter().map(|e| self.conv_expr(env, e)).collect()
2327 }
2328
2329 fn conv_primop_val(&self, op: fhir::BinOp) -> rty::BinOp {
2330 match op {
2331 fhir::BinOp::BitAnd => rty::BinOp::BitAnd(rty::Sort::Int),
2332 fhir::BinOp::BitOr => rty::BinOp::BitOr(rty::Sort::Int),
2333 fhir::BinOp::BitXor => rty::BinOp::BitXor(rty::Sort::Int),
2334 fhir::BinOp::BitShl => rty::BinOp::BitShl(rty::Sort::Int),
2335 fhir::BinOp::BitShr => rty::BinOp::BitShr(rty::Sort::Int),
2336 _ => bug!("unsupported primop {op:?}"),
2337 }
2338 }
2339
2340 fn conv_bin_op(&self, op: fhir::BinOp, fhir_id: FhirId) -> rty::BinOp {
2341 match op {
2342 fhir::BinOp::Iff => rty::BinOp::Iff,
2343 fhir::BinOp::Imp => rty::BinOp::Imp,
2344 fhir::BinOp::Or => rty::BinOp::Or,
2345 fhir::BinOp::And => rty::BinOp::And,
2346 fhir::BinOp::Eq => rty::BinOp::Eq,
2347 fhir::BinOp::Ne => rty::BinOp::Ne,
2348 fhir::BinOp::Gt => rty::BinOp::Gt(self.results().bin_op_sort(fhir_id)),
2349 fhir::BinOp::Ge => rty::BinOp::Ge(self.results().bin_op_sort(fhir_id)),
2350 fhir::BinOp::Lt => rty::BinOp::Lt(self.results().bin_op_sort(fhir_id)),
2351 fhir::BinOp::Le => rty::BinOp::Le(self.results().bin_op_sort(fhir_id)),
2352 fhir::BinOp::Add => rty::BinOp::Add(self.results().bin_op_sort(fhir_id)),
2353 fhir::BinOp::Sub => rty::BinOp::Sub(self.results().bin_op_sort(fhir_id)),
2354 fhir::BinOp::Mul => rty::BinOp::Mul(self.results().bin_op_sort(fhir_id)),
2355 fhir::BinOp::Mod => rty::BinOp::Mod(self.results().bin_op_sort(fhir_id)),
2356 fhir::BinOp::Div => rty::BinOp::Div(self.results().bin_op_sort(fhir_id)),
2357 fhir::BinOp::BitAnd => rty::BinOp::BitAnd(self.results().bin_op_sort(fhir_id)),
2358 fhir::BinOp::BitOr => rty::BinOp::BitOr(self.results().bin_op_sort(fhir_id)),
2359 fhir::BinOp::BitXor => rty::BinOp::BitXor(self.results().bin_op_sort(fhir_id)),
2360 fhir::BinOp::BitShl => rty::BinOp::BitShl(self.results().bin_op_sort(fhir_id)),
2361 fhir::BinOp::BitShr => rty::BinOp::BitShr(self.results().bin_op_sort(fhir_id)),
2362 }
2363 }
2364
2365 fn add_coercions(&self, mut expr: rty::Expr, fhir_id: FhirId) -> rty::Expr {
2366 let span = expr.span();
2367 for coercion in self.results().coercions_for(fhir_id) {
2368 expr = match *coercion {
2369 rty::Coercion::Inject(def_id) => {
2370 rty::Expr::ctor_struct(def_id, List::singleton(expr)).at_opt(span)
2371 }
2372 rty::Coercion::Project(def_id) => {
2373 rty::Expr::field_proj(expr, rty::FieldProj::Adt { def_id, field: 0 })
2374 .at_opt(span)
2375 }
2376 };
2377 }
2378 expr
2379 }
2380
2381 fn hyperlink(&self, span: Span, dst_span: Option<Span>) {
2382 if P::HAS_ELABORATED_INFORMATION
2383 && let Some(dst_span) = dst_span
2384 {
2385 dbg::hyperlink!(self.genv().tcx(), span, dst_span);
2386 }
2387 }
2388
2389 fn conv_func(&mut self, env: &Env, func: &fhir::PathExpr) -> QueryResult<rty::Expr> {
2390 let genv = self.genv();
2391 let span = func.span;
2392 let (expr, sort) = match func.res {
2393 fhir::Res::Param(_, id) => {
2394 let sort = self.results().param_sort(id);
2395 (env.lookup(func).to_expr(), sort)
2396 }
2397 fhir::Res::GlobalFunc(fhir::SpecFuncKind::Def(did)) => {
2398 self.hyperlink(span, Some(genv.func_span(did)));
2399 let sort = rty::Sort::Func(genv.func_sort(did));
2400 (rty::Expr::global_func(rty::SpecFuncKind::Def(did)), sort)
2401 }
2402 fhir::Res::GlobalFunc(fhir::SpecFuncKind::Uif(did)) => {
2403 self.hyperlink(span, Some(genv.func_span(did)));
2404 let sort = rty::Sort::Func(genv.func_sort(did));
2405 (rty::Expr::global_func(rty::SpecFuncKind::Uif(did)), sort)
2406 }
2407 fhir::Res::GlobalFunc(fhir::SpecFuncKind::Thy(itf)) => {
2408 let sort = THEORY_FUNCS.get(&itf).unwrap().sort.clone();
2409 (rty::Expr::global_func(rty::SpecFuncKind::Thy(itf)), rty::Sort::Func(sort))
2410 }
2411 fhir::Res::GlobalFunc(fhir::SpecFuncKind::Cast) => {
2412 let fsort = rty::PolyFuncSort::new(
2413 List::from_arr([rty::SortParamKind::Sort, rty::SortParamKind::Sort]),
2414 rty::FuncSort::new(
2415 vec![rty::Sort::Var(rty::ParamSort::from(0_usize))],
2416 rty::Sort::Var(rty::ParamSort::from(1_usize)),
2417 ),
2418 );
2419 (rty::Expr::internal_func(InternalFuncKind::Cast), rty::Sort::Func(fsort))
2420 }
2421 _ => {
2422 return Err(
2423 self.emit(errors::InvalidRes { span: func.span, res_descr: func.res.descr() })
2424 )?;
2425 }
2426 };
2427 self.0.insert_node_sort(func.fhir_id, sort);
2428 Ok(self.add_coercions(expr, func.fhir_id))
2429 }
2430
2431 fn conv_alias_reft(
2432 &mut self,
2433 env: &mut Env,
2434 fhir_id: FhirId,
2435 alias: &fhir::AliasReft,
2436 ) -> QueryResult<rty::AliasReft> {
2437 let alias_reft = match alias {
2438 fhir::AliasReft::Qualified { qself, trait_, name } => {
2439 let fhir::Res::Def(DefKind::Trait, trait_id) = trait_.res else {
2440 span_bug!(trait_.span, "expected trait")
2441 };
2442 let trait_segment = trait_.last_segment();
2443
2444 let generics = self.genv().generics_of(trait_id)?;
2445 let self_ty =
2446 self.conv_ty_to_generic_arg(env, &generics.param_at(0, self.genv())?, qself)?;
2447 let mut generic_args = vec![self_ty];
2448 self.conv_generic_args_into(env, trait_id, trait_segment, &mut generic_args)?;
2449
2450 let Some(assoc_reft) = self.genv().assoc_refinements_of(trait_id)?.find(name.name)
2451 else {
2452 return Err(self.emit(errors::InvalidAssocReft::new(
2453 trait_.span,
2454 name.name,
2455 format!("{:?}", trait_),
2456 )))?;
2457 };
2458
2459 let assoc_id = assoc_reft.def_id;
2460
2461 dbg::hyperlink!(self.genv().tcx(), name.span, assoc_reft.span);
2462
2463 rty::AliasReft { assoc_id, args: List::from_vec(generic_args) }
2464 }
2465 fhir::AliasReft::TypeRelative { qself, name } => {
2466 let qself_res =
2467 if let Some(path) = qself.as_path() { path.res } else { fhir::Res::Err };
2468 let (assoc_reft, trait_ref) =
2469 self.conv_type_relative_path(AssocReftTag, qself.span, qself_res, *name)?;
2470 rty::AliasReft { assoc_id: assoc_reft.def_id, args: trait_ref.args }
2471 }
2472 };
2473 let fsort = alias_reft.fsort(self.genv())?;
2474 self.0.insert_alias_reft_sort(fhir_id, fsort);
2475 Ok(alias_reft)
2476 }
2477
2478 pub(crate) fn conv_invariants(
2479 &mut self,
2480 adt_id: MaybeExternId,
2481 params: &[fhir::RefineParam],
2482 invariants: &[fhir::Expr],
2483 ) -> QueryResult<Vec<rty::Invariant>> {
2484 let mut env = Env::new(&[]);
2485 env.push_layer(Layer::coalesce(self.results(), adt_id.resolved_id(), params));
2486 invariants
2487 .iter()
2488 .map(|invariant| self.conv_invariant(&mut env, invariant))
2489 .collect()
2490 }
2491
2492 fn conv_invariant(
2493 &mut self,
2494 env: &mut Env,
2495 invariant: &fhir::Expr,
2496 ) -> QueryResult<rty::Invariant> {
2497 Ok(rty::Invariant::new(rty::Binder::bind_with_vars(
2498 self.conv_expr(env, invariant)?,
2499 env.top_layer().to_bound_vars(self.genv())?,
2500 )))
2501 }
2502}
2503
2504impl Env {
2505 fn new(early_params: &[fhir::RefineParam]) -> Self {
2506 let early_params = early_params
2507 .iter()
2508 .map(|param| (param.id, param.name))
2509 .collect();
2510 Self { layers: vec![], early_params }
2511 }
2512
2513 pub(crate) fn empty() -> Self {
2514 Self { layers: vec![], early_params: Default::default() }
2515 }
2516
2517 fn depth(&self) -> usize {
2518 self.layers.len()
2519 }
2520
2521 fn push_layer(&mut self, layer: Layer) {
2522 self.layers.push(layer);
2523 }
2524
2525 fn pop_layer(&mut self) -> Layer {
2526 self.layers.pop().expect("bottom of layer stack")
2527 }
2528
2529 fn top_layer(&self) -> &Layer {
2530 self.layers.last().expect("bottom of layer stack")
2531 }
2532
2533 fn lookup(&self, var: &fhir::PathExpr) -> LookupResult<'_> {
2534 let (_, id) = var.res.expect_param();
2535 for (i, layer) in self.layers.iter().rev().enumerate() {
2536 if let Some((idx, entry)) = layer.get(id) {
2537 let debruijn = DebruijnIndex::from_usize(i);
2538 let kind = LookupResultKind::Bound {
2539 debruijn,
2540 entry,
2541 index: idx as u32,
2542 kind: layer.kind,
2543 };
2544 return LookupResult { var_span: var.span, kind };
2545 }
2546 }
2547 if let Some((idx, _, name)) = self.early_params.get_full(&id) {
2548 LookupResult {
2549 var_span: var.span,
2550 kind: LookupResultKind::EarlyParam { index: idx as u32, name: *name },
2551 }
2552 } else {
2553 span_bug!(var.span, "no entry found for key: `{:?}`", id);
2554 }
2555 }
2556
2557 fn to_early_param_args(&self) -> List<rty::Expr> {
2558 self.early_params
2559 .iter()
2560 .enumerate()
2561 .map(|(idx, (_, name))| rty::Expr::early_param(idx as u32, *name))
2562 .collect()
2563 }
2564}
2565
2566impl Layer {
2567 fn new<R: WfckResultsProvider>(
2568 results: &R,
2569 params: &[fhir::RefineParam],
2570 kind: LayerKind,
2571 ) -> Self {
2572 let map = params
2573 .iter()
2574 .map(|param| {
2575 let sort = results.param_sort(param.id);
2576 let infer_mode = rty::InferMode::from_param_kind(param.kind);
2577 let entry = ParamEntry::new(sort, infer_mode, param.name);
2578 (param.id, entry)
2579 })
2580 .collect();
2581 Self { map, kind }
2582 }
2583
2584 fn list<R: WfckResultsProvider>(
2585 results: &R,
2586 bound_regions: u32,
2587 params: &[fhir::RefineParam],
2588 ) -> Self {
2589 Self::new(results, params, LayerKind::List { bound_regions })
2590 }
2591
2592 fn coalesce<R: WfckResultsProvider>(
2593 results: &R,
2594 def_id: DefId,
2595 params: &[fhir::RefineParam],
2596 ) -> Self {
2597 Self::new(results, params, LayerKind::Coalesce(def_id))
2598 }
2599
2600 fn get(&self, name: impl Borrow<fhir::ParamId>) -> Option<(usize, &ParamEntry)> {
2601 let (idx, _, entry) = self.map.get_full(name.borrow())?;
2602 Some((idx, entry))
2603 }
2604
2605 fn into_bound_vars(self, genv: GlobalEnv) -> QueryResult<List<rty::BoundVariableKind>> {
2606 match self.kind {
2607 LayerKind::List { .. } => {
2608 Ok(self
2609 .into_iter()
2610 .map(|entry| {
2611 let kind = rty::BoundReftKind::Named(entry.name);
2612 rty::BoundVariableKind::Refine(entry.sort, entry.mode, kind)
2613 })
2614 .collect())
2615 }
2616 LayerKind::Coalesce(def_id) => {
2617 let sort_def = genv.adt_sort_def_of(def_id)?;
2618 let args = sort_def.identity_args();
2619 let ctor = rty::SortCtor::Adt(sort_def);
2620 Ok(List::singleton(rty::BoundVariableKind::Refine(
2621 rty::Sort::App(ctor, args),
2622 rty::InferMode::EVar,
2623 rty::BoundReftKind::Anon,
2624 )))
2625 }
2626 }
2627 }
2628
2629 fn to_bound_vars(&self, genv: GlobalEnv) -> QueryResult<List<rty::BoundVariableKind>> {
2630 self.clone().into_bound_vars(genv)
2631 }
2632
2633 fn into_iter(self) -> impl Iterator<Item = ParamEntry> {
2634 self.map.into_values()
2635 }
2636}
2637
2638impl ParamEntry {
2639 fn new(sort: rty::Sort, mode: fhir::InferMode, name: Symbol) -> Self {
2640 ParamEntry { name, sort, mode }
2641 }
2642}
2643
2644impl LookupResult<'_> {
2645 fn to_expr(&self) -> rty::Expr {
2646 let espan = ESpan::new(self.var_span);
2647 match &self.kind {
2648 LookupResultKind::Bound { debruijn, entry: ParamEntry { name, .. }, kind, index } => {
2649 match *kind {
2650 LayerKind::List { bound_regions } => {
2651 rty::Expr::bvar(
2652 *debruijn,
2653 BoundVar::from_u32(bound_regions + *index),
2654 rty::BoundReftKind::Named(*name),
2655 )
2656 .at(espan)
2657 }
2658 LayerKind::Coalesce(def_id) => {
2659 let var =
2660 rty::Expr::bvar(*debruijn, BoundVar::ZERO, rty::BoundReftKind::Anon)
2661 .at(espan);
2662 rty::Expr::field_proj(var, rty::FieldProj::Adt { def_id, field: *index })
2663 .at(espan)
2664 }
2665 }
2666 }
2667 &LookupResultKind::EarlyParam { index, name, .. } => {
2668 rty::Expr::early_param(index, name).at(espan)
2669 }
2670 }
2671 }
2672}
2673
2674pub fn conv_func_decl(genv: GlobalEnv, func: &fhir::SpecFunc) -> QueryResult<rty::PolyFuncSort> {
2675 let wfckresults = WfckResults::new(FluxOwnerId::Flux(func.def_id));
2676 let mut cx = AfterSortck::new(genv, &wfckresults).into_conv_ctxt();
2677 let inputs_and_output = func
2678 .args
2679 .iter()
2680 .map(|p| &p.sort)
2681 .chain(iter::once(&func.sort))
2682 .map(|sort| cx.conv_sort(sort))
2683 .try_collect()?;
2684 let params = iter::repeat_n(rty::SortParamKind::Sort, func.params).collect();
2685 Ok(rty::PolyFuncSort::new(params, rty::FuncSort { inputs_and_output }))
2686}
2687
2688fn conv_un_op(op: fhir::UnOp) -> rty::UnOp {
2689 match op {
2690 fhir::UnOp::Not => rty::UnOp::Not,
2691 fhir::UnOp::Neg => rty::UnOp::Neg,
2692 }
2693}
2694
2695fn def_id_to_param_ty(genv: GlobalEnv, def_id: DefId) -> rty::ParamTy {
2696 rty::ParamTy { index: genv.def_id_to_param_index(def_id), name: ty_param_name(genv, def_id) }
2697}
2698
2699fn def_id_to_param_const(genv: GlobalEnv, def_id: DefId) -> rty::ParamConst {
2700 rty::ParamConst { index: genv.def_id_to_param_index(def_id), name: ty_param_name(genv, def_id) }
2701}
2702
2703fn ty_param_owner(genv: GlobalEnv, def_id: DefId) -> DefId {
2704 let def_kind = genv.def_kind(def_id);
2705 match def_kind {
2706 DefKind::Trait | DefKind::TraitAlias => def_id,
2707 DefKind::LifetimeParam | DefKind::TyParam | DefKind::ConstParam => {
2708 genv.tcx().parent(def_id)
2709 }
2710 _ => bug!("ty_param_owner: {:?} is a {:?} not a type parameter", def_id, def_kind),
2711 }
2712}
2713
2714fn ty_param_name(genv: GlobalEnv, def_id: DefId) -> Symbol {
2715 let def_kind = genv.tcx().def_kind(def_id);
2716 match def_kind {
2717 DefKind::Trait | DefKind::TraitAlias => kw::SelfUpper,
2718 DefKind::LifetimeParam | DefKind::TyParam | DefKind::ConstParam => {
2719 genv.tcx().item_name(def_id)
2720 }
2721 _ => bug!("ty_param_name: {:?} is a {:?} not a type parameter", def_id, def_kind),
2722 }
2723}
2724
2725trait AssocItemTag: Copy {
2728 type AssocItem<'tcx>;
2729
2730 fn descr(self) -> &'static str;
2731
2732 fn trait_defines_item_named<'tcx>(
2733 self,
2734 genv: GlobalEnv<'_, 'tcx>,
2735 trait_def_id: DefId,
2736 assoc_name: Ident,
2737 ) -> QueryResult<Option<Self::AssocItem<'tcx>>>;
2738
2739 fn transitive_bounds_that_define_assoc_item<'tcx>(
2740 self,
2741 genv: GlobalEnv<'_, 'tcx>,
2742 trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
2743 assoc_name: Ident,
2744 ) -> impl Iterator<Item = ty::PolyTraitRef<'tcx>>;
2745}
2746
2747impl AssocItemTag for AssocTag {
2748 type AssocItem<'tcx> = &'tcx AssocItem;
2749
2750 fn descr(self) -> &'static str {
2751 match self {
2752 AssocTag::Const => "constant",
2753 AssocTag::Fn => "function",
2754 AssocTag::Type => "type",
2755 }
2756 }
2757
2758 fn trait_defines_item_named<'tcx>(
2759 self,
2760 genv: GlobalEnv<'_, 'tcx>,
2761 trait_def_id: DefId,
2762 assoc_name: Ident,
2763 ) -> QueryResult<Option<Self::AssocItem<'tcx>>> {
2764 Ok(genv
2765 .tcx()
2766 .associated_items(trait_def_id)
2767 .find_by_ident_and_kind(genv.tcx(), assoc_name, self, trait_def_id))
2768 }
2769
2770 fn transitive_bounds_that_define_assoc_item<'tcx>(
2771 self,
2772 genv: GlobalEnv<'_, 'tcx>,
2773 trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
2774 assoc_name: Ident,
2775 ) -> impl Iterator<Item = ty::PolyTraitRef<'tcx>> {
2776 traits::transitive_bounds_that_define_assoc_item(genv.tcx(), trait_refs, assoc_name)
2777 }
2778}
2779
2780#[derive(Copy, Clone)]
2781struct AssocReftTag;
2782
2783impl AssocItemTag for AssocReftTag {
2784 type AssocItem<'tcx> = AssocReft;
2785
2786 fn descr(self) -> &'static str {
2787 "refinement"
2788 }
2789
2790 fn trait_defines_item_named<'tcx>(
2791 self,
2792 genv: GlobalEnv<'_, 'tcx>,
2793 trait_def_id: DefId,
2794 assoc_name: Ident,
2795 ) -> QueryResult<Option<Self::AssocItem<'tcx>>> {
2796 Ok(genv
2797 .assoc_refinements_of(trait_def_id)?
2798 .find(assoc_name.name))
2799 }
2800
2801 fn transitive_bounds_that_define_assoc_item<'tcx>(
2802 self,
2803 genv: GlobalEnv<'_, 'tcx>,
2804 trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
2805 _assoc_name: Ident,
2806 ) -> impl Iterator<Item = ty::PolyTraitRef<'tcx>> {
2807 transitive_bounds(genv.tcx(), trait_refs)
2808 }
2809}
2810
2811fn type_param_predicates<'tcx>(
2818 tcx: TyCtxt<'tcx>,
2819 param_id: DefId,
2820) -> impl Iterator<Item = ty::PolyTraitPredicate<'tcx>> {
2821 let parent = if tcx.def_kind(param_id) == DefKind::Trait {
2822 param_id
2824 } else {
2825 tcx.parent(param_id)
2826 };
2827 let param_index = tcx
2828 .generics_of(parent)
2829 .param_def_id_to_index(tcx, param_id)
2830 .unwrap();
2831 let predicates = tcx.predicates_of(parent).instantiate_identity(tcx);
2832 predicates.into_iter().filter_map(move |(clause, _)| {
2833 clause
2834 .as_trait_clause()
2835 .filter(|trait_pred| trait_pred.self_ty().skip_binder().is_param(param_index))
2836 })
2837}
2838
2839fn transitive_bounds<'tcx>(
2847 tcx: TyCtxt<'tcx>,
2848 trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
2849) -> impl Iterator<Item = ty::PolyTraitRef<'tcx>> {
2850 let mut seen = FxHashSet::default();
2851 let mut stack: Vec<_> = trait_refs.collect();
2852
2853 std::iter::from_fn(move || {
2854 while let Some(trait_ref) = stack.pop() {
2855 if !seen.insert(tcx.anonymize_bound_vars(trait_ref)) {
2856 continue;
2857 }
2858
2859 stack.extend(
2860 tcx.explicit_super_predicates_of(trait_ref.def_id())
2861 .iter_identity_copied()
2862 .map(|(clause, _)| clause.instantiate_supertrait(tcx, trait_ref))
2863 .filter_map(|clause| clause.as_trait_clause())
2864 .filter(|clause| clause.polarity() == ty::PredicatePolarity::Positive)
2865 .map(|clause| clause.map_bound(|clause| clause.trait_ref)),
2866 );
2867
2868 return Some(trait_ref);
2869 }
2870
2871 None
2872 })
2873}
2874
2875mod errors {
2876 use flux_errors::E0999;
2877 use flux_macros::Diagnostic;
2878 use flux_middle::{fhir, global_env::GlobalEnv, rty::Sort};
2879 use rustc_hir::def_id::DefId;
2880 use rustc_span::{Span, Symbol, symbol::Ident};
2881
2882 #[derive(Diagnostic)]
2883 #[diag(fhir_analysis_assoc_item_not_found, code = E0999)]
2884 #[note]
2885 pub(super) struct AssocItemNotFound {
2886 #[primary_span]
2887 #[label]
2888 pub span: Span,
2889 pub tag: &'static str,
2890 }
2891
2892 #[derive(Diagnostic)]
2893 #[diag(fhir_analysis_ambiguous_assoc_item, code = E0999)]
2894 pub(super) struct AmbiguousAssocItem {
2895 #[primary_span]
2896 pub span: Span,
2897 pub name: Ident,
2898 pub tag: &'static str,
2899 }
2900
2901 #[derive(Diagnostic)]
2902 #[diag(fhir_analysis_invalid_base_instance, code = E0999)]
2903 pub(super) struct InvalidBaseInstance {
2904 #[primary_span]
2905 span: Span,
2906 }
2907
2908 impl InvalidBaseInstance {
2909 pub(super) fn new(span: Span) -> Self {
2910 Self { span }
2911 }
2912 }
2913
2914 #[derive(Diagnostic)]
2915 #[diag(fhir_analysis_generic_argument_count_mismatch, code = E0999)]
2916 pub(super) struct GenericArgCountMismatch {
2917 #[primary_span]
2918 #[label]
2919 span: Span,
2920 found: usize,
2921 expected: usize,
2922 def_descr: &'static str,
2923 }
2924
2925 impl GenericArgCountMismatch {
2926 pub(super) fn new(
2927 genv: GlobalEnv,
2928 def_id: DefId,
2929 segment: &fhir::PathSegment,
2930 expected: usize,
2931 ) -> Self {
2932 GenericArgCountMismatch {
2933 span: segment.ident.span,
2934 found: segment.args.len(),
2935 expected,
2936 def_descr: genv.tcx().def_descr(def_id),
2937 }
2938 }
2939 }
2940
2941 #[derive(Diagnostic)]
2942 #[diag(fhir_analysis_too_few_generic_args, code = E0999)]
2943 pub(super) struct TooFewGenericArgs {
2944 #[primary_span]
2945 #[label]
2946 span: Span,
2947 found: usize,
2948 min: usize,
2949 def_descr: &'static str,
2950 }
2951
2952 impl TooFewGenericArgs {
2953 pub(super) fn new(
2954 genv: GlobalEnv,
2955 def_id: DefId,
2956 segment: &fhir::PathSegment,
2957 min: usize,
2958 ) -> Self {
2959 Self {
2960 span: segment.ident.span,
2961 found: segment.args.len(),
2962 min,
2963 def_descr: genv.tcx().def_descr(def_id),
2964 }
2965 }
2966 }
2967
2968 #[derive(Diagnostic)]
2969 #[diag(fhir_analysis_too_many_generic_args, code = E0999)]
2970 pub(super) struct TooManyGenericArgs {
2971 #[primary_span]
2972 #[label]
2973 span: Span,
2974 found: usize,
2975 max: usize,
2976 def_descr: &'static str,
2977 }
2978
2979 impl TooManyGenericArgs {
2980 pub(super) fn new(
2981 genv: GlobalEnv,
2982 def_id: DefId,
2983 segment: &fhir::PathSegment,
2984 max: usize,
2985 ) -> Self {
2986 Self {
2987 span: segment.ident.span,
2988 found: segment.args.len(),
2989 max,
2990 def_descr: genv.tcx().def_descr(def_id),
2991 }
2992 }
2993 }
2994
2995 #[derive(Diagnostic)]
2996 #[diag(fhir_analysis_refined_unrefinable_type, code = E0999)]
2997 pub(super) struct RefinedUnrefinableType {
2998 #[primary_span]
2999 span: Span,
3000 }
3001
3002 impl RefinedUnrefinableType {
3003 pub(super) fn new(span: Span) -> Self {
3004 Self { span }
3005 }
3006 }
3007
3008 #[derive(Diagnostic)]
3009 #[diag(fhir_analysis_generics_on_primitive_sort, code = E0999)]
3010 pub(super) struct GenericsOnPrimitiveSort {
3011 #[primary_span]
3012 #[label]
3013 span: Span,
3014 name: &'static str,
3015 found: usize,
3016 expected: usize,
3017 }
3018
3019 impl GenericsOnPrimitiveSort {
3020 pub(super) fn new(span: Span, name: &'static str, found: usize, expected: usize) -> Self {
3021 Self { span, found, expected, name }
3022 }
3023 }
3024
3025 #[derive(Diagnostic)]
3026 #[diag(fhir_analysis_incorrect_generics_on_sort, code = E0999)]
3027 pub(super) struct IncorrectGenericsOnSort {
3028 #[primary_span]
3029 #[label]
3030 span: Span,
3031 found: usize,
3032 expected: usize,
3033 def_descr: &'static str,
3034 }
3035
3036 impl IncorrectGenericsOnSort {
3037 pub(super) fn new(
3038 genv: GlobalEnv,
3039 def_id: DefId,
3040 span: Span,
3041 found: usize,
3042 expected: usize,
3043 ) -> Self {
3044 Self { span, found, expected, def_descr: genv.tcx().def_descr(def_id) }
3045 }
3046 }
3047
3048 #[derive(Diagnostic)]
3049 #[diag(fhir_analysis_generics_on_sort_ty_param, code = E0999)]
3050 pub(super) struct GenericsOnSortTyParam {
3051 #[primary_span]
3052 #[label]
3053 span: Span,
3054 found: usize,
3055 }
3056
3057 impl GenericsOnSortTyParam {
3058 pub(super) fn new(span: Span, found: usize) -> Self {
3059 Self { span, found }
3060 }
3061 }
3062
3063 #[derive(Diagnostic)]
3064 #[diag(fhir_analysis_generics_on_self_alias, code = E0999)]
3065 pub(super) struct GenericsOnSelf {
3066 #[primary_span]
3067 #[label]
3068 span: Span,
3069 found: usize,
3070 }
3071
3072 impl GenericsOnSelf {
3073 pub(super) fn new(span: Span, found: usize) -> Self {
3074 Self { span, found }
3075 }
3076 }
3077
3078 #[derive(Diagnostic)]
3079 #[diag(fhir_analysis_fields_on_reflected_enum_variant, code = E0999)]
3080 pub(super) struct FieldsOnReflectedEnumVariant {
3081 #[primary_span]
3082 #[label]
3083 span: Span,
3084 }
3085
3086 impl FieldsOnReflectedEnumVariant {
3087 pub(super) fn new(span: Span) -> Self {
3088 Self { span }
3089 }
3090 }
3091
3092 #[derive(Diagnostic)]
3093 #[diag(fhir_analysis_incorrect_generics_on_opaque_sort, code = E0999)]
3094 pub(super) struct IncorrectGenericsOnUserDefinedOpaqueSort {
3095 #[primary_span]
3096 #[label]
3097 span: Span,
3098 name: Symbol,
3099 expected: usize,
3100 found: usize,
3101 }
3102
3103 impl IncorrectGenericsOnUserDefinedOpaqueSort {
3104 pub(super) fn new(span: Span, name: Symbol, expected: usize, found: usize) -> Self {
3105 Self { span, name, expected, found }
3106 }
3107 }
3108
3109 #[derive(Diagnostic)]
3110 #[diag(fhir_analysis_generics_on_prim_ty, code = E0999)]
3111 pub(super) struct GenericsOnPrimTy {
3112 #[primary_span]
3113 pub span: Span,
3114 pub name: &'static str,
3115 }
3116
3117 #[derive(Diagnostic)]
3118 #[diag(fhir_analysis_generics_on_ty_param, code = E0999)]
3119 pub(super) struct GenericsOnTyParam {
3120 #[primary_span]
3121 pub span: Span,
3122 pub name: Symbol,
3123 }
3124
3125 #[derive(Diagnostic)]
3126 #[diag(fhir_analysis_generics_on_self_ty, code = E0999)]
3127 pub(super) struct GenericsOnSelfTy {
3128 #[primary_span]
3129 pub span: Span,
3130 }
3131
3132 #[derive(Diagnostic)]
3133 #[diag(fhir_analysis_generics_on_foreign_ty, code = E0999)]
3134 pub(super) struct GenericsOnForeignTy {
3135 #[primary_span]
3136 pub span: Span,
3137 }
3138
3139 #[derive(Diagnostic)]
3140 #[diag(fhir_analysis_invalid_bitvector_constant, code = E0999)]
3141 pub struct InvalidBitVectorConstant {
3142 #[primary_span]
3143 #[label]
3144 span: Span,
3145 sort: Sort,
3146 }
3147
3148 impl InvalidBitVectorConstant {
3149 pub(crate) fn new(span: Span, sort: Sort) -> Self {
3150 Self { span, sort }
3151 }
3152 }
3153
3154 #[derive(Diagnostic)]
3155 #[diag(fhir_analysis_invalid_assoc_reft, code = E0999)]
3156 pub struct InvalidAssocReft {
3157 #[primary_span]
3158 span: Span,
3159 trait_: String,
3160 name: Symbol,
3161 }
3162
3163 impl InvalidAssocReft {
3164 pub(crate) fn new(span: Span, name: Symbol, trait_: String) -> Self {
3165 Self { span, trait_, name }
3166 }
3167 }
3168
3169 #[derive(Diagnostic)]
3170 #[diag(fhir_analysis_refine_arg_mismatch, code = E0999)]
3171 pub(super) struct RefineArgMismatch {
3172 #[primary_span]
3173 #[label]
3174 pub span: Span,
3175 pub expected: usize,
3176 pub found: usize,
3177 pub kind: &'static str,
3178 }
3179
3180 #[derive(Diagnostic)]
3181 #[diag(fhir_analysis_expected_type, code = E0999)]
3182 pub(super) struct ExpectedType {
3183 #[primary_span]
3184 pub span: Span,
3185 pub def_descr: &'static str,
3186 pub name: String,
3187 }
3188
3189 #[derive(Diagnostic)]
3190 #[diag(fhir_analysis_fail_to_match_predicates, code = E0999)]
3191 pub(super) struct FailToMatchPredicates {
3192 #[primary_span]
3193 pub span: Span,
3194 }
3195
3196 #[derive(Diagnostic)]
3197 #[diag(fhir_analysis_invalid_res, code = E0999)]
3198 pub(super) struct InvalidRes {
3199 #[primary_span]
3200 pub span: Span,
3201 pub res_descr: &'static str,
3202 }
3203
3204 #[derive(Diagnostic)]
3205 #[diag(fhir_analysis_constant_annotation_needed, code = E0999)]
3206 pub(super) struct ConstantAnnotationNeeded {
3207 #[primary_span]
3208 #[label]
3209 span: Span,
3210 }
3211 impl ConstantAnnotationNeeded {
3212 pub(super) fn new(span: Span) -> Self {
3213 Self { span }
3214 }
3215 }
3216}