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