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