Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom error messages no longer propagate down to first non-inline calls #17

Closed
LouisJenkinsCS opened this issue Oct 6, 2018 · 6 comments

Comments

@LouisJenkinsCS
Copy link
Collaborator

Custom error messages, generated via compilerError, allowed us to provide the user more helpful error messages on how to use our data structure to get around the ambiguity that arise from the default compiler error messages. These custom error messages used to show the callsite (file name and line number) of the first non-inlined function, usually where it was called by the user. Now compilerError stops at the first parent, despite it being inlined or not, meaning the custom error messages are no longer helpful but harmful...

I need to create an issue on this or adapt to the new changes (which may mean no function that generates errors for me but good-old-fashioned copy-paste)

@LouisJenkinsCS
Copy link
Collaborator Author

@mppf mentioned that compilerError has an errorDepth overload that will do what I want. Perhaps Debug.badArgs can take an argument with a similar argument that defaults to 2. Will verify that this works before closing issue.

@LouisJenkinsCS
Copy link
Collaborator Author

@mppf I am having a bit of an issue here because technically the errorDepth is a bit dynamic, but easily provable at compile time. Lets say that each time a function is called a compile-time counter is incremented and when a function exits it gets decremented. This would be enough to obtain the errorDepth, but it seems that this isn't possible? Whenever I attempt to make a global param and then use it in a function I get a 'used before defined' compiler error. The function I am trying to use can be seen below...

proc badArgs(bad, type good...?n) param {
compilerError("Expected argument of type to be in ", good : string, " but received argument of type ", bad.type : string);
}

It does not include the dynamic compile-time counter yet as it will not compile. Any assistance with this? The ability to provide custom errors for the user was actually one of the highlights we made for the language (in the paper and presentation on CHGL), it would be nice to have this ability back.

@mppf
Copy link

mppf commented Oct 8, 2018

I am having a bit of an issue here because technically the errorDepth is a bit dynamic, but easily provable at compile time.

Can you say what the actual issue here is?

Lets say that each time a function is called a compile-time counter is incremented and when a function exits it gets decremented.

You can't modify a param variable.

@LouisJenkinsCS
Copy link
Collaborator Author

LouisJenkinsCS commented Oct 8, 2018

Can you say what the actual issue here is?

We describe vertices and edges via a wrapper (record that contains a type which determines whether the wrapper refers to a vertex or edge), but we also allow implicit type conversions for integers of the same width and signed-ness. Hence we perform type-checking a bit late, sometimes after multiple function calls (a function f can call g which calls h which finally does type-checking) which would need to propagate the type error down to where the user invoked the original function (f in this example).

The issue is that since we have internal functions calling other functions, which may vary in depth, it wouldn't be correct to hard-code the actual errorDepth (for example, the sequence f -> g -> h is valid but so is g -> h or even just h). I suppose one way to resolve this would be to perform type-checking of these implicit casts early or add explicit types (rather than inferred) to enforce a more predictable type-checking from the compiler, but since we allow conversions between integers and their wrappers, if we had N arguments, we'd need to make 2^N + 1 overloads... Example...

     proc hasInclusion(v : vIndexType, e : eIndexType) {                                                                                                                                                  
       const vDesc = toVertex(v);                                                                                                                                                                         
       const eDesc = toEdge(e);                                                                                                                                                                           
                                                                                                                                                                                                          
       return getVertex(vDesc).hasNeighbor(eDesc);                                                                                                                                                        
     }                                                                                                                                                                                                    
                                                                                                                                                                                                          
     proc hasInclusion(vDesc : vDescType, e : eIndexType) {                                                                                                                                               
       const eDesc = toEdge(e);                                                                                                                                                                           
       return getVertex(vDesc).hasNeighbor(eDesc);                                                                                                                                                        
     }                                                                                                                                                                                                    
                                                                                                                                                                                                          
     proc hasInclusion(v : vIndexType, eDesc : eDescType) {                                                                                                                                               
       const vDesc = toVertex(v);                                                                                                                                                                         
       return getVertex(vDesc).hasNeighbor(eDesc);                                                                                                                                                        
     }                                                                                                                                                                                                    
                                                                                                                                                                                                          
     proc hasInclusion(vDesc : vDescType, e : eDescType) {                                                                                                                                                
       return getVertex(vDesc).hasNeighbor(eDesc);                                                                                                                                                        
     }                                                                                                                                                                                                    
                                                                                                                                                                                                          
     proc hasInclusion(v, e) {                                                                                                                                                                            
       Debug.badArgs((v, e), ((vIndexType, eIndexType), (vDescType, eDescType), (vIndexType, eDescType), (vDescType, eIndexType)));                                                                       
     } 

Why do we have Debug.badArgs to begin with if the compiler can emit its own error?

The compiler's default errors are ambiguous and vague at times, and very frustrating to work with at times. Custom and tailored error messages like this make it much easier to figure out what is wrong.

Let me know if I was unclear in any way.

Edit: I should mention that toVertex and toEdge does its own type-checking as well as bounds-checking (if enabled).

@github-actions
Copy link

This issue is stale and should either be closed or eventually resolved.

@mppf
Copy link

mppf commented Jan 31, 2020

I wonder if it'd be sufficient to have something like compilerError that reported the line number at the module boundary (so ignored functions within the module with the compilerError).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants