1use flux_common::{
4 bug,
5 iter::IterExt,
6 result::{ErrorEmitter as _, ResultExt},
7};
8use flux_errors::ErrorGuaranteed;
9use flux_middle::{
10 def_id::MaybeExternId,
11 fhir::{self, FhirId, FluxOwnerId},
12 query_bug, try_alloc_slice,
13};
14use rustc_hir::{
15 self as hir, FnHeader,
16 def_id::{DefId, LocalDefId},
17 intravisit::HirTyCtxt,
18};
19use rustc_span::Span;
20
21use super::{DesugarCtxt, RustItemCtxt};
22
23type Result<T = ()> = std::result::Result<T, ErrorGuaranteed>;
24
25impl<'genv> RustItemCtxt<'_, 'genv, '_> {
26 pub(crate) fn lift_item(&mut self) -> Result<fhir::Item<'genv>> {
27 let hir_item = self
28 .genv
29 .tcx()
30 .hir_item(hir::ItemId { owner_id: self.owner.local_id() });
31 let (generics, kind) = match hir_item.kind {
32 hir::ItemKind::Const(_, generics, ..) => (generics, fhir::ItemKind::Const(None)),
33 hir::ItemKind::Fn { sig, generics, .. } => {
34 (generics, fhir::ItemKind::Fn(self.lift_fn_sig(sig)))
35 }
36 hir::ItemKind::TyAlias(_, generics, ty) => {
37 let ty_alias = self.lift_type_alias(hir_item.span, ty);
38 let kind = fhir::ItemKind::TyAlias(self.genv.alloc(ty_alias));
39 (generics, kind)
40 }
41 hir::ItemKind::Enum(_, generics, enum_def) => {
42 (generics, fhir::ItemKind::Enum(self.lift_enum_def(enum_def)))
43 }
44 hir::ItemKind::Struct(_, generics, variant_data) => {
45 (generics, fhir::ItemKind::Struct(self.lift_struct_def(variant_data)))
46 }
47 hir::ItemKind::Union(_, generics, variant_data) => {
48 (generics, fhir::ItemKind::Struct(self.lift_struct_def(variant_data)))
49 }
50 hir::ItemKind::Trait { generics, .. } => {
51 (generics, fhir::ItemKind::Trait(fhir::Trait { assoc_refinements: &[] }))
52 }
53 hir::ItemKind::Impl(impl_) => {
54 (impl_.generics, fhir::ItemKind::Impl(fhir::Impl { assoc_refinements: &[] }))
55 }
56 hir::ItemKind::Static(..) => (hir::Generics::empty(), fhir::ItemKind::Static(None)),
57 _ => {
58 Err(query_bug!(self.owner.resolved_id(), "unsupported item")).emit(&self.genv())?
59 }
60 };
61 Ok(fhir::Item { owner_id: self.owner, generics: self.lift_generics_inner(generics), kind })
62 }
63
64 pub(crate) fn lift_trait_item(&mut self) -> fhir::TraitItem<'genv> {
65 let hir_trait_item = self
66 .genv
67 .tcx()
68 .hir_trait_item(hir::TraitItemId { owner_id: self.owner.local_id() });
69 let generics = self.lift_generics_inner(hir_trait_item.generics);
70 let kind = match hir_trait_item.kind {
71 hir::TraitItemKind::Fn(fn_sig, ..) => fhir::TraitItemKind::Fn(self.lift_fn_sig(fn_sig)),
72 hir::TraitItemKind::Const(..) => fhir::TraitItemKind::Const,
73 hir::TraitItemKind::Type(..) => fhir::TraitItemKind::Type,
74 };
75 fhir::TraitItem { owner_id: self.owner, generics, kind }
76 }
77
78 pub(crate) fn lift_impl_item(&mut self) -> fhir::ImplItem<'genv> {
79 let hir_impl_item = self
80 .genv
81 .tcx()
82 .hir_impl_item(hir::ImplItemId { owner_id: self.owner.local_id() });
83 let generics = self.lift_generics_inner(hir_impl_item.generics);
84 let kind = match hir_impl_item.kind {
85 hir::ImplItemKind::Fn(fn_sig, ..) => fhir::ImplItemKind::Fn(self.lift_fn_sig(fn_sig)),
86 hir::ImplItemKind::Const(..) => fhir::ImplItemKind::Const,
87 hir::ImplItemKind::Type(..) => fhir::ImplItemKind::Type,
88 };
89 fhir::ImplItem { owner_id: self.owner, generics, kind }
90 }
91
92 pub(crate) fn lift_generics(&mut self) -> fhir::Generics<'genv> {
93 let generics = self.genv.tcx().hir_get_generics(self.local_id()).unwrap();
94 self.lift_generics_inner(generics)
95 }
96
97 pub(crate) fn lift_generic_param(
98 &mut self,
99 param: &hir::GenericParam,
100 ) -> fhir::GenericParam<'genv> {
101 let kind = match param.kind {
102 hir::GenericParamKind::Lifetime { .. } => fhir::GenericParamKind::Lifetime,
103 hir::GenericParamKind::Type { default, .. } => {
104 fhir::GenericParamKind::Type { default: default.map(|ty| self.lift_ty(ty)) }
105 }
106 hir::GenericParamKind::Const { ty, default, .. } => {
107 let ty = self.lift_ty(ty);
108 fhir::GenericParamKind::Const { ty, has_default: default.is_some() }
109 }
110 };
111 fhir::GenericParam {
112 def_id: self.genv.maybe_extern_id(param.def_id),
113 name: param.name,
114 kind,
115 }
116 }
117
118 fn lift_generics_inner(&mut self, generics: &hir::Generics) -> fhir::Generics<'genv> {
119 let params = self.genv.alloc_slice_fill_iter(
120 generics
121 .params
122 .iter()
123 .map(|param| self.lift_generic_param(param)),
124 );
125
126 fhir::Generics { params, refinement_params: &[], predicates: None }
127 }
128
129 fn lift_generic_bound(
130 &mut self,
131 bound: &hir::GenericBound,
132 ) -> Result<fhir::GenericBound<'genv>> {
133 match bound {
134 hir::GenericBound::Trait(poly_trait_ref) => {
135 Ok(fhir::GenericBound::Trait(self.lift_poly_trait_ref(*poly_trait_ref)?))
136 }
137 hir::GenericBound::Outlives(_) => Ok(fhir::GenericBound::Outlives),
138 _ => Err(self.emit_unsupported(&format!("unsupported generic bound: `{bound:?}`"))),
139 }
140 }
141
142 fn lift_poly_trait_ref(
143 &mut self,
144 poly_trait_ref: hir::PolyTraitRef,
145 ) -> Result<fhir::PolyTraitRef<'genv>> {
146 let modifiers = match poly_trait_ref.modifiers {
147 rustc_hir::TraitBoundModifiers {
148 constness: rustc_hir::BoundConstness::Never,
149 polarity: rustc_hir::BoundPolarity::Positive,
150 } => fhir::TraitBoundModifier::None,
151 rustc_hir::TraitBoundModifiers {
152 constness: rustc_hir::BoundConstness::Never,
153 polarity: rustc_hir::BoundPolarity::Maybe(_),
154 } => fhir::TraitBoundModifier::Maybe,
155 _ => {
156 return Err(self.emit_unsupported(&format!(
157 "unsupported trait modifiers: `{:?}`",
158 poly_trait_ref.modifiers,
159 )));
160 }
161 };
162 let bound_generic_params = self.genv.alloc_slice_fill_iter(
163 poly_trait_ref
164 .bound_generic_params
165 .iter()
166 .map(|param| self.lift_generic_param(param)),
167 );
168 let trait_ref = self.lift_path(poly_trait_ref.trait_ref.path)?;
169 Ok(fhir::PolyTraitRef {
170 bound_generic_params,
171 refine_params: &[],
172 modifiers,
173 trait_ref,
174 span: poly_trait_ref.span,
175 })
176 }
177
178 pub(crate) fn lift_opaque_ty(
179 &mut self,
180 opaque_ty: &hir::OpaqueTy,
181 ) -> Result<fhir::OpaqueTy<'genv>> {
182 let bounds =
183 try_alloc_slice!(self.genv, &opaque_ty.bounds, |bound| self.lift_generic_bound(bound))?;
184
185 Ok(fhir::OpaqueTy { def_id: MaybeExternId::Local(opaque_ty.def_id), bounds })
186 }
187
188 pub(crate) fn lift_fn_header(&mut self) -> FnHeader {
189 let hir_id = self.genv.tcx().local_def_id_to_hir_id(self.local_id());
190 self.genv
191 .tcx()
192 .hir_fn_sig_by_hir_id(hir_id)
193 .expect("item does not have a `FnDecl`")
194 .header
195 }
196
197 pub(crate) fn lift_fn_decl(&mut self) -> fhir::FnDecl<'genv> {
198 let hir_id = self.genv.tcx().local_def_id_to_hir_id(self.local_id());
199 let fn_sig = self
200 .genv
201 .tcx()
202 .hir_fn_sig_by_hir_id(hir_id)
203 .expect("item does not have a `FnDecl`");
204
205 self.lift_fn_decl_inner(fn_sig.span, fn_sig.decl)
206 }
207
208 fn lift_fn_decl_inner(&mut self, span: Span, decl: &hir::FnDecl) -> fhir::FnDecl<'genv> {
209 let inputs = self
210 .genv
211 .alloc_slice_fill_iter(decl.inputs.iter().map(|ty| self.lift_ty(ty)));
212
213 let output =
214 fhir::FnOutput { params: &[], ensures: &[], ret: self.lift_fn_ret_ty(&decl.output) };
215
216 fhir::FnDecl { requires: &[], inputs, output, span, lifted: true }
217 }
218
219 fn lift_fn_ret_ty(&mut self, ret_ty: &hir::FnRetTy) -> fhir::Ty<'genv> {
220 match ret_ty {
221 hir::FnRetTy::DefaultReturn(_) => {
222 let kind = fhir::TyKind::Tuple(&[]);
223 fhir::Ty { kind, span: ret_ty.span() }
224 }
225 hir::FnRetTy::Return(ty) => self.lift_ty(ty),
226 }
227 }
228
229 fn lift_type_alias(&mut self, span: Span, ty: &hir::Ty) -> fhir::TyAlias<'genv> {
230 let ty = self.lift_ty(ty);
231 fhir::TyAlias { index: None, ty, span, lifted: true }
232 }
233
234 fn lift_struct_def(&mut self, variant_data: hir::VariantData) -> fhir::StructDef<'genv> {
235 fhir::StructDef {
236 refinement: self
237 .genv
238 .alloc(fhir::RefinementKind::Refined(fhir::RefinedBy::trivial())),
239 params: &[],
240 kind: fhir::StructKind::Transparent {
241 fields: self.genv.alloc_slice_fill_iter(
242 variant_data.fields().iter().map(|f| self.lift_field_def(f)),
243 ),
244 },
245 invariants: &[],
246 }
247 }
248
249 pub(crate) fn lift_field_def(&mut self, field_def: &hir::FieldDef) -> fhir::FieldDef<'genv> {
250 let ty = self.lift_ty(field_def.ty);
251 fhir::FieldDef { ty, lifted: true }
252 }
253
254 fn lift_enum_def(&mut self, enum_def: hir::EnumDef) -> fhir::EnumDef<'genv> {
255 fhir::EnumDef {
256 refinement: self
257 .genv
258 .alloc(fhir::RefinementKind::Refined(fhir::RefinedBy::trivial())),
259 params: &[],
260 variants: self.genv.alloc_slice_fill_iter(
261 enum_def
262 .variants
263 .iter()
264 .map(|variant| self.lift_enum_variant(variant)),
265 ),
266 invariants: &[],
267 }
268 }
269
270 pub(crate) fn lift_enum_variant(&mut self, variant: &hir::Variant) -> fhir::VariantDef<'genv> {
271 let item = self.genv.tcx().hir_expect_item(self.local_id());
272 let hir::ItemKind::Enum(_, generics, _) = &item.kind else { bug!("expected an enum") };
273
274 let fields = self.genv.alloc_slice_fill_iter(
275 variant
276 .data
277 .fields()
278 .iter()
279 .map(|field| self.lift_field_def(field)),
280 );
281
282 let ret = self.lift_variant_ret_inner(generics);
283
284 fhir::VariantDef {
285 def_id: variant.def_id,
286 params: &[],
287 fields,
288 ret,
289 span: variant.span,
290 lifted: true,
291 }
292 }
293
294 pub(crate) fn lift_variant_ret(&mut self) -> fhir::VariantRet<'genv> {
295 let item = self.genv.tcx().hir_expect_item(self.local_id());
296 let hir::ItemKind::Enum(_, generics, _) = &item.kind else { bug!("expected an enum") };
297 self.lift_variant_ret_inner(generics)
298 }
299
300 fn lift_variant_ret_inner(&mut self, generics: &hir::Generics) -> fhir::VariantRet<'genv> {
301 let kind = fhir::ExprKind::Record(&[]);
302 fhir::VariantRet {
303 enum_id: self.owner.resolved_id(),
304 idx: fhir::Expr {
305 kind,
306 fhir_id: self.next_fhir_id(),
307 span: generics.span.shrink_to_hi(),
308 },
309 }
310 }
311
312 fn lift_ty(&mut self, ty: &hir::Ty) -> fhir::Ty<'genv> {
313 let kind = match ty.kind {
314 hir::TyKind::Slice(ty) => {
315 let ty = self.lift_ty(ty);
316 let kind = fhir::BaseTyKind::Slice(self.genv.alloc(ty));
317 let bty = fhir::BaseTy { kind, fhir_id: self.next_fhir_id(), span: ty.span };
318 return fhir::Ty { kind: fhir::TyKind::BaseTy(bty), span: ty.span };
319 }
320 hir::TyKind::Array(ty, len) => {
321 let ty = self.lift_ty(ty);
322 fhir::TyKind::Array(self.genv.alloc(ty), self.lift_const_arg(len))
323 }
324 hir::TyKind::Ref(_, ty, mutbl) => {
325 let ty = self.lift_ty(ty);
326 fhir::TyKind::Ref(self.genv.alloc(ty), mutbl)
327 }
328 hir::TyKind::FnPtr(fn_ptr) => {
329 let bare_fn = self.lift_bare_fn(ty.span, fn_ptr);
330 fhir::TyKind::BareFn(self.genv.alloc(bare_fn))
331 }
332 hir::TyKind::Never => fhir::TyKind::Never,
333 hir::TyKind::Tup(tys) => {
334 let tys = self
335 .genv
336 .alloc_slice_fill_iter(tys.iter().map(|ty| self.lift_ty(ty)));
337 fhir::TyKind::Tuple(tys)
338 }
339 hir::TyKind::Path(qpath) => {
340 match self.lift_qpath(qpath) {
341 Ok(qpath) => {
342 let bty = fhir::BaseTy::from_qpath(qpath, self.next_fhir_id());
343 fhir::TyKind::BaseTy(bty)
344 }
345 Err(err) => fhir::TyKind::Err(err),
346 }
347 }
348 hir::TyKind::Ptr(ty, mutbl) => {
349 let ty = self.lift_ty(ty);
350 let kind = fhir::BaseTyKind::RawPtr(self.genv.alloc(ty), mutbl);
351 fhir::TyKind::BaseTy(fhir::BaseTy {
352 kind,
353 fhir_id: self.next_fhir_id(),
354 span: ty.span,
355 })
356 }
357 hir::TyKind::OpaqueDef(opaque_ty) => {
358 match self.lift_opaque_ty(opaque_ty) {
359 Ok(opaque_ty) => {
360 let opaque_ty = self.insert_opaque_ty(opaque_ty);
361 fhir::TyKind::OpaqueDef(opaque_ty)
362 }
363 Err(err) => fhir::TyKind::Err(err),
364 }
365 }
366 hir::TyKind::TraitObject(poly_traits, lt) => {
367 let poly_traits = try_alloc_slice!(self.genv, poly_traits, |poly_trait| {
368 if poly_trait.modifiers != hir::TraitBoundModifiers::NONE {
369 return Err(self.emit_unsupported(&format!(
370 "unsupported type: `{}`",
371 hir_ty_to_string(self.genv.tcx(), ty)
372 )));
373 }
374 self.lift_poly_trait_ref(*poly_trait)
375 });
376 match poly_traits {
377 Ok(poly_traits) => fhir::TyKind::TraitObject(poly_traits, lt.tag()),
378 Err(err) => fhir::TyKind::Err(err),
379 }
380 }
381 _ => {
382 fhir::TyKind::Err(self.emit_unsupported(&format!(
383 "unsupported type: `{}`",
384 hir_ty_to_string(self.genv.tcx(), ty)
385 )))
386 }
387 };
388 fhir::Ty { kind, span: ty.span }
389 }
390
391 fn lift_bare_fn(&mut self, span: Span, fn_ptr: &hir::FnPtrTy) -> fhir::BareFnTy<'genv> {
392 let generic_params = self.genv.alloc_slice_fill_iter(
393 fn_ptr
394 .generic_params
395 .iter()
396 .map(|param| self.lift_generic_param(param)),
397 );
398 let decl = self.lift_fn_decl_inner(span, fn_ptr.decl);
399 fhir::BareFnTy {
400 params: &[],
401 safety: fn_ptr.safety,
402 abi: fn_ptr.abi,
403 generic_params,
404 decl: self.genv.alloc(decl),
405 param_idents: self.genv.alloc_slice(fn_ptr.param_idents),
406 }
407 }
408
409 fn lift_qpath(&mut self, qpath: hir::QPath) -> Result<fhir::QPath<'genv>> {
410 match qpath {
411 hir::QPath::Resolved(qself, path) => {
412 let qself = if let Some(ty) = qself {
413 let ty = self.lift_ty(ty);
414 Some(self.genv.alloc(ty))
415 } else {
416 None
417 };
418 let path = self.lift_path(path)?;
419 Ok(fhir::QPath::Resolved(qself, path))
420 }
421 hir::QPath::TypeRelative(qself, segment) => {
422 let qself = self.lift_ty(qself);
423 let segment = self.lift_path_segment(segment)?;
424 Ok(fhir::QPath::TypeRelative(self.genv.alloc(qself), self.genv.alloc(segment)))
425 }
426 }
427 }
428
429 fn lift_path(&mut self, path: &hir::Path) -> Result<fhir::Path<'genv>> {
430 let Ok(res) = path.res.try_into() else {
431 return Err(self.emit_unsupported(&format!("unsupported res: `{:?}`", path.res)));
432 };
433 let segments =
434 try_alloc_slice!(self.genv, path.segments, |segment| self.lift_path_segment(segment))?;
435
436 Ok(fhir::Path {
437 res: self.fix_maybe_extern_id_in_res(res),
438 fhir_id: self.next_fhir_id(),
439 segments,
440 refine: &[],
441 span: path.span,
442 })
443 }
444
445 fn lift_path_segment(
446 &mut self,
447 segment: &hir::PathSegment,
448 ) -> Result<fhir::PathSegment<'genv>> {
449 let Ok(res) = segment.res.try_into() else {
450 return Err(self.emit_unsupported(&format!("unsupported res: `{:?}`", segment.res)));
451 };
452 let (args, bindings) = {
453 match segment.args {
454 Some(args) => {
455 (
456 self.lift_generic_args(args.args)?,
457 self.lift_assoc_item_constraints(args.constraints)?,
458 )
459 }
460 None => ([].as_slice(), [].as_slice()),
461 }
462 };
463
464 Ok(fhir::PathSegment { res, ident: segment.ident, args, constraints: bindings })
465 }
466
467 fn lift_generic_args(
468 &mut self,
469 args: &[hir::GenericArg<'_>],
470 ) -> Result<&'genv [fhir::GenericArg<'genv>]> {
471 try_alloc_slice!(
473 self.genv,
474 cap: args.len(),
475 args.iter().filter_map(|arg| {
476 match arg {
477 hir::GenericArg::Lifetime(_) => None,
478 hir::GenericArg::Type(ty) => {
479 let ty = self.lift_ty(ty.as_unambig_ty());
480 Some(Ok(fhir::GenericArg::Type(self.genv.alloc(ty))))
481 }
482 hir::GenericArg::Const(const_arg) => {
483 Some(Ok(fhir::GenericArg::Const(
484 self.lift_const_arg(const_arg.as_unambig_ct()),
485 )))
486 }
487 hir::GenericArg::Infer(_) => {
488 Some(Err(self.emit_unsupported("unsupported inference generic argument")))
489 }
490 }
491 })
492 )
493 }
494
495 fn lift_assoc_item_constraints(
496 &mut self,
497 constraints: &[hir::AssocItemConstraint<'_>],
498 ) -> Result<&'genv [fhir::AssocItemConstraint<'genv>]> {
499 try_alloc_slice!(self.genv, constraints, |cstr| {
500 let hir::AssocItemConstraintKind::Equality { term } = cstr.kind else {
501 return Err(self.emit_unsupported("unsupported type binding"));
502 };
503 let hir::Term::Ty(term) = term else {
504 return Err(self.emit_unsupported("unsupported type binding"));
505 };
506 let kind = fhir::AssocItemConstraintKind::Equality { term: self.lift_ty(term) };
507 Ok(fhir::AssocItemConstraint { ident: cstr.ident, kind })
508 })
509 }
510
511 fn lift_const_arg(&mut self, const_arg: &hir::ConstArg) -> fhir::ConstArg {
512 fhir::ConstArg { kind: fhir::ConstArgKind::Infer, span: const_arg.span }
513 }
514
515 #[track_caller]
516 fn emit_unsupported(&self, note: &str) -> ErrorGuaranteed {
517 let tcx = self.genv.tcx();
518 let local_id = self.owner.local_id().def_id;
519 let span = tcx.def_span(local_id);
520 let def_kind = tcx.def_descr(local_id.to_def_id());
521 self.emit(errors::UnsupportedHir { span, def_kind, note })
522 }
523
524 fn next_fhir_id(&self) -> FhirId {
525 FhirId { owner: FluxOwnerId::Rust(self.owner), local_id: self.local_id_gen.fresh() }
526 }
527
528 fn local_id(&self) -> LocalDefId {
529 self.owner.local_id().def_id
530 }
531
532 fn lift_fn_sig(&mut self, fn_sig: hir::FnSig) -> fhir::FnSig<'genv> {
533 let decl = self.lift_fn_decl_inner(fn_sig.span, fn_sig.decl);
534 fhir::FnSig { header: fn_sig.header, decl: self.genv.alloc(decl), no_panic_if: None }
535 }
536
537 pub(crate) fn lift_foreign_item(
538 &mut self,
539 foreign_item: hir::ForeignItem,
540 ) -> Result<fhir::ForeignItem<'genv>> {
541 let kind = match foreign_item.kind {
542 hir::ForeignItemKind::Fn(fnsig, _, _) => {
543 let lifted_fnsig = self.lift_fn_sig(fnsig);
544 let fnsig = self.genv.alloc(lifted_fnsig);
545 let lifted_generics = self.lift_generics();
546 let generics = self.genv.alloc(lifted_generics);
547 fhir::ForeignItemKind::Fn(*fnsig, generics)
548 }
549 rustc_hir::ForeignItemKind::Static(ty, mutbl, safety) => {
550 let lifted_ty = self.lift_ty(ty);
551 let ty = self.genv.alloc(lifted_ty);
552 let lifted_generics = fhir::Generics::empty(self.genv);
553 let generics = self.genv.alloc(lifted_generics);
554 fhir::ForeignItemKind::Static(*ty, mutbl, safety, generics)
555 }
556 _ => {
557 return Err(self.emit_unsupported("unsupported foreign item kind"));
558 }
559 };
560 Ok(fhir::ForeignItem {
561 ident: foreign_item.ident,
562 kind,
563 owner_id: MaybeExternId::Local(foreign_item.owner_id),
564 span: foreign_item.span,
565 })
566 }
567
568 fn fix_maybe_extern_id_in_res(&self, res: fhir::Res) -> fhir::Res {
570 match res {
571 fhir::Res::SelfTyParam { trait_ } => {
572 fhir::Res::SelfTyParam { trait_: self.fix_maybe_extern_id(trait_) }
573 }
574 fhir::Res::SelfTyAlias { alias_to, is_trait_impl } => {
575 fhir::Res::SelfTyAlias {
576 alias_to: self.fix_maybe_extern_id(alias_to),
577 is_trait_impl,
578 }
579 }
580 fhir::Res::Def(kind, def_id) => fhir::Res::Def(kind, self.fix_maybe_extern_id(def_id)),
581 _ => res,
582 }
583 }
584
585 #[allow(
589 clippy::disallowed_methods,
590 reason = "we are fixing the def_id to uphold the invariant on extern specs"
591 )]
592 fn fix_maybe_extern_id(&self, def_id: DefId) -> DefId {
593 if let Some(def_id) = def_id.as_local() {
594 self.genv.maybe_extern_id(def_id).resolved_id()
595 } else {
596 def_id
597 }
598 }
599}
600
601pub mod errors {
602 use flux_errors::E0999;
603 use flux_macros::Diagnostic;
604 use rustc_span::Span;
605
606 #[derive(Diagnostic)]
607 #[diag("refinement of unsupported {$def_kind}", code = E0999)]
608 #[note("{$note}")]
609 pub(super) struct UnsupportedHir<'a> {
610 #[primary_span]
611 #[label("this {$def_kind} contains unsupported features")]
612 pub span: Span,
613 pub def_kind: &'static str,
614 pub note: &'a str,
615 }
616}
617
618fn hir_ty_to_string(tcx: rustc_middle::ty::TyCtxt<'_>, ty: &hir::Ty<'_>) -> String {
619 rustc_hir_pretty::ty_to_string(&(&tcx as &dyn HirTyCtxt<'_>), ty)
620}