diff --git a/compiler/qsc_eval/src/lower.rs b/compiler/qsc_eval/src/lower.rs index 18a59cb249..23aed7f597 100644 --- a/compiler/qsc_eval/src/lower.rs +++ b/compiler/qsc_eval/src/lower.rs @@ -537,7 +537,7 @@ fn lower_functor_set(functors: &qsc_hir::ty::FunctorSet) -> qsc_fir::ty::Functor qsc_hir::ty::FunctorSet::Value(v) => { qsc_fir::ty::FunctorSet::Value(lower_functor_set_value(v)) } - qsc_hir::ty::FunctorSet::Param(p) => { + qsc_hir::ty::FunctorSet::Param(p, _) => { qsc_fir::ty::FunctorSet::Param(ParamId::from(usize::from(p))) } qsc_hir::ty::FunctorSet::Infer(i) => { diff --git a/compiler/qsc_frontend/src/typeck/convert.rs b/compiler/qsc_frontend/src/typeck/convert.rs index 2678e567e3..955647d06d 100644 --- a/compiler/qsc_frontend/src/typeck/convert.rs +++ b/compiler/qsc_frontend/src/typeck/convert.rs @@ -203,7 +203,7 @@ fn synthesize_functor_params(next_param: &mut ParamId, ty: &mut Ty) -> Vec match arrow.functors { FunctorSet::Value(functors) if arrow.kind == hir::CallableKind::Operation => { let param = GenericParam::Functor(functors); - arrow.functors = FunctorSet::Param(*next_param); + arrow.functors = FunctorSet::Param(*next_param, functors); *next_param = next_param.successor(); vec![param] } diff --git a/compiler/qsc_hir/src/ty.rs b/compiler/qsc_hir/src/ty.rs index bf7a7a841b..b006e88c56 100644 --- a/compiler/qsc_hir/src/ty.rs +++ b/compiler/qsc_hir/src/ty.rs @@ -75,10 +75,16 @@ impl Ty { CallableKind::Function => "->", CallableKind::Operation => "=>", }; - let functors = if arrow.functors == FunctorSet::Value(FunctorSetValue::Empty) { - String::new() - } else { - format!(" is {}", arrow.functors) + + let functors = match arrow.functors { + FunctorSet::Value(FunctorSetValue::Empty) + | FunctorSet::Param(_, FunctorSetValue::Empty) => String::new(), + FunctorSet::Value(_) | FunctorSet::Infer(_) => { + format!(" is {}", arrow.functors) + } + FunctorSet::Param(_, functors) => { + format!(" is {functors}") + } }; format!( "({} {arrow_symbol} {}{functors})", @@ -231,7 +237,7 @@ fn instantiate_arrow_ty<'a>( ) -> Result { let input = instantiate_ty(arg, &arrow.input)?; let output = instantiate_ty(arg, &arrow.output)?; - let functors = if let FunctorSet::Param(param) = arrow.functors { + let functors = if let FunctorSet::Param(param, _) = arrow.functors { match arg(¶m) { Some(GenericArg::Functor(functor_arg)) => *functor_arg, Some(_) => return Err(InstantiationError::Kind(param)), @@ -409,7 +415,7 @@ pub enum FunctorSet { /// An evaluated set. Value(FunctorSetValue), /// A functor parameter. - Param(ParamId), + Param(ParamId, FunctorSetValue), /// A placeholder functor variable used during type inference. Infer(InferFunctorId), } @@ -424,7 +430,7 @@ impl FunctorSet { pub fn expect_value(self, msg: &str) -> FunctorSetValue { match self { Self::Value(value) => value, - Self::Param(_) | Self::Infer(_) => panic!("{msg}"), + Self::Param(_, _) | Self::Infer(_) => panic!("{msg}"), } } } @@ -433,7 +439,7 @@ impl Display for FunctorSet { fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { Self::Value(value) => Display::fmt(value, f), - Self::Param(param) => write!(f, "Param<{param}>"), + Self::Param(param, _) => write!(f, "Param<{param}>"), Self::Infer(infer) => Display::fmt(infer, f), } } diff --git a/language_service/src/hover/tests.rs b/language_service/src/hover/tests.rs index fef0da84a5..1a35c1ba90 100644 --- a/language_service/src/hover/tests.rs +++ b/language_service/src/hover/tests.rs @@ -1084,6 +1084,26 @@ fn callable_param_doc() { ); } +#[test] +fn callable_generic_functor_display() { + check( + indoc! {" + namespace Test { + operation Foo(op : (Qubit => Unit is Adj)) : Unit {} + operation Main() : Unit { + ◉Fo↘o◉; + } + } + "}, + &expect![[r#" + ```qsharp + Test + operation Foo(op : (Qubit => Unit is Adj)) : Unit + ``` + "#]], + ); +} + #[test] fn udt_field_incorrect() { check_none(indoc! {r#"