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