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