@@ -33,7 +33,7 @@ use crate::env::{self, EnvLen, Level, SharedEnv, UniqueEnv};
3333use crate :: source:: { BytePos , ByteRange , Span , Spanned , StringId , StringInterner } ;
3434use crate :: surface:: elaboration:: reporting:: Message ;
3535use crate :: surface:: {
36- distillation, pretty, BinOp , FormatField , Item , Module , Param , Pattern , Term ,
36+ distillation, pretty, Arg , BinOp , FormatField , Item , Module , Param , Pattern , Term ,
3737} ;
3838
3939mod order;
@@ -934,13 +934,17 @@ impl<'interner, 'arena> Context<'interner, 'arena> {
934934 self . local_env . reserve ( params. len ( ) ) ;
935935
936936 Vec :: from_iter ( params. iter ( ) . map ( |param| {
937- let range = param. pattern . range ( ) ;
938- let ( pattern, type_value) =
939- self . synth_ann_pattern ( & param. pattern , param. r#type . as_ref ( ) ) ;
937+ let ( plicity, pattern, r#type) = match param {
938+ Param :: Explicit ( pattern, r#type) => ( Plicity :: Explicit , pattern, r#type) ,
939+ Param :: Implicit ( pattern, r#type) => ( Plicity :: Implicit , pattern, r#type) ,
940+ } ;
941+
942+ let range = pattern. range ( ) ;
943+ let ( pattern, type_value) = self . synth_ann_pattern ( pattern, r#type. as_ref ( ) ) ;
940944 let r#type = self . quote_env ( ) . quote ( self . scope , & type_value) ;
941945 let ( name, _) = self . push_local_param ( pattern, type_value) ;
942946
943- ( range, param . plicity , name, r#type)
947+ ( range, plicity, name, r#type)
944948 } ) )
945949 }
946950
@@ -1393,7 +1397,7 @@ impl<'interner, 'arena> Context<'interner, 'arena> {
13931397 ( expr, r#type)
13941398 }
13951399 Term :: Universe ( range) => ( core:: Term :: Universe ( range. into ( ) ) , self . universe . clone ( ) ) ,
1396- Term :: Arrow ( range, plicity , param_type, body_type) => {
1400+ Term :: Arrow ( range, param_type, body_type) => {
13971401 let universe = self . universe . clone ( ) ;
13981402 let param_type = self . check ( param_type, & universe) ;
13991403 let param_type_value = self . eval_env ( ) . eval ( & param_type) ;
@@ -1404,7 +1408,7 @@ impl<'interner, 'arena> Context<'interner, 'arena> {
14041408
14051409 let fun_type = core:: Term :: FunType (
14061410 range. into ( ) ,
1407- * plicity ,
1411+ Plicity :: Explicit ,
14081412 None ,
14091413 self . scope . to_scope ( param_type) ,
14101414 self . scope . to_scope ( body_type) ,
@@ -1447,28 +1451,29 @@ impl<'interner, 'arena> Context<'interner, 'arena> {
14471451 let ( mut head_expr, mut head_type) = self . synth ( head_expr) ;
14481452
14491453 for arg in * args {
1450- head_type = self . elim_env ( ) . force ( & head_type) ;
1451-
1452- match arg. plicity {
1453- Plicity :: Implicit => { }
1454- Plicity :: Explicit => {
1454+ let ( arg_plicity, arg_term) = match arg {
1455+ Arg :: Explicit ( arg_term) => {
14551456 ( head_expr, head_type) =
14561457 self . insert_implicit_apps ( head_range, head_expr, head_type) ;
1458+ ( Plicity :: Explicit , arg_term)
14571459 }
1458- }
1460+ Arg :: Implicit ( arg_term) => ( Plicity :: Implicit , arg_term) ,
1461+ } ;
1462+
1463+ head_type = self . elim_env ( ) . force ( & head_type) ;
14591464
14601465 let ( param_type, body_type) = match head_type. as_ref ( ) {
1461- Value :: FunType ( plicity , _, param_type, body_type) => {
1462- if arg . plicity == * plicity {
1466+ Value :: FunType ( param_plicity , _, param_type, body_type) => {
1467+ if arg_plicity == * param_plicity {
14631468 ( param_type, body_type)
14641469 } else {
14651470 let head_type = self . pretty_print_value ( & head_type) ;
14661471 self . messages . push ( Message :: PlicityArgumentMismatch {
14671472 head_range,
1468- head_plicity : Plicity :: Explicit ,
1473+ head_plicity : * param_plicity ,
14691474 head_type,
1470- arg_range : arg . term . range ( ) ,
1471- arg_plicity : arg . plicity ,
1475+ arg_range : arg_term . range ( ) ,
1476+ arg_plicity,
14721477 } ) ;
14731478 return self . synth_reported_error ( * range) ;
14741479 }
@@ -1487,21 +1492,20 @@ impl<'interner, 'arena> Context<'interner, 'arena> {
14871492 self . push_message ( Message :: UnexpectedArgument {
14881493 head_range,
14891494 head_type,
1490- arg_range : arg . term . range ( ) ,
1495+ arg_range : arg_term . range ( ) ,
14911496 } ) ;
14921497 return self . synth_reported_error ( * range) ;
14931498 }
14941499 } ;
14951500
1496- let arg_range = arg. term . range ( ) ;
1497- head_range = ByteRange :: merge ( & head_range, & arg_range) . unwrap ( ) ;
1498-
1499- let arg_expr = self . check ( & arg. term , param_type) ;
1501+ let arg_range = arg_term. range ( ) ;
1502+ let arg_expr = self . check ( arg_term, param_type) ;
15001503 let arg_expr_value = self . eval_env ( ) . eval ( & arg_expr) ;
15011504
1505+ head_range = ByteRange :: merge ( & head_range, & arg_range) . unwrap ( ) ;
15021506 head_expr = core:: Term :: FunApp (
15031507 head_range. into ( ) ,
1504- arg . plicity ,
1508+ arg_plicity ,
15051509 self . scope . to_scope ( head_expr) ,
15061510 self . scope . to_scope ( arg_expr) ,
15071511 ) ;
@@ -1695,37 +1699,39 @@ impl<'interner, 'arena> Context<'interner, 'arena> {
16951699 ) -> core:: Term < ' arena > {
16961700 match params. split_first ( ) {
16971701 Some ( ( param, next_params) ) => {
1702+ let ( param_plicity, pattern, pattern_type) = match param {
1703+ Param :: Explicit ( pattern, r#type) => ( Plicity :: Explicit , pattern, r#type) ,
1704+ Param :: Implicit ( pattern, r#type) => ( Plicity :: Implicit , pattern, r#type) ,
1705+ } ;
1706+
16981707 let body_type = self . elim_env ( ) . force ( expected_type) ;
1699- match body_type. as_ref ( ) {
1700- Value :: FunType ( param_plicity , _, param_type, next_body_type )
1701- if param . plicity == * param_plicity =>
1708+ match ( param_plicity , body_type. as_ref ( ) ) {
1709+ ( param_plicity , Value :: FunType ( next_plicity , _, param_type, body_type ) )
1710+ if param_plicity == * next_plicity =>
17021711 {
1703- let range =
1704- ByteRange :: merge ( & param. pattern . range ( ) , & body_expr. range ( ) ) . unwrap ( ) ;
1705- let pattern = self . check_ann_pattern (
1706- & param. pattern ,
1707- param. r#type . as_ref ( ) ,
1708- param_type,
1709- ) ;
1712+ let range = ByteRange :: merge ( & pattern. range ( ) , & body_expr. range ( ) ) . unwrap ( ) ;
1713+ let pattern =
1714+ self . check_ann_pattern ( pattern, pattern_type. as_ref ( ) , param_type) ;
17101715 let ( name, arg_expr) = self . push_local_param ( pattern, param_type. clone ( ) ) ;
17111716
1712- let body_type = self . elim_env ( ) . apply_closure ( next_body_type , arg_expr) ;
1717+ let body_type = self . elim_env ( ) . apply_closure ( body_type , arg_expr) ;
17131718 let body_expr =
17141719 self . check_fun_lit ( range, next_params, body_expr, & body_type) ;
17151720 self . local_env . pop ( ) ;
17161721
17171722 core:: Term :: FunLit (
17181723 range. into ( ) ,
1719- param . plicity ,
1724+ param_plicity ,
17201725 name,
17211726 self . scope . to_scope ( body_expr) ,
17221727 )
17231728 }
1724- // If an implicit function is expected, try to generalise the
1725- // function literal by wrapping it in an implicit function
1726- Value :: FunType ( Plicity :: Implicit , param_name, param_type, next_body_type)
1727- if param. plicity == Plicity :: Explicit =>
1728- {
1729+ // If an implicit function is expected, generalise the
1730+ // function literal by it in an implicit function
1731+ (
1732+ Plicity :: Explicit ,
1733+ Value :: FunType ( Plicity :: Implicit , param_name, param_type, next_body_type) ,
1734+ ) => {
17291735 let arg_expr = self . local_env . push_param ( * param_name, param_type. clone ( ) ) ;
17301736 let body_type = self . elim_env ( ) . apply_closure ( next_body_type, arg_expr) ;
17311737 let body_expr = self . check_fun_lit ( range, params, body_expr, & body_type) ;
@@ -1737,20 +1743,20 @@ impl<'interner, 'arena> Context<'interner, 'arena> {
17371743 self . scope . to_scope ( body_expr) ,
17381744 )
17391745 }
1740- // Attempt to elaborate the the body of the function in synthesis
1741- // mode if we are checking against a metavariable.
1742- Value :: Stuck ( Head :: MetaVar ( _) , _) => {
1743- let range =
1744- ByteRange :: merge ( & param. pattern . range ( ) , & body_expr. range ( ) ) . unwrap ( ) ;
1746+ // Attempt to elaborate the the body of the function in
1747+ // synthesis mode if we are checking against a metavariable.
1748+ ( _, Value :: Stuck ( Head :: MetaVar ( _) , _) ) => {
1749+ let range = ByteRange :: merge ( & pattern. range ( ) , & body_expr. range ( ) ) . unwrap ( ) ;
17451750 let ( expr, r#type) = self . synth_fun_lit ( range, params, body_expr, None ) ;
17461751 self . convert ( range, expr, & r#type, expected_type)
17471752 }
1748- Value :: Stuck ( Head :: Prim ( Prim :: ReportedError ) , _) => {
1753+ // Propagate reported errors
1754+ ( _, Value :: Stuck ( Head :: Prim ( Prim :: ReportedError ) , _) ) => {
17491755 core:: Term :: Prim ( range. into ( ) , Prim :: ReportedError )
17501756 }
1751- _ => {
1757+ ( _ , _ ) => {
17521758 self . push_message ( Message :: UnexpectedParameter {
1753- param_range : param . pattern . range ( ) ,
1759+ param_range : pattern. range ( ) ,
17541760 } ) ;
17551761 // TODO: For improved error recovery, bind the rest of
17561762 // the parameters, and check the body of the function
@@ -1770,7 +1776,6 @@ impl<'interner, 'arena> Context<'interner, 'arena> {
17701776 body_expr : & Term < ' _ , ByteRange > ,
17711777 body_type : Option < & Term < ' _ , ByteRange > > ,
17721778 ) -> ( core:: Term < ' arena > , ArcValue < ' arena > ) {
1773- self . local_env . reserve ( params. len ( ) ) ;
17741779 let initial_local_len = self . local_env . len ( ) ;
17751780
17761781 let params = self . synth_and_push_params ( params) ;
0 commit comments