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