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