digital-asset / daml

The Daml smart contract language
https://www.digitalasset.com/developers
Other
801 stars 203 forks source link

Duplicate errors without locations for template fields with out of scope types #13826

Open cocreature opened 2 years ago

cocreature commented 2 years ago
module Main where

template T
  with
    p : Party
    f : MyBrokenType
  where
    signatory p

This produces 4 errors. 3/4 have no location which in vscode confusingly pops up as a module-level error

2022-05-09 10:39:58.95 [INFO]  [build] 
Compiling foobar to a DAR.
File:     daml/Main.daml
Hidden:   no
Range:    1:1-1:1
Source:   typecheck
Severity: DsError
Message:  daml/Main.daml:1:1: error:Not in scope: type constructor or class ‘MyBrokenType’
File:     daml/Main.daml
Hidden:   no
Range:    1:1-1:1
Source:   typecheck
Severity: DsError
Message:  daml/Main.daml:1:1: error:Not in scope: type constructor or class ‘MyBrokenType’
File:     daml/Main.daml
Hidden:   no
Range:    1:1-1:1
Source:   typecheck
Severity: DsError
Message:  daml/Main.daml:1:1: error:Not in scope: type constructor or class ‘MyBrokenType’
File:     daml/Main.daml
Hidden:   no
Range:    6:9-6:21
Source:   typecheck
Severity: DsError
Message:  daml/Main.daml:6:9: error:Not in scope: type constructor or class ‘MyBrokenType’
ERROR: Creation of DAR file failed.
akrmn commented 2 years ago

The extra errors (the ones with location 1:1-1:1) come from the records preprocessor (DA.Daml.Preprocessor.Records), which adds the following instance

instance HasField "f" T MyBrokenType where
--                      ^^^^^^^^^^^^
  getField = getFieldPrim @"f" @T @MyBrokenType
--                                 ^^^^^^^^^^^^
  setField = setFieldPrim @"f" @T @MyBrokenType
--                                 ^^^^^^^^^^^^

I don't really know how to get rid of these from the root, since at the preprocessor we have no way of knowing if MyBrokenType is a type in scope.

At first I thought we could extend the SrcLoc type with another constructor for compiler- or preprocessor-generated code, which could then be filtered out when reporting errors, but I'm uncomfortable with the idea that a program might fail with just that sort of error - though perhaps in that case we could just show all the errors.

A different approach would be to use the original locations in the generated instance and nubOrd the diagnostics before showing them.