@@ -1597,14 +1597,24 @@ impl<'arena> Context<'arena> {
15971597 ( term, r#type)
15981598 }
15991599 Term :: Proj ( range, head_expr, labels) => {
1600- let head_range = head_expr. range ( ) ;
1600+ let mut head_range = head_expr. range ( ) ;
16011601 let ( mut head_expr, mut head_type) = self . synth_and_insert_implicit_apps ( head_expr) ;
16021602
16031603 ' labels: for ( label_range, proj_label) in * labels {
16041604 head_type = self . elim_env ( ) . force ( & head_type) ;
1605- match ( & head_expr, head_type. as_ref ( ) ) {
1605+ match head_type. as_ref ( ) {
1606+ r#type if r#type. is_unit_type ( ) => {
1607+ self . push_message ( Message :: RecordProjUnit {
1608+ head_range : self . file_range ( head_range) ,
1609+ head_type : self . pretty_value ( & head_type) ,
1610+ label_range : self . file_range ( * label_range) ,
1611+ label : * proj_label,
1612+ } ) ;
1613+ return self . synth_reported_error ( * range) ;
1614+ }
1615+
16061616 // Ensure that the head of the projection is a record
1607- ( _ , Value :: RecordType ( labels, types) ) => {
1617+ Value :: RecordType ( labels, types) => {
16081618 let mut labels = labels. iter ( ) . copied ( ) ;
16091619 let mut types = types. clone ( ) ;
16101620
@@ -1618,9 +1628,9 @@ impl<'arena> Context<'arena> {
16181628 if * proj_label == label {
16191629 // The field was found. Update the head expression
16201630 // and continue elaborating the next projection.
1631+ head_range = ByteRange :: merge ( head_range, * label_range) ;
16211632 head_expr = core:: Term :: RecordProj (
1622- self . file_range ( ByteRange :: merge ( head_range, * label_range) )
1623- . into ( ) ,
1633+ self . file_range ( head_range) . into ( ) ,
16241634 self . scope . to_scope ( head_expr) ,
16251635 * proj_label,
16261636 ) ;
@@ -1636,28 +1646,32 @@ impl<'arena> Context<'arena> {
16361646 }
16371647 }
16381648 // Couldn't find the field in the record type.
1639- // Fallthrough with an error.
1649+ self . push_message ( Message :: RecordProjNotFound {
1650+ head_range : self . file_range ( head_range) ,
1651+ head_type : self . pretty_value ( & head_type) ,
1652+ label_range : self . file_range ( * label_range) ,
1653+ label : * proj_label,
1654+ suggested_label : suggest_name ( * proj_label, labels) ,
1655+ } ) ;
1656+ return self . synth_reported_error ( * range) ;
16401657 }
16411658 // There's been an error when elaborating the head of
16421659 // the projection, so avoid trying to elaborate any
16431660 // further to prevent cascading type errors.
1644- ( core:: Term :: Prim ( _, Prim :: ReportedError ) , _)
1645- | ( _, Value :: Stuck ( Head :: Prim ( Prim :: ReportedError ) , _) ) => {
1661+ _ if head_expr. is_error ( ) || head_type. is_error ( ) => {
16461662 return self . synth_reported_error ( * range) ;
16471663 }
16481664 // The head expression was not a record type.
1649- // Fallthrough with an error.
1650- _ => { }
1665+ _ => {
1666+ self . push_message ( Message :: RecordProjNotRecord {
1667+ head_range : self . file_range ( head_range) ,
1668+ head_type : self . pretty_value ( & head_type) ,
1669+ label_range : self . file_range ( * label_range) ,
1670+ label : * proj_label,
1671+ } ) ;
1672+ return self . synth_reported_error ( * range) ;
1673+ }
16511674 }
1652-
1653- self . push_message ( Message :: UnknownField {
1654- head_range : self . file_range ( head_range) ,
1655- head_type : self . pretty_value ( & head_type) ,
1656- label_range : self . file_range ( * label_range) ,
1657- label : * proj_label,
1658- suggested_label : suggest_name ( * proj_label, labels. iter ( ) . map ( |( _, l) | * l) ) ,
1659- } ) ;
1660- return self . synth_reported_error ( * range) ;
16611675 }
16621676
16631677 ( head_expr, head_type)
0 commit comments