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