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