microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
billt/revert-mimalloc

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

compiler/qsc_hir/src/ty.rs

782lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use indenter::{indented, Indented};
5use qsc_data_structures::span::Span;
6use rustc_hash::FxHashMap;
7
8use crate::hir::{CallableKind, FieldPath, Functor, ItemId, PackageId, Res};
9use std::{
10 fmt::{self, Debug, Display, Formatter, Write},
11 rc::Rc,
12};
13
14fn set_indentation<'a, 'b>(
15 indent: Indented<'a, Formatter<'b>>,
16 level: usize,
17) -> Indented<'a, Formatter<'b>> {
18 match level {
19 0 => indent.with_str(""),
20 1 => indent.with_str(" "),
21 2 => indent.with_str(" "),
22 _ => unimplemented!("intentation level not supported"),
23 }
24}
25
26/// A type.
27#[derive(Clone, Debug, Default, Eq, PartialEq)]
28pub enum Ty {
29 /// An array type.
30 Array(Box<Ty>),
31 /// An arrow type: `->` for a function or `=>` for an operation.
32 Arrow(Box<Arrow>),
33 /// A placeholder type variable used during type inference.
34 Infer(InferTyId),
35 /// A type parameter.
36 Param(Rc<str>, ParamId),
37 /// A primitive type.
38 Prim(Prim),
39 /// A tuple type.
40 Tuple(Vec<Ty>),
41 /// A user-defined type.
42 Udt(Rc<str>, Res),
43 /// An invalid type.
44 #[default]
45 Err,
46}
47
48impl Ty {
49 /// The unit type.
50 pub const UNIT: Self = Self::Tuple(Vec::new());
51
52 #[must_use]
53 pub fn with_package(&self, package: PackageId) -> Self {
54 match self {
55 Ty::Infer(_) | Ty::Param(_, _) | Ty::Prim(_) | Ty::Err => self.clone(),
56 Ty::Array(item) => Ty::Array(Box::new(item.with_package(package))),
57 Ty::Arrow(arrow) => Ty::Arrow(Box::new(arrow.with_package(package))),
58 Ty::Tuple(items) => Ty::Tuple(
59 items
60 .iter()
61 .map(|item| item.with_package(package))
62 .collect(),
63 ),
64 Ty::Udt(name, res) => Ty::Udt(name.clone(), res.with_package(package)),
65 }
66 }
67
68 pub fn display(&self) -> String {
69 match self {
70 Ty::Array(item) => {
71 format!("{}[]", item.display())
72 }
73 Ty::Arrow(arrow) => {
74 let arrow_symbol = match arrow.kind {
75 CallableKind::Function => "->",
76 CallableKind::Operation => "=>",
77 };
78
79 let functors = match arrow.functors {
80 FunctorSet::Value(FunctorSetValue::Empty)
81 | FunctorSet::Param(_, FunctorSetValue::Empty) => String::new(),
82 FunctorSet::Value(_) | FunctorSet::Infer(_) => {
83 format!(" is {}", arrow.functors)
84 }
85 FunctorSet::Param(_, functors) => {
86 format!(" is {functors}")
87 }
88 };
89 format!(
90 "({} {arrow_symbol} {}{functors})",
91 arrow.input.display(),
92 arrow.output.display()
93 )
94 }
95 Ty::Infer(_) | Ty::Err => "?".to_string(),
96 Ty::Param(name, _) | Ty::Udt(name, _) => name.to_string(),
97 Ty::Prim(prim) => format!("{prim:?}"),
98 Ty::Tuple(items) => {
99 if items.is_empty() {
100 "Unit".to_string()
101 } else if items.len() == 1 {
102 let item = items.first().expect("expected single item");
103 format!("({},)", item.display())
104 } else {
105 let items = items.iter().map(Ty::display).collect::<Vec<_>>().join(", ");
106 format!("({items})")
107 }
108 }
109 }
110 }
111}
112
113impl Display for Ty {
114 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
115 match self {
116 Ty::Array(item) => write!(f, "{item}[]"),
117 Ty::Arrow(arrow) => Display::fmt(arrow, f),
118 Ty::Infer(infer) => Display::fmt(infer, f),
119 Ty::Param(name, param_id) => {
120 write!(f, "Param<\"{name}\": {param_id}>")
121 }
122 Ty::Prim(prim) => Debug::fmt(prim, f),
123 Ty::Tuple(items) => {
124 if items.is_empty() {
125 f.write_str("Unit")
126 } else {
127 f.write_char('(')?;
128 if let Some((first, rest)) = items.split_first() {
129 Display::fmt(first, f)?;
130 if rest.is_empty() {
131 f.write_char(',')?;
132 } else {
133 for item in rest {
134 f.write_str(", ")?;
135 Display::fmt(item, f)?;
136 }
137 }
138 }
139 f.write_str(")")
140 }
141 }
142 Ty::Udt(name, res) => {
143 write!(f, "UDT<\"{name}\": {res}>")
144 }
145 Ty::Err => f.write_char('?'),
146 }
147 }
148}
149
150/// A type scheme.
151pub struct Scheme {
152 params: Vec<GenericParam>,
153 ty: Box<Arrow>,
154}
155
156impl Scheme {
157 /// Creates a new type scheme.
158 #[must_use]
159 pub fn new(params: Vec<GenericParam>, ty: Box<Arrow>) -> Self {
160 Self { params, ty }
161 }
162
163 #[must_use]
164 pub fn with_package(&self, package: PackageId) -> Self {
165 Self {
166 params: self.params.clone(),
167 ty: Box::new(Arrow {
168 kind: self.ty.kind,
169 input: Box::new(self.ty.input.with_package(package)),
170 output: Box::new(self.ty.output.with_package(package)),
171 functors: self.ty.functors,
172 }),
173 }
174 }
175
176 /// The generic parameters to the type.
177 #[must_use]
178 pub fn params(&self) -> &[GenericParam] {
179 &self.params
180 }
181
182 /// Instantiates this type scheme with the given arguments.
183 ///
184 /// # Errors
185 ///
186 /// Returns an error if the given arguments do not match the scheme parameters.
187 pub fn instantiate(&self, args: &[GenericArg]) -> Result<Arrow, InstantiationError> {
188 if args.len() == self.params.len() {
189 let args: FxHashMap<_, _> = self
190 .params
191 .iter()
192 .enumerate()
193 .map(|(ix, _)| ParamId::from(ix))
194 .zip(args)
195 .collect();
196 instantiate_arrow_ty(|name| args.get(name).copied(), &self.ty)
197 } else {
198 Err(InstantiationError::Arity)
199 }
200 }
201}
202
203/// A type scheme instantiation error.
204#[derive(Debug)]
205pub enum InstantiationError {
206 /// The number of generic arguments does not match the number of generic parameters.
207 Arity,
208 /// A generic argument does not match the kind of its corresponding generic parameter.
209 Kind(ParamId),
210}
211
212fn instantiate_ty<'a>(
213 arg: impl Fn(&ParamId) -> Option<&'a GenericArg> + Copy,
214 ty: &Ty,
215) -> Result<Ty, InstantiationError> {
216 match ty {
217 Ty::Err | Ty::Infer(_) | Ty::Prim(_) | Ty::Udt(_, _) => Ok(ty.clone()),
218 Ty::Array(item) => Ok(Ty::Array(Box::new(instantiate_ty(arg, item)?))),
219 Ty::Arrow(arrow) => Ok(Ty::Arrow(Box::new(instantiate_arrow_ty(arg, arrow)?))),
220 Ty::Param(_, param) => match arg(param) {
221 Some(GenericArg::Ty(ty_arg)) => Ok(ty_arg.clone()),
222 Some(_) => Err(InstantiationError::Kind(*param)),
223 None => Ok(ty.clone()),
224 },
225 Ty::Tuple(items) => Ok(Ty::Tuple(
226 items
227 .iter()
228 .map(|item| instantiate_ty(arg, item))
229 .collect::<Result<_, _>>()?,
230 )),
231 }
232}
233
234fn instantiate_arrow_ty<'a>(
235 arg: impl Fn(&ParamId) -> Option<&'a GenericArg> + Copy,
236 arrow: &Arrow,
237) -> Result<Arrow, InstantiationError> {
238 let input = instantiate_ty(arg, &arrow.input)?;
239 let output = instantiate_ty(arg, &arrow.output)?;
240 let functors = if let FunctorSet::Param(param, _) = arrow.functors {
241 match arg(&param) {
242 Some(GenericArg::Functor(functor_arg)) => *functor_arg,
243 Some(_) => return Err(InstantiationError::Kind(param)),
244 None => arrow.functors,
245 }
246 } else {
247 arrow.functors
248 };
249
250 Ok(Arrow {
251 kind: arrow.kind,
252 input: Box::new(input),
253 output: Box::new(output),
254 functors,
255 })
256}
257
258impl Display for GenericParam {
259 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
260 match self {
261 GenericParam::Ty(name) => write!(f, "type {name}"),
262 GenericParam::Functor(min) => write!(f, "functor ({min})"),
263 }
264 }
265}
266
267/// The kind of a generic parameter.
268#[derive(Clone, Debug, PartialEq)]
269pub enum GenericParam {
270 /// A type parameter.
271 Ty(TypeParamName),
272 /// A functor parameter with a lower bound.
273 Functor(FunctorSetValue),
274}
275
276/// The name of a generic type parameter.
277#[derive(Clone, Debug, PartialEq)]
278pub struct TypeParamName {
279 /// The span.
280 pub span: Span,
281 /// The name.
282 pub name: Rc<str>,
283}
284
285impl Display for TypeParamName {
286 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
287 write!(f, "{} \"{}\"", self.span, self.name)
288 }
289}
290
291/// A generic parameter ID.
292#[derive(Clone, Copy, Default, Debug, Eq, Hash, PartialEq)]
293pub struct ParamId(u32);
294
295impl ParamId {
296 /// The successor of this ID.
297 #[must_use]
298 pub fn successor(self) -> Self {
299 Self(self.0 + 1)
300 }
301}
302
303impl From<usize> for ParamId {
304 fn from(value: usize) -> Self {
305 ParamId(
306 value
307 .try_into()
308 .expect("Type Parameter ID does not fit into u32"),
309 )
310 }
311}
312
313impl From<ParamId> for usize {
314 fn from(value: ParamId) -> Self {
315 value.0 as usize
316 }
317}
318
319impl Display for ParamId {
320 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
321 Display::fmt(&self.0, f)
322 }
323}
324
325/// An argument to a generic parameter.
326#[derive(Clone, Debug, Eq, PartialEq)]
327pub enum GenericArg {
328 /// A type argument.
329 Ty(Ty),
330 /// A functor argument.
331 Functor(FunctorSet),
332}
333
334impl Display for GenericArg {
335 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
336 match self {
337 GenericArg::Ty(ty) => Display::fmt(ty, f),
338 GenericArg::Functor(functors) => Display::fmt(functors, f),
339 }
340 }
341}
342
343/// An arrow type: `->` for a function or `=>` for an operation.
344#[derive(Clone, Debug, Eq, PartialEq)]
345pub struct Arrow {
346 /// Whether the callable is a function or an operation.
347 pub kind: CallableKind,
348 /// The input type to the callable.
349 pub input: Box<Ty>,
350 /// The output type from the callable.
351 pub output: Box<Ty>,
352 /// The functors supported by the callable.
353 pub functors: FunctorSet,
354}
355
356impl Arrow {
357 #[must_use]
358 pub fn with_package(&self, package: PackageId) -> Self {
359 Self {
360 kind: self.kind,
361 input: Box::new(self.input.with_package(package)),
362 output: Box::new(self.output.with_package(package)),
363 functors: self.functors,
364 }
365 }
366}
367
368impl Display for Arrow {
369 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
370 let arrow = match self.kind {
371 CallableKind::Function => "->",
372 CallableKind::Operation => "=>",
373 };
374 write!(f, "({} {arrow} {}", self.input, self.output)?;
375 if self.functors != FunctorSet::Value(FunctorSetValue::Empty) {
376 f.write_str(" is ")?;
377 Display::fmt(&self.functors, f)?;
378 }
379 f.write_char(')')
380 }
381}
382
383/// A primitive type.
384#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
385pub enum Prim {
386 /// The big integer type.
387 BigInt,
388 /// The boolean type.
389 Bool,
390 /// The floating-point type.
391 Double,
392 /// The integer type.
393 Int,
394 /// The Pauli operator type.
395 Pauli,
396 /// The qubit type.
397 Qubit,
398 /// The range type.
399 Range,
400 /// The range type without a lower bound.
401 RangeTo,
402 /// The range type without an upper bound.
403 RangeFrom,
404 /// The range type without lower and upper bounds.
405 RangeFull,
406 /// The measurement result type.
407 Result,
408 /// The string type.
409 String,
410}
411
412/// A set of functors.
413#[derive(Clone, Copy, Debug, Eq, PartialEq)]
414pub enum FunctorSet {
415 /// An evaluated set.
416 Value(FunctorSetValue),
417 /// A functor parameter.
418 Param(ParamId, FunctorSetValue),
419 /// A placeholder functor variable used during type inference.
420 Infer(InferFunctorId),
421}
422
423impl FunctorSet {
424 /// Returns the contained value.
425 ///
426 /// # Panics
427 ///
428 /// Panics if this set is not a value.
429 #[must_use]
430 pub fn expect_value(self, msg: &str) -> FunctorSetValue {
431 match self {
432 Self::Value(value) => value,
433 Self::Param(_, _) | Self::Infer(_) => panic!("{msg}"),
434 }
435 }
436}
437
438impl Display for FunctorSet {
439 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
440 match self {
441 Self::Value(value) => Display::fmt(value, f),
442 Self::Param(param, _) => write!(f, "Param<{param}>"),
443 Self::Infer(infer) => Display::fmt(infer, f),
444 }
445 }
446}
447
448/// The value of a functor set.
449#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
450pub enum FunctorSetValue {
451 /// The empty set.
452 #[default]
453 Empty,
454 /// The singleton adjoint set.
455 Adj,
456 /// The singleton controlled set.
457 Ctl,
458 /// The set of controlled and adjoint.
459 CtlAdj,
460}
461
462impl FunctorSetValue {
463 /// True if this set contains the functor.
464 #[must_use]
465 pub fn contains(&self, functor: &Functor) -> bool {
466 match self {
467 Self::Empty => false,
468 Self::Adj => matches!(functor, Functor::Adj),
469 Self::Ctl => matches!(functor, Functor::Ctl),
470 Self::CtlAdj => matches!(functor, Functor::Adj | Functor::Ctl),
471 }
472 }
473
474 /// The intersection of this set and another set.
475 #[must_use]
476 pub fn intersect(&self, other: &Self) -> Self {
477 match (self, other) {
478 (Self::Empty, _)
479 | (_, Self::Empty)
480 | (Self::Adj, Self::Ctl)
481 | (Self::Ctl, Self::Adj) => Self::Empty,
482 (Self::Adj, Self::Adj) => Self::Adj,
483 (Self::Ctl, Self::Ctl) => Self::Ctl,
484 (Self::CtlAdj, &set) | (&set, Self::CtlAdj) => set,
485 }
486 }
487
488 /// The union of this set and another set.
489 #[must_use]
490 pub fn union(&self, other: &Self) -> Self {
491 match (self, other) {
492 (Self::Empty, &set) | (&set, Self::Empty) => set,
493 (Self::Adj, Self::Adj) => Self::Adj,
494 (Self::Ctl, Self::Ctl) => Self::Ctl,
495 (Self::CtlAdj, _)
496 | (_, Self::CtlAdj)
497 | (Self::Adj, Self::Ctl)
498 | (Self::Ctl, Self::Adj) => Self::CtlAdj,
499 }
500 }
501
502 #[must_use]
503 pub fn satisfies(&self, other: &Self) -> bool {
504 matches!(
505 (self, other),
506 (_, Self::Empty)
507 | (Self::Adj | Self::CtlAdj, Self::Adj)
508 | (Self::Ctl | Self::CtlAdj, Self::Ctl)
509 | (Self::CtlAdj, Self::CtlAdj)
510 )
511 }
512}
513
514impl Display for FunctorSetValue {
515 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
516 match self {
517 Self::Empty => f.write_str("empty set"),
518 Self::Adj => f.write_str("Adj"),
519 Self::Ctl => f.write_str("Ctl"),
520 Self::CtlAdj => f.write_str("Adj + Ctl"),
521 }
522 }
523}
524
525/// A user-defined type.
526#[derive(Clone, Debug, PartialEq)]
527pub struct Udt {
528 /// The span.
529 pub span: Span,
530 /// The name.
531 pub name: Rc<str>,
532 // The definition.
533 pub definition: UdtDef,
534}
535
536impl Udt {
537 #[must_use]
538 pub fn get_pure_ty(&self) -> Ty {
539 fn get_pure_ty(def: &UdtDef) -> Ty {
540 match &def.kind {
541 UdtDefKind::Field(field) => field.ty.clone(),
542 UdtDefKind::Tuple(tup) => Ty::Tuple(tup.iter().map(get_pure_ty).collect()),
543 }
544 }
545 get_pure_ty(&self.definition)
546 }
547
548 /// The type scheme of the constructor for this type definition.
549 ///
550 /// # Arguments
551 ///
552 /// * `id` - The ID of the constructed type.
553 #[must_use]
554 pub fn cons_scheme(&self, id: ItemId) -> Scheme {
555 Scheme {
556 params: Vec::new(),
557 ty: Box::new(Arrow {
558 kind: CallableKind::Function,
559 input: Box::new(self.get_pure_ty()),
560 output: Box::new(Ty::Udt(self.name.clone(), Res::Item(id))),
561 functors: FunctorSet::Value(FunctorSetValue::Empty),
562 }),
563 }
564 }
565
566 /// The path to the field with the given name. Returns [None] if this user-defined type does not
567 /// have a field with the given name.
568 #[must_use]
569 pub fn field_path(&self, name: &str) -> Option<FieldPath> {
570 Self::find_field_path(&self.definition, name)
571 }
572
573 fn find_field_path(def: &UdtDef, name: &str) -> Option<FieldPath> {
574 match &def.kind {
575 UdtDefKind::Field(field) => field.name.as_ref().and_then(|field_name| {
576 if field_name.as_ref() == name {
577 Some(FieldPath::default())
578 } else {
579 None
580 }
581 }),
582 UdtDefKind::Tuple(defs) => defs.iter().enumerate().find_map(|(i, def)| {
583 Self::find_field_path(def, name).map(|mut path| {
584 path.indices.insert(0, i);
585 path
586 })
587 }),
588 }
589 }
590
591 fn find_field(&self, path: &FieldPath) -> Option<&UdtField> {
592 let mut udt_def = &self.definition;
593 for &index in &path.indices {
594 let UdtDefKind::Tuple(items) = &udt_def.kind else {
595 return None;
596 };
597 udt_def = &items[index];
598 }
599 let UdtDefKind::Field(field) = &udt_def.kind else {
600 return None;
601 };
602 Some(field)
603 }
604
605 /// The field with the given name. Returns [None] if this user-defined type does not
606 /// have a field with the given name.
607 #[must_use]
608 pub fn find_field_by_name(&self, name: &str) -> Option<&UdtField> {
609 Self::find_field_by_name_rec(&self.definition, name)
610 }
611
612 fn find_field_by_name_rec<'a>(def: &'a UdtDef, name: &str) -> Option<&'a UdtField> {
613 match &def.kind {
614 UdtDefKind::Field(field) => field.name.as_ref().and_then(|field_name| {
615 if field_name.as_ref() == name {
616 Some(field)
617 } else {
618 None
619 }
620 }),
621 UdtDefKind::Tuple(defs) => defs
622 .iter()
623 .find_map(|def| Self::find_field_by_name_rec(def, name)),
624 }
625 }
626
627 /// The type of the field at the given path. Returns [None] if the path is not valid for this
628 /// user-defined type.
629 #[must_use]
630 pub fn field_ty(&self, path: &FieldPath) -> Option<&Ty> {
631 self.find_field(path).map(|field| &field.ty)
632 }
633
634 /// The type of the field with the given name. Returns [None] if this user-defined type does not
635 /// have a field with the given name.
636 #[must_use]
637 pub fn field_ty_by_name(&self, name: &str) -> Option<&Ty> {
638 self.find_field_by_name(name).map(|field| &field.ty)
639 }
640}
641
642impl Display for Udt {
643 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
644 let mut indent = set_indentation(indented(f), 0);
645 write!(indent, "UDT {}:", self.span)?;
646 indent = set_indentation(indent, 1);
647 write!(indent, "\n{}", self.definition)?;
648 Ok(())
649 }
650}
651
652/// A UDT type definition.
653#[derive(Clone, Debug, PartialEq)]
654pub struct UdtDef {
655 /// The span.
656 pub span: Span,
657 /// The type definition kind.
658 pub kind: UdtDefKind,
659}
660
661impl Display for UdtDef {
662 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
663 write!(f, "TyDef {}: {}", self.span, self.kind)
664 }
665}
666
667/// A UDT type definition kind.
668#[derive(Clone, Debug, PartialEq)]
669pub enum UdtDefKind {
670 /// A field definition with an optional name but required type.
671 Field(UdtField),
672 /// A tuple.
673 Tuple(Vec<UdtDef>),
674}
675
676impl Display for UdtDefKind {
677 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
678 let mut indent = set_indentation(indented(f), 0);
679 match &self {
680 UdtDefKind::Field(field) => {
681 write!(indent, "Field:")?;
682 indent = set_indentation(indent, 1);
683 write!(indent, "{field}")?;
684 }
685 UdtDefKind::Tuple(ts) => {
686 if ts.is_empty() {
687 write!(indent, "Unit")?;
688 } else {
689 write!(indent, "Tuple:")?;
690 indent = set_indentation(indent, 1);
691 for t in ts {
692 write!(indent, "\n{t}")?;
693 }
694 }
695 }
696 }
697 Ok(())
698 }
699}
700
701/// A user-defined type.
702#[derive(Clone, Debug, PartialEq)]
703pub struct UdtField {
704 /// The span of the field name.
705 pub name_span: Option<Span>,
706 /// The field name.
707 pub name: Option<Rc<str>>,
708 // The field type.
709 pub ty: Ty,
710}
711
712impl Display for UdtField {
713 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
714 if let Some(n) = &self.name {
715 if let Some(s) = &self.name_span {
716 write!(f, "\nname: {n} {s}")?;
717 }
718 }
719 write!(f, "\ntype: {}", self.ty)?;
720 Ok(())
721 }
722}
723
724/// A placeholder type variable used during type inference.
725#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
726pub struct InferTyId(usize);
727
728impl InferTyId {
729 /// The successor of this ID.
730 #[must_use]
731 pub fn successor(self) -> Self {
732 Self(self.0 + 1)
733 }
734}
735
736impl Display for InferTyId {
737 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
738 write!(f, "?{}", self.0)
739 }
740}
741
742impl From<usize> for InferTyId {
743 fn from(value: usize) -> Self {
744 Self(value)
745 }
746}
747
748impl From<InferTyId> for usize {
749 fn from(value: InferTyId) -> Self {
750 value.0
751 }
752}
753
754/// A placeholder functor variable used during type inference.
755#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
756pub struct InferFunctorId(usize);
757
758impl InferFunctorId {
759 /// The successor of this ID.
760 #[must_use]
761 pub fn successor(self) -> Self {
762 Self(self.0 + 1)
763 }
764}
765
766impl Display for InferFunctorId {
767 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
768 write!(f, "f?{}", self.0)
769 }
770}
771
772impl From<usize> for InferFunctorId {
773 fn from(value: usize) -> Self {
774 InferFunctorId(value)
775 }
776}
777
778impl From<InferFunctorId> for usize {
779 fn from(value: InferFunctorId) -> Self {
780 value.0
781 }
782}
783