1mod lift;
2
3use std::{iter, ops::Range};
4
5use flux_common::{
6 bug, dbg,
7 index::IndexGen,
8 iter::IterExt,
9 result::{ErrorCollector, ErrorEmitter},
10 span_bug,
11};
12use flux_config as config;
13use flux_errors::{Errors, FluxSession};
14use flux_middle::{
15 ResolverOutput,
16 def_id::{FluxLocalDefId, MaybeExternId},
17 fhir::{self, FhirId, FluxOwnerId, Namespace, PartialRes, QPathExpr, Res},
18 global_env::GlobalEnv,
19 query_bug,
20 rty::QualifierKind,
21 try_alloc_slice,
22};
23use flux_syntax::{
24 surface::{self, ConstructorArg, NodeId, visit::Visitor as _},
25 symbols::{kw, sym},
26 walk_list,
27};
28use hir::{ItemKind, def::DefKind};
29use itertools::{Either, Itertools};
30use rustc_ast::ast;
31use rustc_data_structures::{fx::FxIndexSet, unord::UnordSet};
32use rustc_errors::{Diagnostic, ErrorGuaranteed};
33use rustc_hir::{self as hir, OwnerId};
34use rustc_span::{
35 DUMMY_SP, Span,
36 def_id::{DefId, LocalDefId},
37};
38
39type Result<T = ()> = std::result::Result<T, ErrorGuaranteed>;
40
41use crate::errors;
42
43fn collect_generics_in_params(
46 genv: GlobalEnv,
47 owner: MaybeExternId<OwnerId>,
48 resolver_output: &ResolverOutput,
49 params: &surface::RefineParams,
50) -> FxIndexSet<DefId> {
51 struct ParamCollector<'a> {
52 resolver_output: &'a ResolverOutput,
53 found: UnordSet<DefId>,
54 }
55 impl surface::visit::Visitor<'_> for ParamCollector<'_> {
56 fn visit_base_sort(&mut self, bsort: &surface::BaseSort) {
57 if let surface::BaseSort::Path(path) = bsort {
58 let res = self.resolver_output.path_res_map[&path.node_id];
59 if let fhir::Res::Def(DefKind::TyParam, def_id) = res.base_res() {
60 self.found.insert(def_id);
61 }
62 }
63 surface::visit::walk_base_sort(self, bsort);
64 }
65 }
66 let mut vis = ParamCollector { resolver_output, found: UnordSet::new() };
67 walk_list!(vis, visit_refine_param, params);
68 genv.tcx()
69 .generics_of(owner.resolved_id())
70 .own_params
71 .iter()
72 .filter_map(
73 |param| if vis.found.contains(¶m.def_id) { Some(param.def_id) } else { None },
74 )
75 .collect()
76}
77
78fn collect_holes(qself: &surface::Ty, path: &surface::Path) -> Vec<Span> {
80 struct HoleCollector {
81 holes: Vec<Span>,
82 }
83 impl surface::visit::Visitor<'_> for HoleCollector {
84 fn visit_ty(&mut self, ty: &surface::Ty) {
85 if let surface::TyKind::Hole = ty.kind {
86 self.holes.push(ty.span);
87 }
88 surface::visit::walk_ty(self, ty);
89 }
90
91 fn visit_const_arg(&mut self, const_arg: &surface::ConstArg) {
92 if let surface::ConstArgKind::Infer = const_arg.kind {
93 self.holes.push(const_arg.span);
94 }
95 surface::visit::walk_const_arg(self, const_arg);
96 }
97 }
98 let mut vis = HoleCollector { holes: vec![] };
99 vis.visit_ty(qself);
100 vis.visit_path(path);
101 vis.holes
102}
103
104pub(crate) struct RustItemCtxt<'a, 'genv, 'tcx> {
105 genv: GlobalEnv<'genv, 'tcx>,
106 local_id_gen: IndexGen<fhir::ItemLocalId>,
107 owner: MaybeExternId<OwnerId>,
108 fn_sig_scope: Option<NodeId>,
109 resolver_output: &'genv ResolverOutput,
110 opaque: Option<LocalDefId>,
113 opaque_tys: Option<&'a mut Vec<&'genv fhir::OpaqueTy<'genv>>>,
116 errors: Errors<'genv>,
117}
118
119impl<'a, 'genv, 'tcx: 'genv> RustItemCtxt<'a, 'genv, 'tcx> {
120 pub(crate) fn with<T>(
121 genv: GlobalEnv<'genv, 'tcx>,
122 owner: MaybeExternId<OwnerId>,
123 resolver_output: &'genv ResolverOutput,
124 opaque_tys: Option<&'a mut Vec<&'genv fhir::OpaqueTy<'genv>>>,
125 f: impl FnOnce(&mut Self) -> Result<T>,
126 ) -> Result<T> {
127 let mut cx = RustItemCtxt {
128 genv,
129 owner,
130 fn_sig_scope: None,
131 local_id_gen: IndexGen::new(),
132 resolver_output,
133 opaque_tys,
134 errors: Errors::new(genv.sess()),
135 opaque: collect_opaque_types(genv, owner)?,
136 };
137 let r = f(&mut cx)?;
138 cx.into_result()?;
139 Ok(r)
140 }
141
142 pub(crate) fn desugar_item(&mut self, item: &surface::Item) -> Result<fhir::Item<'genv>> {
143 match &item.kind {
144 surface::ItemKind::Fn(fn_sig) => {
145 let (generics, fn_sig) = self.desugar_fn_sig(fn_sig.as_ref())?;
146 Ok(fhir::Item { generics, kind: fhir::ItemKind::Fn(fn_sig), owner_id: self.owner })
147 }
148 surface::ItemKind::Struct(struct_def) => Ok(self.desugar_struct_def(struct_def)),
149 surface::ItemKind::Enum(enum_def) => self.desugar_enum_def(enum_def),
150 surface::ItemKind::Trait(trait_) => self.desugar_trait(trait_),
151 surface::ItemKind::Impl(impl_) => Ok(self.desugar_impl(impl_)),
152 surface::ItemKind::Const(constant_info) => Ok(self.desugar_const(constant_info)),
153 surface::ItemKind::Static(static_info) => Ok(self.desugar_static(static_info)),
154 surface::ItemKind::TyAlias(ty_alias) => Ok(self.desugar_type_alias(ty_alias)),
155 surface::ItemKind::Mod => Err(self.emit(query_bug!("modules can't be desugared"))),
156 }
157 }
158
159 pub(crate) fn desugar_trait_item(
160 &mut self,
161 item: &surface::TraitItemFn,
162 ) -> Result<fhir::TraitItem<'genv>> {
163 let (generics, fn_sig) = self.desugar_fn_sig(item.sig.as_ref())?;
164 Ok(fhir::TraitItem {
165 generics,
166 kind: fhir::TraitItemKind::Fn(fn_sig),
167 owner_id: self.owner,
168 })
169 }
170
171 pub(crate) fn desugar_impl_item(
172 &mut self,
173 item: &surface::ImplItemFn,
174 ) -> Result<fhir::ImplItem<'genv>> {
175 let (generics, fn_sig) = self.desugar_fn_sig(item.sig.as_ref())?;
176 Ok(fhir::ImplItem { generics, kind: fhir::ImplItemKind::Fn(fn_sig), owner_id: self.owner })
177 }
178
179 fn desugar_trait(&mut self, trait_: &surface::Trait) -> Result<fhir::Item<'genv>> {
180 let generics = if let Some(generics) = &trait_.generics {
181 self.desugar_generics(generics)
182 } else {
183 self.lift_generics()
184 };
185 let assoc_refinements = self.desugar_trait_assoc_refts(&trait_.assoc_refinements)?;
186 let trait_ = fhir::Trait { assoc_refinements };
187
188 if config::dump_fhir() {
189 dbg::dump_item_info(self.genv.tcx(), self.owner.local_id(), "fhir", &trait_).unwrap();
190 }
191
192 Ok(fhir::Item { generics, kind: fhir::ItemKind::Trait(trait_), owner_id: self.owner })
193 }
194
195 fn desugar_trait_assoc_refts(
196 &mut self,
197 assoc_refts: &[surface::TraitAssocReft],
198 ) -> Result<&'genv [fhir::TraitAssocReft<'genv>]> {
199 let iter = assoc_refts
200 .iter()
201 .map(|assoc_reft| {
202 let name = assoc_reft.name.name;
203 let params = self.desugar_refine_params(&assoc_reft.params);
204 let output = self.desugar_base_sort(&assoc_reft.output, None);
205 let body = assoc_reft.body.as_ref().map(|expr| self.desugar_expr(expr));
206 if body.is_none() && assoc_reft.final_ {
207 Err(self.emit(errors::FinalAssocReftWithoutBody::new(assoc_reft.span)))
208 } else {
209 Ok(fhir::TraitAssocReft {
210 name,
211 params,
212 output,
213 body,
214 span: assoc_reft.span,
215 final_: assoc_reft.final_,
216 })
217 }
218 })
219 .try_collect_vec()?
220 .into_iter();
221 Ok(self.genv().alloc_slice_fill_iter(iter))
222 }
223
224 fn desugar_impl(&mut self, impl_: &surface::Impl) -> fhir::Item<'genv> {
225 let generics = if let Some(generics) = &impl_.generics {
226 self.desugar_generics(generics)
227 } else {
228 self.lift_generics()
229 };
230 let assoc_refinements = self.desugar_impl_assoc_refts(&impl_.assoc_refinements);
231 let impl_ = fhir::Impl { assoc_refinements };
232
233 if config::dump_fhir() {
234 dbg::dump_item_info(self.genv.tcx(), self.owner.local_id(), "fhir", &impl_).unwrap();
235 }
236
237 fhir::Item { generics, kind: fhir::ItemKind::Impl(impl_), owner_id: self.owner }
238 }
239
240 fn desugar_impl_assoc_refts(
241 &mut self,
242 assoc_refts: &[surface::ImplAssocReft],
243 ) -> &'genv [fhir::ImplAssocReft<'genv>] {
244 self.genv()
245 .alloc_slice_fill_iter(assoc_refts.iter().map(|assoc_reft| {
246 let name = assoc_reft.name.name;
247 let body = self.desugar_expr(&assoc_reft.body);
248 let params = self.desugar_refine_params(&assoc_reft.params);
249 let output = self.desugar_base_sort(&assoc_reft.output, None);
250 fhir::ImplAssocReft { name, params, output, body, span: assoc_reft.span }
251 }))
252 }
253
254 fn desugar_generics(&mut self, generics: &surface::Generics) -> fhir::Generics<'genv> {
255 let params = self.genv.alloc_slice_fill_iter(
256 self.genv
257 .tcx()
258 .hir_get_generics(self.owner.local_id().def_id)
259 .unwrap()
260 .params
261 .iter()
262 .map(|hir_param| self.lift_generic_param(hir_param)),
263 );
264
265 let predicates = generics
266 .predicates
267 .as_ref()
268 .map(|preds| self.desugar_generic_predicates(preds));
269 fhir::Generics { params, refinement_params: &[], predicates }
270 }
271
272 fn desugar_opt_generics(
273 &mut self,
274 generics: Option<&surface::Generics>,
275 ) -> fhir::Generics<'genv> {
276 if let Some(generics) = generics {
277 self.desugar_generics(generics)
278 } else {
279 self.lift_generics()
280 }
281 }
282
283 fn desugar_generic_predicates(
284 &mut self,
285 predicates: &[surface::WhereBoundPredicate],
286 ) -> &'genv [fhir::WhereBoundPredicate<'genv>] {
287 self.genv
288 .alloc_slice_fill_iter(predicates.iter().map(|pred| {
289 let bounded_ty = self.desugar_ty(&pred.bounded_ty);
290 let bounds = self.desugar_generic_bounds(&pred.bounds);
291 fhir::WhereBoundPredicate { span: pred.span, bounded_ty, bounds }
292 }))
293 }
294
295 fn desugar_generic_bounds(
296 &mut self,
297 bounds: &[surface::TraitRef],
298 ) -> fhir::GenericBounds<'genv> {
299 self.genv().alloc_slice_fill_iter(
300 bounds
301 .iter()
302 .map(|bound| fhir::GenericBound::Trait(self.desugar_trait_ref(bound))),
303 )
304 }
305
306 fn desugar_trait_ref(&mut self, trait_ref: &surface::TraitRef) -> fhir::PolyTraitRef<'genv> {
307 let fhir::QPath::Resolved(None, path) = self.desugar_qpath(None, &trait_ref.path) else {
308 span_bug!(trait_ref.path.span, "desugar_alias_reft: unexpected qpath")
309 };
310 let span = path.span;
311
312 let refine_params = self
313 .genv
314 .alloc_slice_fill_iter(self.implicit_params_to_params(trait_ref.node_id));
315
316 fhir::PolyTraitRef {
317 bound_generic_params: &[],
318 refine_params,
319 modifiers: fhir::TraitBoundModifier::None,
320 trait_ref: path,
321 span,
322 }
323 }
324
325 fn desugar_refined_by(&mut self, refined_by: &surface::RefineParams) -> fhir::RefinedBy<'genv> {
326 let generic_id_to_var_idx =
327 collect_generics_in_params(self.genv, self.owner, self.resolver_output, refined_by);
328
329 let fields = refined_by
330 .iter()
331 .map(|param| {
332 (param.ident.name, self.desugar_sort(¶m.sort, Some(&generic_id_to_var_idx)))
333 })
334 .collect();
335
336 fhir::RefinedBy::new(fields, generic_id_to_var_idx)
337 }
338
339 fn desugar_struct_def(&mut self, struct_def: &surface::StructDef) -> fhir::Item<'genv> {
340 let refined_by = if let Some(refined_by) = &struct_def.refined_by {
341 self.desugar_refined_by(refined_by)
342 } else {
343 fhir::RefinedBy::trivial()
344 };
345
346 let generics = self.desugar_opt_generics(struct_def.generics.as_ref());
347
348 let invariants = self.genv().alloc_slice_fill_iter(
349 struct_def
350 .invariants
351 .iter()
352 .map(|invariant| self.desugar_expr(invariant)),
353 );
354
355 let kind = if struct_def.opaque {
356 fhir::StructKind::Opaque
357 } else {
358 let kind = &self
359 .genv
360 .tcx()
361 .hir_expect_item(self.owner.local_id().def_id)
362 .kind;
363 match kind {
364 hir::ItemKind::Struct(_, _, variant_data)
365 | hir::ItemKind::Union(_, _, variant_data) => {
366 debug_assert_eq!(struct_def.fields.len(), variant_data.fields().len());
367 let fields = self.genv.alloc_slice_fill_iter(
368 iter::zip(&struct_def.fields, variant_data.fields()).map(
369 |(ty, hir_field)| {
370 if let Some(ty) = ty {
371 fhir::FieldDef { ty: self.desugar_ty(ty), lifted: false }
372 } else {
373 self.lift_field_def(hir_field)
374 }
375 },
376 ),
377 );
378 fhir::StructKind::Transparent { fields }
379 }
380 _ => bug!("expected struct or union"),
381 }
382 };
383
384 let params = self.desugar_refine_params(struct_def.refined_by.as_deref().unwrap_or(&[]));
385 let refinement = fhir::RefinementKind::Refined(refined_by);
386 let struct_def =
387 fhir::StructDef { refinement: self.genv.alloc(refinement), params, kind, invariants };
388
389 if config::dump_fhir() {
390 dbg::dump_item_info(self.genv.tcx(), self.owner.local_id(), "fhir", struct_def)
391 .unwrap();
392 }
393
394 fhir::Item { generics, kind: fhir::ItemKind::Struct(struct_def), owner_id: self.owner }
395 }
396
397 fn desugar_enum_def(&mut self, enum_def: &surface::EnumDef) -> Result<fhir::Item<'genv>> {
398 let def_id = self.owner.local_id().def_id;
399 let ItemKind::Enum(_, _, hir_enum) = self.genv.tcx().hir_expect_item(def_id).kind else {
400 bug!("expected enum");
401 };
402 let reflected = enum_def.reflected;
403 let variants = try_alloc_slice!(
404 self.genv,
405 iter::zip(&enum_def.variants, hir_enum.variants),
406 |(variant, hir_variant)| self.desugar_enum_variant_def(reflected, variant, hir_variant)
407 )?;
408
409 let kind = if enum_def.reflected {
410 fhir::RefinementKind::Reflected
411 } else if let Some(refined_by) = &enum_def.refined_by {
412 fhir::RefinementKind::Refined(self.desugar_refined_by(refined_by))
413 } else {
414 fhir::RefinementKind::Refined(fhir::RefinedBy::trivial())
415 };
416
417 let generics = self.desugar_opt_generics(enum_def.generics.as_ref());
418
419 let invariants = self.genv().alloc_slice_fill_iter(
420 enum_def
421 .invariants
422 .iter()
423 .map(|invariant| self.desugar_expr(invariant)),
424 );
425
426 let params = self.desugar_refine_params(enum_def.refined_by.as_deref().unwrap_or(&[]));
427 let enum_def =
428 fhir::EnumDef { refinement: self.genv.alloc(kind), params, variants, invariants };
429
430 if config::dump_fhir() {
431 dbg::dump_item_info(self.genv.tcx(), self.owner.local_id(), "fhir", &enum_def).unwrap();
432 }
433
434 Ok(fhir::Item { generics, kind: fhir::ItemKind::Enum(enum_def), owner_id: self.owner })
435 }
436
437 fn desugar_enum_variant_def(
438 &mut self,
439 reflected: bool,
440 variant_def: &Option<surface::VariantDef>,
441 hir_variant: &hir::Variant,
442 ) -> Result<fhir::VariantDef<'genv>> {
443 if let Some(variant_def) = variant_def {
444 if reflected {
445 return Err(self.emit(errors::InvalidReflectedVariant::new(hir_variant.span)));
446 }
447 let fields = self.genv.alloc_slice_fill_iter(
448 variant_def
449 .fields
450 .iter()
451 .map(|ty| fhir::FieldDef { ty: self.desugar_ty(ty), lifted: false }),
452 );
453
454 let ret = if let Some(ret) = &variant_def.ret {
455 self.desugar_variant_ret(ret)?
456 } else {
457 self.lift_variant_ret()
458 };
459
460 let params = self
461 .genv
462 .alloc_slice_fill_iter(self.implicit_params_to_params(variant_def.node_id));
463
464 Ok(fhir::VariantDef {
465 def_id: hir_variant.def_id,
466 params,
467 fields,
468 ret,
469 span: variant_def.span,
470 lifted: false,
471 })
472 } else {
473 Ok(self.lift_enum_variant(hir_variant))
474 }
475 }
476
477 fn desugar_type_alias(&mut self, ty_alias: &surface::TyAlias) -> fhir::Item<'genv> {
478 let mut generics = self.desugar_generics(&ty_alias.generics);
479
480 let ty = self.desugar_ty(&ty_alias.ty);
481
482 generics.refinement_params = self.desugar_refine_params(&ty_alias.params);
483
484 let index = ty_alias
485 .index
486 .as_ref()
487 .map(|index| self.desugar_refine_param(index));
488
489 let ty_alias =
490 self.genv()
491 .alloc(fhir::TyAlias { index, ty, span: ty_alias.span, lifted: false });
492 if config::dump_fhir() {
493 dbg::dump_item_info(self.genv.tcx(), self.owner.local_id(), "fhir", ty_alias).unwrap();
494 }
495 fhir::Item { generics, kind: fhir::ItemKind::TyAlias(ty_alias), owner_id: self.owner }
496 }
497
498 fn desugar_const(&mut self, const_info: &surface::ConstantInfo) -> fhir::Item<'genv> {
499 let expr = const_info.expr.as_ref().map(|e| self.desugar_expr(e));
500 let owner_id = self.owner;
501 let generics = self.lift_generics();
502 let kind = fhir::ItemKind::Const(expr);
503 fhir::Item { owner_id, generics, kind }
504 }
505
506 fn desugar_static(&mut self, static_info: &surface::StaticInfo) -> fhir::Item<'genv> {
507 let ty = self.desugar_ty(&static_info.ty);
508 let owner_id = self.owner;
509 let generics = fhir::Generics::empty(self.genv);
510 let kind = fhir::ItemKind::Static(Some(ty));
511 fhir::Item { owner_id, generics, kind }
512 }
513
514 fn desugar_fn_sig(
515 &mut self,
516 fn_sig: Option<&surface::FnSig>,
517 ) -> Result<(fhir::Generics<'genv>, fhir::FnSig<'genv>)> {
518 let mut header = self.lift_fn_header();
519 let (generics, decl, expr) = if let Some(fn_sig) = fn_sig {
520 self.fn_sig_scope = Some(fn_sig.node_id);
521
522 let mut requires = vec![];
523
524 let mut generics = self.desugar_generics(&fn_sig.generics);
525
526 for surface_requires in &fn_sig.requires {
527 let params = self.desugar_refine_params(&surface_requires.params);
528 let pred = self.desugar_expr(&surface_requires.pred);
529 requires.push(fhir::Requires { params, pred });
530 }
531
532 let inputs = self
534 .genv()
535 .alloc_slice_fill_iter(fn_sig.inputs.iter().map(|arg| self.desugar_fn_input(arg)));
536
537 let output = self.desugar_fn_output(fn_sig.asyncness, &fn_sig.output)?;
538
539 generics.refinement_params = self.desugar_fn_sig_refine_params(fn_sig);
540
541 let decl = fhir::FnDecl {
542 requires: self.genv.alloc_slice(&requires),
543 inputs,
544 output,
545 span: fn_sig.span,
546 lifted: false,
547 };
548
549 if let surface::Async::Yes { span, .. } = fn_sig.asyncness {
551 header.asyncness = hir::IsAsync::Async(span);
552 }
553 let expr = fn_sig.no_panic.as_ref().map(|e| self.desugar_expr(e));
554 (generics, decl, expr)
555 } else {
556 (self.lift_generics(), self.lift_fn_decl(), None)
557 };
558 if config::dump_fhir() {
559 dbg::dump_item_info(self.genv.tcx(), self.owner.local_id(), "fhir", decl).unwrap();
560 }
561 Ok((generics, fhir::FnSig { header, decl: self.genv.alloc(decl), no_panic_if: expr }))
562 }
563
564 fn desugar_fn_sig_refine_params(
565 &mut self,
566 fn_sig: &surface::FnSig,
567 ) -> &'genv [fhir::RefineParam<'genv>] {
568 let genv = self.genv;
569 let mut params = self
570 .desugar_refine_params_iter(&fn_sig.params)
571 .collect_vec();
572 params.extend(self.implicit_params_to_params(fn_sig.node_id));
573
574 genv.alloc_slice(¶ms)
575 }
576
577 fn desugar_fn_output(
578 &mut self,
579 asyncness: surface::Async,
580 output: &surface::FnOutput,
581 ) -> Result<fhir::FnOutput<'genv>> {
582 let ret = self.desugar_asyncness(asyncness, &output.returns);
583
584 let ensures = try_alloc_slice!(self.genv, &output.ensures, |it| self.desugar_ensures(it))?;
585
586 let params = self
587 .genv
588 .alloc_slice_fill_iter(self.implicit_params_to_params(output.node_id));
589 Ok(fhir::FnOutput { params, ret, ensures })
590 }
591
592 fn desugar_ensures(&mut self, cstr: &surface::Ensures) -> Result<fhir::Ensures<'genv>> {
593 match cstr {
594 surface::Ensures::Type(loc, ty, node_id) => {
595 let res = self.desugar_loc(*loc, *node_id)?;
596 let path = fhir::PathExpr {
597 segments: self.genv().alloc_slice(&[*loc]),
598 res,
599 fhir_id: self.next_fhir_id(),
600 span: loc.span,
601 };
602 let ty = self.desugar_ty(ty);
603 Ok(fhir::Ensures::Type(path, self.genv().alloc(ty)))
604 }
605 surface::Ensures::Pred(e) => {
606 let pred = self.desugar_expr(e);
607 Ok(fhir::Ensures::Pred(pred))
608 }
609 }
610 }
611
612 fn desugar_fn_input(&mut self, input: &surface::FnInput) -> fhir::Ty<'genv> {
613 match input {
614 surface::FnInput::Constr(bind, path, pred, node_id) => {
615 let bty = self.desugar_path_to_bty(None, path);
616
617 let pred = self.desugar_expr(pred);
618
619 let ty = if let Some(idx) = self.implicit_param_into_refine_arg(*bind, *node_id) {
620 fhir::Ty { kind: fhir::TyKind::Indexed(bty, idx), span: path.span }
621 } else {
622 fhir::Ty { kind: fhir::TyKind::BaseTy(bty), span: path.span }
623 };
624
625 let span = path.span.to(pred.span);
626 let kind = fhir::TyKind::Constr(pred, self.genv.alloc(ty));
627 fhir::Ty { kind, span }
628 }
629 surface::FnInput::StrgRef(loc, ty, node_id) => {
630 let span = loc.span;
631 let (id, kind) = self.resolve_implicit_param(*node_id).unwrap();
632 let path = fhir::PathExpr {
633 segments: self.genv.alloc_slice(&[*loc]),
634 res: Res::Param(kind, id),
635 fhir_id: self.next_fhir_id(),
636 span: loc.span,
637 };
638 let ty = self.desugar_ty(ty);
639 let kind = fhir::TyKind::StrgRef(self.genv.alloc(path), self.genv.alloc(ty));
640 fhir::Ty { kind, span }
641 }
642 surface::FnInput::Ty(bind, ty, node_id) => {
643 if let Some(bind) = bind
644 && let surface::TyKind::Base(bty) = &ty.kind
645 {
646 let bty = self.desugar_bty(bty);
647 let kind =
648 if let Some(idx) = self.implicit_param_into_refine_arg(*bind, *node_id) {
649 fhir::TyKind::Indexed(bty, idx)
650 } else {
651 fhir::TyKind::BaseTy(bty)
652 };
653 fhir::Ty { kind, span: ty.span }
654 } else {
655 self.desugar_ty(ty)
656 }
657 }
658 }
659 }
660
661 fn desugar_asyncness(
662 &mut self,
663 asyncness: surface::Async,
664 returns: &surface::FnRetTy,
665 ) -> fhir::Ty<'genv> {
666 match asyncness {
667 surface::Async::Yes { span, .. } => {
668 let def_id = self.opaque.unwrap();
670
671 let opaque_ty = self.desugar_opaque_ty_for_async(def_id, returns);
674 let opaque_ty = self.insert_opaque_ty(opaque_ty);
675 let kind = fhir::TyKind::OpaqueDef(opaque_ty);
676 fhir::Ty { kind, span }
677 }
678 surface::Async::No => self.desugar_fn_ret_ty(returns),
679 }
680 }
681
682 fn desugar_opaque_ty_for_async(
683 &mut self,
684 def_id: LocalDefId,
685 returns: &surface::FnRetTy,
686 ) -> fhir::OpaqueTy<'genv> {
687 let output = self.desugar_fn_ret_ty(returns);
688 let trait_ref = self.make_lang_item_path(
689 rustc_attr_ir::LangItem::Future,
690 DUMMY_SP,
691 &[],
692 self.genv.alloc_slice(&[fhir::AssocItemConstraint {
693 ident: surface::Ident::with_dummy_span(sym::Output),
694 kind: fhir::AssocItemConstraintKind::Equality { term: output },
695 }]),
696 );
697 let bound = fhir::GenericBound::Trait(fhir::PolyTraitRef {
698 bound_generic_params: &[],
699 refine_params: &[],
700 modifiers: fhir::TraitBoundModifier::None,
701 trait_ref,
702 span: trait_ref.span,
703 });
704 fhir::OpaqueTy {
705 def_id: MaybeExternId::Local(def_id),
706 bounds: self.genv.alloc_slice(&[bound]),
707 }
708 }
709
710 fn make_lang_item_path(
711 &mut self,
712 lang_item: rustc_attr_ir::LangItem,
713 span: Span,
714 args: &'genv [fhir::GenericArg<'genv>],
715 constraints: &'genv [fhir::AssocItemConstraint<'genv>],
716 ) -> fhir::Path<'genv> {
717 let def_id = self.genv.tcx().require_lang_item(lang_item, span);
718 let def_kind = self.genv.def_kind(def_id);
719 let res = Res::Def(def_kind, def_id);
720 fhir::Path {
721 span,
722 fhir_id: self.next_fhir_id(),
723 res,
724 segments: self.genv.alloc_slice_fill_iter([fhir::PathSegment {
725 ident: surface::Ident::new(lang_item.name(), span),
726 res,
727 args,
728 constraints,
729 }]),
730 refine: &[],
731 }
732 }
733
734 fn desugar_fn_ret_ty(&mut self, returns: &surface::FnRetTy) -> fhir::Ty<'genv> {
735 match returns {
736 surface::FnRetTy::Ty(ty) => self.desugar_ty(ty),
737 surface::FnRetTy::Default(span) => {
738 let kind = fhir::TyKind::Tuple(&[]);
739 fhir::Ty { kind, span: *span }
740 }
741 }
742 }
743
744 fn desugar_opaque_ty_for_impl_trait(
745 &mut self,
746 def_id: LocalDefId,
747 bounds: &[surface::TraitRef],
748 ) -> fhir::OpaqueTy<'genv> {
749 let bounds = self.desugar_generic_bounds(bounds);
750 fhir::OpaqueTy { def_id: MaybeExternId::Local(def_id), bounds }
751 }
752
753 fn desugar_variant_ret(
754 &mut self,
755 ret: &surface::VariantRet,
756 ) -> Result<fhir::VariantRet<'genv>> {
757 let Some(enum_id) = self.check_variant_ret_path(&ret.path) else {
758 return Err(self.emit(errors::InvalidVariantRet::new(&ret.path)));
759 };
760 let idx = self.desugar_indices(&ret.indices);
761 Ok(fhir::VariantRet { enum_id, idx })
762 }
763
764 fn check_variant_ret_path(&mut self, path: &surface::Path) -> Option<DefId> {
765 let resolved_id = self.owner.resolved_id();
766
767 match self.resolver_output().path_res_map[&path.node_id].full_res()? {
768 fhir::Res::Def(DefKind::Enum, def_id) if def_id == resolved_id => {}
769 fhir::Res::SelfTyAlias { .. } => return Some(resolved_id),
770 _ => return None,
771 }
772
773 let generics = self.genv.tcx().generics_of(resolved_id);
774 let args = &path.last().args;
775 if generics.own_counts().types != args.len() {
776 return None;
777 }
778 let mut i = 0;
779 for param in &generics.own_params {
780 let rustc_middle::ty::GenericParamDefKind::Type { .. } = param.kind else { continue };
781 let arg = &args[i];
782 if let surface::GenericArgKind::Type(arg_ty) = &arg.kind
783 && let surface::TyKind::Base(arg_bty) = &arg_ty.kind
784 && let surface::BaseTyKind::Path(None, arg_path) = &arg_bty.kind
785 && let fhir::Res::Def(DefKind::TyParam, def_id) =
786 self.resolver_output().path_res_map[&arg_path.node_id].full_res()?
787 && def_id == param.def_id
788 {
789 } else {
790 return None;
791 }
792 i += 1;
793 }
794
795 Some(resolved_id)
796 }
797
798 fn insert_opaque_ty(
799 &mut self,
800 opaque_ty: fhir::OpaqueTy<'genv>,
801 ) -> &'genv fhir::OpaqueTy<'genv> {
802 let opaque_ty = self.genv.alloc(opaque_ty);
803 self.opaque_tys
804 .as_mut()
805 .unwrap_or_else(|| bug!("`impl Trait` not supported in this item `{:?}`", self.owner))
806 .push(opaque_ty);
807 opaque_ty
808 }
809}
810
811impl ErrorEmitter for RustItemCtxt<'_, '_, '_> {
812 fn emit<'a>(&'a self, err: impl Diagnostic<'a>) -> ErrorGuaranteed {
813 self.errors.emit(err)
814 }
815}
816
817impl ErrorCollector<ErrorGuaranteed> for RustItemCtxt<'_, '_, '_> {
818 type Result = std::result::Result<(), ErrorGuaranteed>;
819
820 fn collect(&mut self, err: ErrorGuaranteed) {
821 self.errors.collect(err);
822 }
823
824 fn into_result(self) -> Self::Result {
825 self.errors.into_result()
826 }
827}
828
829pub(crate) struct FluxItemCtxt<'genv, 'tcx> {
830 genv: GlobalEnv<'genv, 'tcx>,
831 resolver_output: &'genv ResolverOutput,
832 local_id_gen: IndexGen<fhir::ItemLocalId>,
833 owner: FluxLocalDefId,
834 allow_primop_app: bool,
835 errors: Errors<'genv>,
836}
837
838impl<'genv, 'tcx> FluxItemCtxt<'genv, 'tcx> {
839 pub(crate) fn with<T>(
840 genv: GlobalEnv<'genv, 'tcx>,
841 resolver_output: &'genv ResolverOutput,
842 owner: FluxLocalDefId,
843 f: impl FnOnce(&mut Self) -> T,
844 ) -> Result<T> {
845 let mut cx = Self {
846 genv,
847 resolver_output,
848 local_id_gen: Default::default(),
849 owner,
850 allow_primop_app: false,
851 errors: Errors::new(genv.sess()),
852 };
853 let r = f(&mut cx);
854 cx.into_result()?;
855 Ok(r)
856 }
857
858 pub(crate) fn desugar_flux_item(&mut self, item: &surface::FluxItem) -> fhir::FluxItem<'genv> {
859 match item {
860 surface::FluxItem::Qualifier(qual) => {
861 let qual = self.desugar_qualifier(qual);
862 fhir::FluxItem::Qualifier(self.genv.alloc(qual))
863 }
864 surface::FluxItem::FuncDef(func) => {
865 let func = self.desugar_spec_func(func);
866 fhir::FluxItem::Func(self.genv.alloc(func))
867 }
868 surface::FluxItem::PrimOpProp(primop_prop) => {
869 self.allow_primop_app = true;
870 let primop_prop = self.desugar_primop_prop(primop_prop);
871 self.allow_primop_app = false;
872 fhir::FluxItem::PrimOpProp(self.genv.alloc(primop_prop))
873 }
874 surface::FluxItem::Axiom(axiom) => {
875 self.allow_primop_app = true;
877 let axiom = self.desugar_axiom(axiom);
878 self.allow_primop_app = false;
879 fhir::FluxItem::Axiom(self.genv.alloc(axiom))
880 }
881 surface::FluxItem::SortDecl(sort_decl) => {
882 let sort_decl = self.desugar_sort_decl(sort_decl);
883 fhir::FluxItem::SortDecl(self.genv.alloc(sort_decl))
884 }
885 surface::FluxItem::Use(..) => bug!("unexpected use item"),
886 }
887 }
888
889 pub(crate) fn desugar_sort_decl(&mut self, sort_decl: &surface::SortDecl) -> fhir::SortDecl {
890 fhir::SortDecl {
891 def_id: self.owner,
892 params: sort_decl.sort_vars.len(),
893 span: sort_decl.name.span,
894 }
895 }
896
897 fn desugar_qualifier_kind(qualifier: &surface::Qualifier) -> QualifierKind {
898 match qualifier.kind {
899 surface::QualifierKind::Global => QualifierKind::Global,
900 surface::QualifierKind::Local => QualifierKind::Local,
901 surface::QualifierKind::Hint => QualifierKind::Hint,
902 }
903 }
904
905 fn desugar_qualifier(&mut self, qualifier: &surface::Qualifier) -> fhir::Qualifier<'genv> {
906 let kind = Self::desugar_qualifier_kind(qualifier);
907 fhir::Qualifier {
908 def_id: self.owner,
909 args: self.desugar_refine_params(&qualifier.params),
910 wildcards: self.genv().alloc_slice(&qualifier.wildcards),
911 kind,
912 expr: self.desugar_expr(&qualifier.expr),
913 }
914 }
915
916 fn desugar_primop_prop(
917 &mut self,
918 primop_prop: &surface::PrimOpProp,
919 ) -> fhir::PrimOpProp<'genv> {
920 let body = self.desugar_expr(&primop_prop.body);
921 let args = self.desugar_refine_params(&primop_prop.params);
922 fhir::PrimOpProp {
923 def_id: self.owner,
924 op: primop_prop.op,
925 args,
926 body,
927 span: primop_prop.span,
928 }
929 }
930
931 fn desugar_axiom(&mut self, axiom: &surface::Axiom) -> fhir::Axiom<'genv> {
932 fhir::Axiom {
933 def_id: self.owner,
934 args: self.desugar_refine_params(&axiom.params),
935 body: self.desugar_expr(&axiom.body),
936 span: axiom.span,
937 }
938 }
939
940 fn desugar_spec_func(&mut self, spec_func: &surface::SpecFunc) -> fhir::SpecFunc<'genv> {
941 let body = spec_func.body.as_ref().map(|body| self.desugar_expr(body));
942 let params = spec_func.sort_vars.len();
943 let sort = self.desugar_sort(&spec_func.output, None);
944 let args = self.desugar_refine_params(&spec_func.params);
945 let ident_span = spec_func.name.span;
946 fhir::SpecFunc {
947 def_id: self.owner,
948 params,
949 args,
950 sort,
951 body,
952 hide: spec_func.hide,
953 ident_span,
954 }
955 }
956}
957
958impl ErrorEmitter for FluxItemCtxt<'_, '_> {
959 fn emit<'a>(&'a self, err: impl Diagnostic<'a>) -> ErrorGuaranteed {
960 self.errors.emit(err)
961 }
962}
963
964impl ErrorCollector<ErrorGuaranteed> for FluxItemCtxt<'_, '_> {
965 type Result = std::result::Result<(), ErrorGuaranteed>;
966
967 fn collect(&mut self, err: ErrorGuaranteed) {
968 self.errors.collect(err);
969 }
970
971 fn into_result(self) -> Self::Result {
972 self.errors.into_result()
973 }
974}
975
976trait DesugarCtxt<'genv, 'tcx: 'genv>: ErrorEmitter + ErrorCollector<ErrorGuaranteed> {
977 fn genv(&self) -> GlobalEnv<'genv, 'tcx>;
978 fn resolver_output(&self) -> &'genv ResolverOutput;
979 fn next_fhir_id(&self) -> FhirId;
980 fn desugar_impl_trait(&mut self, bounds: &[surface::TraitRef]) -> fhir::TyKind<'genv>;
981
982 fn allow_primop_app(&self) -> bool {
983 false
984 }
985
986 fn resolve_implicit_param(&self, node_id: NodeId) -> Option<(fhir::ParamId, fhir::ParamKind)> {
987 self.resolver_output().param_res_map.get(&node_id).copied()
988 }
989
990 fn check_no_holes(&self, qself: &surface::Ty, path: &surface::Path) -> Result {
993 collect_holes(qself, path)
994 .into_iter()
995 .try_for_each_exhaust(|span| Err(self.emit(errors::UnsupportedHole::new(span))))
996 }
997
998 fn desugar_epath(&self, path: &surface::ExprPath) -> fhir::QPathExpr<'genv> {
999 let partial_res = self
1000 .opt_resolve_path(path.node_id)
1001 .unwrap_or_else(|| span_bug!(path.span, "unresolved expr path"));
1002
1003 let unresolved_segments = partial_res.unresolved_segments();
1004
1005 if unresolved_segments == 0 {
1006 let path = fhir::PathExpr {
1007 segments: self
1008 .genv()
1009 .alloc_slice_fill_iter(path.segments.iter().map(|s| s.ident)),
1010 res: partial_res.base_res(),
1011 fhir_id: self.next_fhir_id(),
1012 span: path.span,
1013 };
1014 return fhir::QPathExpr::Resolved(path, None);
1015 }
1016
1017 let proj_start = path.segments.len() - unresolved_segments;
1018 let ty_path = fhir::Path {
1019 res: partial_res.base_res(),
1020 fhir_id: self.next_fhir_id(),
1021 segments: self.genv().alloc_slice_fill_iter(
1022 path.segments[..proj_start]
1023 .iter()
1024 .map(|segment| self.desugar_epath_segment(segment)),
1025 ),
1026 refine: &[],
1027 span: path.span,
1028 };
1029
1030 let mut ty = self
1031 .genv()
1032 .alloc(self.ty_path(fhir::QPath::Resolved(None, ty_path)));
1033
1034 for (i, segment) in path.segments.iter().enumerate().skip(proj_start) {
1035 if i == path.segments.len() - 1 {
1036 return fhir::QPathExpr::TypeRelative(ty, segment.ident);
1037 }
1038
1039 let hir_segment = self.desugar_epath_segment(segment);
1040 let qpath = fhir::QPath::TypeRelative(ty, self.genv().alloc(hir_segment));
1041 ty = self.genv().alloc(self.ty_path(qpath));
1042 }
1043
1044 span_bug!(
1045 path.span,
1046 "desugar_epath: no final extension segment in {}..{}",
1047 proj_start,
1048 path.segments.len()
1049 );
1050 }
1051
1052 #[track_caller]
1053 fn desugar_loc(&self, ident: surface::Ident, node_id: NodeId) -> Result<Res> {
1054 let partial_res = self.resolve_path(node_id);
1055 if let Some(res @ Res::Param(fhir::ParamKind::Loc, _)) = partial_res.full_res() {
1056 Ok(res)
1057 } else {
1058 let span = ident.span;
1059 Err(self.emit(errors::InvalidLoc { span }))
1060 }
1061 }
1062
1063 fn opt_resolve_path(&self, node_id: NodeId) -> Option<PartialRes> {
1064 Some(
1065 self.resolver_output()
1066 .path_res_map
1067 .get(&node_id)?
1068 .map_param_id(|param_id| self.resolve_param(param_id).0),
1069 )
1070 }
1071
1072 fn resolve_path(&self, node_id: NodeId) -> PartialRes {
1073 self.opt_resolve_path(node_id).unwrap()
1074 }
1075
1076 #[track_caller]
1077 fn resolve_param(&self, node_id: NodeId) -> (fhir::ParamId, fhir::ParamKind) {
1078 self.resolver_output().param_res_map[&node_id]
1079 }
1080
1081 fn resolve_implicit_params(
1082 &self,
1083 scope: NodeId,
1084 ) -> impl ExactSizeIterator<Item = (surface::Ident, fhir::ParamId, fhir::ParamKind)> {
1085 self.resolver_output()
1086 .implicit_params
1087 .get(&scope)
1088 .map_or(&[][..], |it| it)
1089 .iter()
1090 .map(|(ident, param_id)| {
1091 let (param_id, kind) = self.resolve_param(*param_id);
1092 (*ident, param_id, kind)
1093 })
1094 }
1095
1096 fn implicit_params_to_params(
1097 &self,
1098 scope: NodeId,
1099 ) -> impl ExactSizeIterator<Item = fhir::RefineParam<'genv>> {
1100 self.resolve_implicit_params(scope)
1101 .map(|(ident, id, kind)| {
1102 let sort = if kind.is_loc() { fhir::Sort::Loc } else { fhir::Sort::Infer };
1103 fhir::RefineParam {
1104 id,
1105 name: ident.name,
1106 span: ident.span,
1107 kind,
1108 sort,
1109 fhir_id: self.next_fhir_id(),
1110 }
1111 })
1112 }
1113
1114 fn desugar_refine_params(
1115 &mut self,
1116 params: &[surface::RefineParam],
1117 ) -> &'genv [fhir::RefineParam<'genv>] {
1118 self.genv()
1119 .alloc_slice_fill_iter(self.desugar_refine_params_iter(params))
1120 }
1121
1122 fn desugar_refine_params_iter(
1123 &mut self,
1124 params: &[surface::RefineParam],
1125 ) -> impl ExactSizeIterator<Item = fhir::RefineParam<'genv>> {
1126 params.iter().map(|param| self.desugar_refine_param(param))
1127 }
1128
1129 fn desugar_refine_param(&mut self, param: &surface::RefineParam) -> fhir::RefineParam<'genv> {
1130 let (id, kind) = self.resolve_param(param.node_id);
1131 fhir::RefineParam {
1132 id,
1133 name: param.ident.name,
1134 span: param.ident.span,
1135 kind,
1136 sort: self.desugar_sort(¶m.sort, None),
1137 fhir_id: self.next_fhir_id(),
1138 }
1139 }
1140
1141 fn desugar_sort(
1142 &mut self,
1143 sort: &surface::Sort,
1144 generic_id_to_var_idx: Option<&FxIndexSet<DefId>>,
1145 ) -> fhir::Sort<'genv> {
1146 match sort {
1147 surface::Sort::Base(bsort) => self.desugar_base_sort(bsort, generic_id_to_var_idx),
1148 surface::Sort::Func { inputs, output } => {
1149 let inputs_and_output = self.genv().alloc_slice_with_capacity(
1150 inputs.len() + 1,
1151 inputs
1152 .iter()
1153 .chain(iter::once(output))
1154 .map(|sort| self.desugar_base_sort(sort, generic_id_to_var_idx)),
1155 );
1156 fhir::Sort::Func(fhir::PolyFuncSort::new(0, inputs_and_output))
1157 }
1158 surface::Sort::Infer => fhir::Sort::Infer,
1159 }
1160 }
1161
1162 fn desugar_base_sort(
1163 &mut self,
1164 sort: &surface::BaseSort,
1165 generic_id_to_var_idx: Option<&FxIndexSet<DefId>>,
1166 ) -> fhir::Sort<'genv> {
1167 let genv = self.genv();
1168 match sort {
1169 surface::BaseSort::BitVec(width) => fhir::Sort::BitVec(*width),
1170 surface::BaseSort::Path(surface::SortPath { segments, args, node_id }) => {
1171 let res = self.resolve_path(*node_id);
1172
1173 let res = if let fhir::Res::Def(DefKind::TyParam, def_id) = res.base_res()
1175 && let Some(generic_id_to_var_idx) = generic_id_to_var_idx
1176 {
1177 let idx = generic_id_to_var_idx.get_index_of(&def_id).unwrap();
1178 fhir::PartialRes::new(fhir::Res::SortParam(idx))
1179 } else {
1180 res
1181 };
1182
1183 let args = genv.alloc_slice_fill_iter(
1184 args.iter()
1185 .map(|s| self.desugar_base_sort(s, generic_id_to_var_idx)),
1186 );
1187
1188 let path = fhir::SortPath { res, segments: genv.alloc_slice(segments), args };
1189 fhir::Sort::Path(path)
1190 }
1191 surface::BaseSort::SortOf(qself, path) => {
1192 match self.check_no_holes(qself, path) {
1193 Ok(()) => fhir::Sort::SortOf(self.desugar_path_to_bty(Some(qself), path)),
1194 Err(err) => fhir::Sort::Err(err),
1195 }
1196 }
1197 surface::BaseSort::Tuple(sorts) => {
1198 let sorts = genv.alloc_slice_fill_iter(
1199 sorts
1200 .iter()
1201 .map(|s| self.desugar_base_sort(s, generic_id_to_var_idx)),
1202 );
1203 fhir::Sort::Tuple(sorts)
1204 }
1205 }
1206 }
1207
1208 fn desugar_generic_args(
1209 &mut self,
1210 args: &[surface::GenericArg],
1211 ) -> (&'genv [fhir::GenericArg<'genv>], &'genv [fhir::AssocItemConstraint<'genv>]) {
1212 let mut fhir_args = vec![];
1213 let mut constraints = vec![];
1214 for arg in args {
1215 match &arg.kind {
1216 surface::GenericArgKind::Type(ty) => {
1217 if matches!(ty.kind, surface::TyKind::Hole) {
1218 fhir_args.push(fhir::GenericArg::Infer);
1219 continue;
1220 }
1221 if let Some(path) = ty.is_potential_const_arg()
1224 && let Some(res) = self.resolve_path(path.node_id).full_res()
1225 && res.matches_ns(Namespace::ValueNS)
1226 {
1227 fhir_args.push(self.desugar_const_path_to_const_arg(path, res));
1228 continue;
1229 }
1230 let ty = self.desugar_ty(ty);
1231 fhir_args.push(fhir::GenericArg::Type(self.genv().alloc(ty)));
1232 }
1233 surface::GenericArgKind::Constraint(ident, ty) => {
1234 constraints.push(fhir::AssocItemConstraint {
1235 ident: *ident,
1236 kind: fhir::AssocItemConstraintKind::Equality { term: self.desugar_ty(ty) },
1237 });
1238 }
1239 }
1240 }
1241 (self.genv().alloc_slice(&fhir_args), self.genv().alloc_slice(&constraints))
1242 }
1243
1244 fn desugar_const_path_to_const_arg(
1245 &mut self,
1246 path: &surface::Path,
1247 res: fhir::Res,
1248 ) -> fhir::GenericArg<'genv> {
1249 let kind = self.desugar_const_path_to_const_arg_kind(path, res);
1250 fhir::GenericArg::Const(fhir::ConstArg { kind, span: path.span })
1251 }
1252
1253 fn desugar_const_path_to_const_arg_kind(
1254 &mut self,
1255 path: &surface::Path,
1256 res: fhir::Res,
1257 ) -> fhir::ConstArgKind {
1258 if let Res::Def(DefKind::ConstParam, def_id) = res {
1259 fhir::ConstArgKind::Param(def_id)
1260 } else {
1261 self.emit(errors::UnsupportedConstGenericArg::new(path.span, res.descr()));
1262 fhir::ConstArgKind::Infer
1263 }
1264 }
1265
1266 fn desugar_ty(&mut self, ty: &surface::Ty) -> fhir::Ty<'genv> {
1271 let node_id = ty.node_id;
1272 let span = ty.span;
1273 let kind = match &ty.kind {
1274 surface::TyKind::Base(bty) => {
1275 let bty = self.desugar_bty(bty);
1276 fhir::TyKind::BaseTy(bty)
1277 }
1278 surface::TyKind::Indexed { bty, indices } => {
1279 let bty = self.desugar_bty(bty);
1280 let idx = self.desugar_indices(indices);
1281 fhir::TyKind::Indexed(bty, idx)
1282 }
1283 surface::TyKind::Exists { bind, bty, pred } => {
1284 let ty_span = ty.span;
1285 let bty_span = bty.span;
1286
1287 let bty = self.desugar_bty(bty);
1288 let pred = self.desugar_expr(pred);
1289
1290 let (id, kind) = self.resolve_param(node_id);
1291 let param = fhir::RefineParam {
1292 id,
1293 name: bind.name,
1294 span: bind.span,
1295 sort: fhir::Sort::Infer,
1296 kind,
1297 fhir_id: self.next_fhir_id(),
1298 };
1299 let path = fhir::PathExpr {
1300 segments: self.genv().alloc_slice(&[*bind]),
1301 res: Res::Param(kind, id),
1302 fhir_id: self.next_fhir_id(),
1303 span: bind.span,
1304 };
1305 let idx = fhir::Expr {
1306 kind: fhir::ExprKind::Var(QPathExpr::Resolved(path, None)),
1307 span: bind.span,
1308 fhir_id: self.next_fhir_id(),
1309 };
1310 let indexed = fhir::Ty { kind: fhir::TyKind::Indexed(bty, idx), span: bty_span };
1311 let constr = fhir::Ty {
1312 kind: fhir::TyKind::Constr(pred, self.genv().alloc(indexed)),
1313 span: ty_span,
1314 };
1315 fhir::TyKind::Exists(self.genv().alloc_slice(&[param]), self.genv().alloc(constr))
1316 }
1317 surface::TyKind::GeneralExists { params, ty, pred } => {
1318 let mut ty = self.desugar_ty(ty);
1319 if let Some(pred) = pred {
1320 let pred = self.desugar_expr(pred);
1321 ty = fhir::Ty { kind: fhir::TyKind::Constr(pred, self.genv().alloc(ty)), span };
1322 }
1323 let params = self.desugar_refine_params(params);
1324
1325 fhir::TyKind::Exists(params, self.genv().alloc(ty))
1326 }
1327 surface::TyKind::Constr(pred, ty) => {
1328 let pred = self.desugar_expr(pred);
1329 let ty = self.desugar_ty(ty);
1330 fhir::TyKind::Constr(pred, self.genv().alloc(ty))
1331 }
1332 surface::TyKind::Ref(mutbl, ty) => {
1333 let ty = self.desugar_ty(ty);
1334 fhir::TyKind::Ref(self.genv().alloc(ty), *mutbl)
1335 }
1336
1337 surface::TyKind::Tuple(tys) => {
1338 let tys = self
1339 .genv()
1340 .alloc_slice_fill_iter(tys.iter().map(|ty| self.desugar_ty(ty)));
1341 fhir::TyKind::Tuple(tys)
1342 }
1343 surface::TyKind::Array(ty, len) => {
1344 let ty = self.desugar_ty(ty);
1345 let len = self.desugar_const_arg(len);
1346 fhir::TyKind::Array(self.genv().alloc(ty), len)
1347 }
1348 surface::TyKind::BareFn(bare_fn) => {
1349 match self.desugar_bare_fn(bare_fn) {
1350 Ok(bare_fn) => fhir::TyKind::BareFn(self.genv().alloc(bare_fn)),
1351 Err(err) => fhir::TyKind::Err(err),
1352 }
1353 }
1354 surface::TyKind::ImplTrait(_, bounds) => self.desugar_impl_trait(bounds),
1355 surface::TyKind::Hole => fhir::TyKind::Infer,
1356 };
1357 fhir::Ty { kind, span }
1358 }
1359
1360 fn desugar_bare_fn(&mut self, bare_fn: &surface::BareFnTy) -> Result<fhir::BareFnTy<'genv>> {
1361 let inputs = self
1362 .genv()
1363 .alloc_slice_fill_iter(bare_fn.inputs.iter().map(|ty| self.desugar_ty(ty)));
1364 let ret = match &bare_fn.output {
1365 surface::FnRetTy::Ty(ty) => self.desugar_ty(ty),
1366 surface::FnRetTy::Default(span) => {
1367 fhir::Ty { kind: fhir::TyKind::Tuple(&[]), span: *span }
1368 }
1369 };
1370 let output = fhir::FnOutput { params: &[], ret, ensures: &[] };
1371 let decl =
1372 fhir::FnDecl { requires: &[], inputs, output, span: bare_fn.span, lifted: false };
1373 let safety = match bare_fn.safety {
1374 surface::Safety::Safe => hir::Safety::Safe,
1375 surface::Safety::Unsafe => hir::Safety::Unsafe,
1376 };
1377 let abi = match bare_fn.abi {
1378 None => rustc_abi::ExternAbi::Rust,
1379 Some(abi) => {
1380 abi.name
1381 .as_str()
1382 .parse::<rustc_abi::ExternAbi>()
1383 .map_err(|_| self.emit(errors::InvalidAbi::new(abi)))?
1384 }
1385 };
1386 let params = self
1387 .genv()
1388 .alloc_slice_fill_iter(self.implicit_params_to_params(bare_fn.node_id));
1389 Ok(fhir::BareFnTy {
1390 params,
1391 safety,
1392 abi,
1393 generic_params: &[],
1394 decl: self.genv().alloc(decl),
1395 param_idents: self
1396 .genv()
1397 .alloc_slice_fill_iter(bare_fn.inputs.iter().map(|_| None)),
1398 })
1399 }
1400
1401 fn desugar_const_arg(&mut self, const_arg: &surface::ConstArg) -> fhir::ConstArg {
1402 let kind = match &const_arg.kind {
1403 surface::ConstArgKind::Lit(val) => fhir::ConstArgKind::Lit(*val),
1404 surface::ConstArgKind::Path(path) => {
1405 let res = self
1406 .resolve_path(path.node_id)
1407 .full_res()
1408 .unwrap_or(Res::Err);
1409 self.desugar_const_path_to_const_arg_kind(path, res)
1410 }
1411 surface::ConstArgKind::Infer => fhir::ConstArgKind::Infer,
1412 };
1413 fhir::ConstArg { kind, span: const_arg.span }
1414 }
1415
1416 fn desugar_bty(&mut self, bty: &surface::BaseTy) -> fhir::BaseTy<'genv> {
1417 match &bty.kind {
1418 surface::BaseTyKind::Path(qself, path) => {
1419 let qpath = self.desugar_qpath(qself.as_deref(), path);
1420 fhir::BaseTy::from_qpath(qpath, self.next_fhir_id())
1421 }
1422 surface::BaseTyKind::Slice(ty) => {
1423 let ty = self.desugar_ty(ty);
1424 let kind = fhir::BaseTyKind::Slice(self.genv().alloc(ty));
1425 fhir::BaseTy { kind, fhir_id: self.next_fhir_id(), span: bty.span }
1426 }
1427 surface::BaseTyKind::Ptr(mutbl, ty) => {
1428 let ty = self.desugar_ty(ty);
1429 let kind = fhir::BaseTyKind::RawPtr(self.genv().alloc(ty), *mutbl);
1430 fhir::BaseTy { kind, fhir_id: self.next_fhir_id(), span: bty.span }
1431 }
1432 }
1433 }
1434
1435 fn desugar_path_to_bty(
1436 &mut self,
1437 qself: Option<&surface::Ty>,
1438 path: &surface::Path,
1439 ) -> fhir::BaseTy<'genv> {
1440 let qpath = self.desugar_qpath(qself, path);
1441 fhir::BaseTy::from_qpath(qpath, self.next_fhir_id())
1442 }
1443
1444 fn desugar_qpath(
1445 &mut self,
1446 qself: Option<&surface::Ty>,
1447 path: &surface::Path,
1448 ) -> fhir::QPath<'genv> {
1449 let qself = if let Some(ty) = qself {
1450 let ty = self.desugar_ty(ty);
1451 Some(self.genv().alloc(ty))
1452 } else {
1453 None
1454 };
1455 let partial_res = self.resolve_path(path.node_id);
1456
1457 let unresolved_segments = partial_res.unresolved_segments();
1458
1459 let proj_start = path.segments.len() - unresolved_segments;
1460 let fhir_path = fhir::Path {
1461 res: partial_res.base_res(),
1462 fhir_id: self.next_fhir_id(),
1463 segments: self.genv().alloc_slice_fill_iter(
1464 path.segments[..proj_start]
1465 .iter()
1466 .map(|segment| self.desugar_path_segment(segment)),
1467 ),
1468 refine: self
1469 .genv()
1470 .alloc_slice_fill_iter(path.refine.iter().map(|arg| self.desugar_refine_arg(arg))),
1471 span: path.span,
1472 };
1473
1474 if unresolved_segments == 0 {
1477 return fhir::QPath::Resolved(qself, fhir_path);
1478 }
1479
1480 let mut ty = if fhir_path.segments.is_empty() {
1482 qself.expect("missing QSelf for <T>::...")
1485 } else {
1486 self.genv()
1490 .alloc(self.ty_path(fhir::QPath::Resolved(qself, fhir_path)))
1491 };
1492
1493 for (i, segment) in path.segments.iter().enumerate().skip(proj_start) {
1494 let hir_segment = self.desugar_path_segment(segment);
1495 let qpath = fhir::QPath::TypeRelative(ty, self.genv().alloc(hir_segment));
1496
1497 if i == path.segments.len() - 1 {
1498 return qpath;
1499 }
1500
1501 ty = self.genv().alloc(self.ty_path(qpath));
1502 }
1503
1504 span_bug!(
1505 path.span,
1506 "desugar_qpath: no final extension segment in {}..{}",
1507 proj_start,
1508 path.segments.len()
1509 );
1510 }
1511
1512 fn desugar_path_segment(&mut self, segment: &surface::PathSegment) -> fhir::PathSegment<'genv> {
1513 let res = self
1514 .opt_resolve_path(segment.node_id)
1515 .map_or(Res::Err, |r| r.expect_full_res());
1516 let (args, constraints) = self.desugar_generic_args(&segment.args);
1517 fhir::PathSegment { ident: segment.ident, res, args, constraints }
1518 }
1519
1520 fn desugar_epath_segment(
1521 &self,
1522 segment: &surface::ExprPathSegment,
1523 ) -> fhir::PathSegment<'genv> {
1524 let res = self
1525 .opt_resolve_path(segment.node_id)
1526 .map_or(Res::Err, |r| r.expect_full_res());
1527 fhir::PathSegment { ident: segment.ident, res, args: &[], constraints: &[] }
1528 }
1529
1530 fn ty_path(&self, qpath: fhir::QPath<'genv>) -> fhir::Ty<'genv> {
1531 fhir::Ty {
1532 span: qpath.span(),
1533 kind: fhir::TyKind::BaseTy(fhir::BaseTy::from_qpath(qpath, self.next_fhir_id())),
1534 }
1535 }
1536
1537 fn desugar_indices(&mut self, idxs: &surface::Indices) -> fhir::Expr<'genv> {
1538 if let [arg] = &idxs.indices[..] {
1539 self.desugar_refine_arg(arg)
1540 } else {
1541 let flds = self
1542 .genv()
1543 .alloc_slice_fill_iter(idxs.indices.iter().map(|arg| self.desugar_refine_arg(arg)));
1544 fhir::Expr {
1545 kind: fhir::ExprKind::Record(flds),
1546 fhir_id: self.next_fhir_id(),
1547 span: idxs.span,
1548 }
1549 }
1550 }
1551
1552 fn desugar_refine_arg(&mut self, arg: &surface::RefineArg) -> fhir::Expr<'genv> {
1553 match arg {
1554 surface::RefineArg::Bind(ident, .., node_id) => {
1555 self.implicit_param_into_refine_arg(*ident, *node_id)
1556 .unwrap()
1557 }
1558 surface::RefineArg::Expr(expr) => self.desugar_expr(expr),
1559 surface::RefineArg::Abs(params, body, span, _) => {
1560 let body = self.genv().alloc(self.desugar_expr(body));
1561 let params = self.desugar_refine_params(params);
1562 fhir::Expr {
1563 kind: fhir::ExprKind::Abs(params, body),
1564 fhir_id: self.next_fhir_id(),
1565 span: *span,
1566 }
1567 }
1568 }
1569 }
1570
1571 fn implicit_param_into_refine_arg(
1572 &self,
1573 ident: surface::Ident,
1574 node_id: NodeId,
1575 ) -> Option<fhir::Expr<'genv>> {
1576 let (id, kind) = self.resolve_implicit_param(node_id)?;
1577 let path = fhir::PathExpr {
1578 segments: self.genv().alloc_slice(&[ident]),
1579 res: Res::Param(kind, id),
1580 fhir_id: self.next_fhir_id(),
1581 span: ident.span,
1582 };
1583 Some(fhir::Expr {
1584 kind: fhir::ExprKind::Var(QPathExpr::Resolved(path, Some(kind))),
1585 span: ident.span,
1586 fhir_id: self.next_fhir_id(),
1587 })
1588 }
1589
1590 fn desugar_quant_dom(&mut self, dom: &Option<Range<usize>>) -> fhir::QuantDom {
1591 match dom {
1592 Some(rng) => fhir::QuantDom::Bounded { start: rng.start, end: rng.end },
1593 None => fhir::QuantDom::Unbounded,
1594 }
1595 }
1596
1597 fn desugar_expr(&mut self, expr: &surface::Expr) -> fhir::Expr<'genv> {
1598 let kind = match &expr.kind {
1599 surface::ExprKind::Path(path) => fhir::ExprKind::Var(self.desugar_epath(path)),
1600 surface::ExprKind::Literal(lit) => self.desugar_lit(expr.span, *lit),
1601 surface::ExprKind::BinaryOp(op, deref!([e1, e2])) => {
1602 let e1 = self.desugar_expr(e1);
1603 let e2 = self.desugar_expr(e2);
1604 fhir::ExprKind::BinaryOp(*op, self.genv().alloc(e1), self.genv().alloc(e2))
1605 }
1606 surface::ExprKind::UnaryOp(op, deref!(e)) => {
1607 fhir::ExprKind::UnaryOp(*op, self.genv().alloc(self.desugar_expr(e)))
1608 }
1609 surface::ExprKind::Dot(base, fld) => {
1610 let base = self.desugar_expr(base);
1611 fhir::ExprKind::Dot(self.genv().alloc(base), *fld)
1612 }
1613 surface::ExprKind::Call(callee, args) => self.desugar_call(callee, args),
1614 surface::ExprKind::AssocReft(..) | surface::ExprKind::PrimUIF(..) => {
1615 fhir::ExprKind::Err(self.emit(errors::UnsupportedPosition::new(expr.span)))
1616 }
1617 surface::ExprKind::IfThenElse(deref!([p, e1, e2])) => {
1618 let p = self.desugar_expr(p);
1619 let e1 = self.desugar_expr(e1);
1620 let e2 = self.desugar_expr(e2);
1621 fhir::ExprKind::IfThenElse(
1622 self.genv().alloc(p),
1623 self.genv().alloc(e1),
1624 self.genv().alloc(e2),
1625 )
1626 }
1627 surface::ExprKind::Constructor(path, args) => {
1628 self.desugar_constructor(path.as_ref(), args)
1629 }
1630 surface::ExprKind::Quant(kind, param, dom, body) => {
1631 let kind = match kind {
1632 surface::QuantKind::Exists => fhir::QuantKind::Exists,
1633 surface::QuantKind::Forall => fhir::QuantKind::Forall,
1634 };
1635 let body = self.genv().alloc(self.desugar_expr(body));
1636 let param = self.desugar_refine_param(param);
1637 let rng = self.desugar_quant_dom(dom);
1638 fhir::ExprKind::Quant(kind, param, rng, body)
1639 }
1640 surface::ExprKind::Block(decls, body) => {
1641 let decls = self.genv().alloc_slice_fill_iter(decls.iter().map(|decl| {
1642 fhir::LetDecl {
1643 param: self.desugar_refine_param(&decl.param),
1644 init: self.desugar_expr(&decl.init),
1645 }
1646 }));
1647 let body = self.genv().alloc(self.desugar_expr(body));
1648 fhir::ExprKind::Block(decls, body)
1649 }
1650 surface::ExprKind::SetLiteral(exprs) => {
1651 let exprs = self
1652 .genv()
1653 .alloc_slice_fill_iter(exprs.iter().map(|expr| self.desugar_expr(expr)));
1654 fhir::ExprKind::SetLiteral(exprs)
1655 }
1656 surface::ExprKind::Tuple(exprs) => {
1657 let exprs = self
1658 .genv()
1659 .alloc_slice_fill_iter(exprs.iter().map(|expr| self.desugar_expr(expr)));
1660 fhir::ExprKind::Tuple(exprs)
1661 }
1662 };
1663
1664 fhir::Expr { kind, span: expr.span, fhir_id: self.next_fhir_id() }
1665 }
1666
1667 fn desugar_call(
1668 &mut self,
1669 callee: &surface::Expr,
1670 args: &[surface::Expr],
1671 ) -> fhir::ExprKind<'genv> {
1672 let args = self.desugar_exprs(args);
1673 match &callee.kind {
1674 surface::ExprKind::Path(path) => {
1675 match self.desugar_epath(path) {
1676 QPathExpr::Resolved(path, _) => fhir::ExprKind::App(path, args),
1677 QPathExpr::TypeRelative(qself, name) => {
1678 fhir::ExprKind::Alias(fhir::AliasReft::TypeRelative { qself, name }, args)
1679 }
1680 }
1681 }
1682 surface::ExprKind::PrimUIF(op) if args.len() == 2 && self.allow_primop_app() => {
1683 fhir::ExprKind::PrimApp(*op, &args[0], &args[1])
1684 }
1685 surface::ExprKind::AssocReft(qself, path, name) => {
1686 if let Err(err) = self.check_no_holes(qself, path) {
1687 return fhir::ExprKind::Err(err);
1688 }
1689 let qself = self.desugar_ty(qself);
1690 let fhir::QPath::Resolved(None, trait_) = self.desugar_qpath(None, path) else {
1691 span_bug!(path.span, "desugar_alias_reft: unexpected qpath")
1692 };
1693 let Res::Def(DefKind::Trait, _) = trait_.res else {
1694 return fhir::ExprKind::Err(self.emit(errors::InvalidAliasReft::new(path)));
1696 };
1697 let alias_reft = fhir::AliasReft::Qualified {
1698 qself: self.genv().alloc(qself),
1699 trait_,
1700 name: *name,
1701 };
1702 fhir::ExprKind::Alias(alias_reft, args)
1703 }
1704 _ => fhir::ExprKind::Err(self.emit(errors::UnsupportedPosition::new(callee.span))),
1705 }
1706 }
1707
1708 fn desugar_constructor(
1709 &mut self,
1710 path: Option<&surface::ExprPath>,
1711 args: &[surface::ConstructorArg],
1712 ) -> fhir::ExprKind<'genv> {
1713 let path = if let Some(path) = path {
1714 let Some(res @ Res::Def(DefKind::Struct | DefKind::Enum, _)) =
1715 self.resolve_path(path.node_id).full_res()
1716 else {
1717 return fhir::ExprKind::Err(
1718 self.emit(errors::InvalidConstructorPath { span: path.span }),
1719 );
1720 };
1721 let segments = self
1722 .genv()
1723 .alloc_slice_fill_iter(path.segments.iter().map(|s| s.ident));
1724 Some(fhir::PathExpr { res, segments, fhir_id: self.next_fhir_id(), span: path.span })
1725 } else {
1726 None
1727 };
1728
1729 let (field_exprs, spreads): (Vec<_>, Vec<_>) = args.iter().partition_map(|arg| {
1730 match arg {
1731 ConstructorArg::FieldExpr(e) => Either::Left(e),
1732 ConstructorArg::Spread(s) => Either::Right(s),
1733 }
1734 });
1735
1736 let field_exprs = self
1737 .genv()
1738 .alloc_slice_fill_iter(field_exprs.iter().map(|field_expr| {
1739 let e = self.desugar_refine_arg(&field_expr.expr);
1740 fhir::FieldExpr {
1741 ident: field_expr.ident,
1742 expr: e,
1743 fhir_id: self.next_fhir_id(),
1744 span: e.span,
1745 }
1746 }));
1747
1748 match &spreads[..] {
1749 [] => fhir::ExprKind::Constructor(path, field_exprs, None),
1750 [s] => {
1751 let spread = fhir::Spread {
1752 expr: self.desugar_expr(&s.expr),
1753 span: s.span,
1754 fhir_id: self.next_fhir_id(),
1755 };
1756 fhir::ExprKind::Constructor(path, field_exprs, Some(self.genv().alloc(spread)))
1757 }
1758 [s1, s2, ..] => {
1759 let err = errors::MultipleSpreadsInConstructor::new(s1.span, s2.span);
1760 fhir::ExprKind::Err(self.emit(err))
1761 }
1762 }
1763 }
1764
1765 fn desugar_exprs(&mut self, exprs: &[surface::Expr]) -> &'genv [fhir::Expr<'genv>] {
1766 self.genv()
1767 .alloc_slice_fill_iter(exprs.iter().map(|e| self.desugar_expr(e)))
1768 }
1769
1770 fn try_parse_int_lit(&self, span: Span, s: &str) -> Result<u128> {
1771 let s = s.replace("_", "");
1772 let parsed_int = if s.len() <= 2 {
1773 s.parse::<u128>()
1774 } else {
1775 match &s[0..2] {
1776 "0x" => u128::from_str_radix(&s[2..], 16), "0o" => u128::from_str_radix(&s[2..], 8), "0b" => u128::from_str_radix(&s[2..], 2), _ => s.parse::<u128>(), }
1781 };
1782
1783 if let Ok(n) = parsed_int {
1784 Ok(n) } else {
1786 Err(self.emit(errors::IntTooLarge { span }))
1787 }
1788 }
1789
1790 fn desugar_lit(&self, span: Span, lit: surface::Lit) -> fhir::ExprKind<'genv> {
1792 let lit = match lit.kind {
1793 surface::LitKind::Integer => {
1794 let n = match self.try_parse_int_lit(span, lit.symbol.as_str()) {
1795 Ok(n) => n,
1796 Err(err) => return fhir::ExprKind::Err(err),
1797 };
1798 match lit.suffix {
1799 None => fhir::Lit::Int(n),
1800 Some(suffix) => {
1801 return fhir::ExprKind::Err(
1802 self.emit(errors::InvalidNumericSuffix::new(span, suffix)),
1803 );
1804 }
1805 }
1806 }
1807 surface::LitKind::Float => {
1808 if let Some(suffix) = lit.suffix {
1809 return fhir::ExprKind::Err(
1810 self.emit(errors::InvalidNumericSuffix::new(span, suffix)),
1811 );
1812 }
1813 fhir::Lit::Real(lit.symbol)
1814 }
1815 surface::LitKind::Bool => fhir::Lit::Bool(lit.symbol == kw::True),
1816 surface::LitKind::Str => fhir::Lit::Str(lit.symbol),
1817 surface::LitKind::Char => {
1818 match ast::LitKind::from_token_lit(lit) {
1820 Ok(ast::LitKind::Char(c)) => fhir::Lit::Char(c),
1821 _ => return fhir::ExprKind::Err(self.emit(errors::UnexpectedLiteral { span })),
1822 }
1823 }
1824 _ => return fhir::ExprKind::Err(self.emit(errors::UnexpectedLiteral { span })),
1825 };
1826 fhir::ExprKind::Literal(lit)
1827 }
1828}
1829
1830impl<'genv, 'tcx> DesugarCtxt<'genv, 'tcx> for RustItemCtxt<'_, 'genv, 'tcx> {
1831 fn next_fhir_id(&self) -> FhirId {
1832 FhirId { owner: FluxOwnerId::Rust(self.owner), local_id: self.local_id_gen.fresh() }
1833 }
1834
1835 fn genv(&self) -> GlobalEnv<'genv, 'tcx> {
1836 self.genv
1837 }
1838
1839 fn resolver_output(&self) -> &'genv ResolverOutput {
1840 self.resolver_output
1841 }
1842
1843 fn desugar_impl_trait(&mut self, bounds: &[surface::TraitRef]) -> fhir::TyKind<'genv> {
1844 let def_id = self.opaque.unwrap();
1846
1847 let opaque_ty = self.desugar_opaque_ty_for_impl_trait(def_id, bounds);
1850 let opaque_ty = self.insert_opaque_ty(opaque_ty);
1851
1852 fhir::TyKind::OpaqueDef(opaque_ty)
1853 }
1854}
1855
1856impl<'genv, 'tcx> DesugarCtxt<'genv, 'tcx> for FluxItemCtxt<'genv, 'tcx> {
1857 fn next_fhir_id(&self) -> FhirId {
1858 FhirId { owner: FluxOwnerId::Flux(self.owner), local_id: self.local_id_gen.fresh() }
1859 }
1860
1861 fn allow_primop_app(&self) -> bool {
1862 self.allow_primop_app
1863 }
1864
1865 fn genv(&self) -> GlobalEnv<'genv, 'tcx> {
1866 self.genv
1867 }
1868
1869 fn resolver_output(&self) -> &'genv ResolverOutput {
1870 self.resolver_output
1871 }
1872
1873 fn desugar_impl_trait(&mut self, _: &[surface::TraitRef]) -> fhir::TyKind<'genv> {
1874 unimplemented!("`impl Trait` not supported in this item")
1875 }
1876}
1877
1878fn collect_opaque_types(
1881 genv: GlobalEnv,
1882 owner_id: MaybeExternId<OwnerId>,
1883) -> Result<Option<LocalDefId>> {
1884 let mut collector = OpaqueTypeCollector::new(genv.sess());
1885 match genv.tcx().hir_owner_node(owner_id.local_id()) {
1886 hir::OwnerNode::Item(item) => hir::intravisit::walk_item(&mut collector, item),
1887 hir::OwnerNode::ImplItem(impl_item) => {
1888 hir::intravisit::walk_impl_item(&mut collector, impl_item);
1889 }
1890 hir::OwnerNode::TraitItem(trait_item) => {
1891 hir::intravisit::walk_trait_item(&mut collector, trait_item);
1892 }
1893 hir::OwnerNode::ForeignItem(_) | hir::OwnerNode::Crate(_) | hir::OwnerNode::Synthetic => {}
1894 };
1895 collector.into_result()
1896}
1897
1898struct OpaqueTypeCollector<'sess> {
1899 opaque: Option<LocalDefId>,
1900 errors: Errors<'sess>,
1901}
1902
1903impl<'sess> OpaqueTypeCollector<'sess> {
1904 fn new(sess: &'sess FluxSession) -> Self {
1905 Self { opaque: None, errors: Errors::new(sess) }
1906 }
1907
1908 fn into_result(self) -> Result<Option<LocalDefId>> {
1909 self.errors.into_result()?;
1910 Ok(self.opaque)
1911 }
1912}
1913
1914impl<'tcx> hir::intravisit::Visitor<'tcx> for OpaqueTypeCollector<'_> {
1915 fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, rustc_hir::AmbigArg>) {
1916 if let hir::TyKind::OpaqueDef(opaque_ty, ..) = ty.kind {
1917 if self.opaque.is_some() {
1918 self.errors.emit(errors::UnsupportedSignature {
1919 span: ty.span,
1920 note: "duplicate opaque types in signature",
1921 });
1922 } else {
1923 self.opaque = Some(opaque_ty.def_id);
1924 }
1925 }
1926 hir::intravisit::walk_ty(self, ty);
1927 }
1928}