-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Improve error messages for scope extrusion errors #24318
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
Conversation
The merged class is reporting.Message.Note.
Present the information as part of explaining an IncludeFailure instead.
eac944e to
b3a1c7c
Compare
b3a1c7c to
744a3d4
Compare
natsukagami
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, I just have some comments about the errors. I like the outlive messages!
| | Capability cap outlives its scope: it leaks into outer capture set 's1 which is owned by value local. | ||
| | The leakage occurred when trying to match the following types: | ||
| | | ||
| | Found: scala.util.boundary.Label[Object^'s1] | ||
| | Required: scala.util.boundary.Label[Object^]^² |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be unrelated to changes in this PR, but I think it's still not clear where cap comes up in this error.
This could be an exception here due to it being an inline-expanded definition with an inlined local variable
| | | ||
| | Note that capability x$0 is not included in capture set {cap}. | ||
| |Note that capability x$0 is not included in capture set {cap} | ||
| |because cap, which is existentially bound in () =>² Unit, cannot subsume x$0 since that capability is not a SharedCapability. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the number 2 in () =>² Unit seems to be out of nowhere compared to the preceding context.
| |Capability cap outlives its scope: it leaks into outer capture set 's1 which is owned by value leak. | ||
| |The leakage occurred when trying to match the following types: | ||
| | | ||
| |Note that capability cap cannot be included in outer capture set 's6. | ||
| |Found: (lcap: Cap^'s2) ->'s3 () ->'s4 Id[Cap^'s5]^'s6 | ||
| |Required: (lcap: Cap^) => () =>² Id[Cap^'s1]^'s7 | ||
| | | ||
| |where: => refers to a fresh root capability created in value leak when checking argument to parameter op of method withCap | ||
| | =>² refers to a root capability associated with the result type of (lcap: Cap^): () =>² Id[Cap^'s6]^'s7 | ||
| | =>² refers to a root capability associated with the result type of (lcap: Cap^): () =>² Id[Cap^'s1]^'s7 | ||
| | ^ refers to the universal root capability | ||
| | cap is a root capability associated with the result type of (): Id[Cap^'s4]^'s5 | ||
| | cap is a root capability associated with the result type of (): Id[Cap^'s5]^'s6 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's quite confusing here that we have "cap cannot outlive 's1" (which is part of the result type), but cap is also "a root capability associated with the result type of (): Id[Cap^'s5]^'s6"
|
For some comparison, I wrote a Rust almost equivalent (link to Rust Playground) of Rust error messagesRust source code#[derive(Debug)]
struct File {}
fn test(file: &mut File) {
let mut v = file;
let mut w: Box<dyn FnOnce() -> ()> = Box::new(|| ());
// two parameters, otherwise Rust will complain about separation
|x: &mut File, y: &mut File| {
let g = Box::new(|| println!("{:?}", y));
v = x;
w = g;
};
}
fn with_file<T>(fun: impl FnOnce(&mut File) -> T) -> T {
let mut f = File {};
let r = fun(&mut f);
r
}
fn ident<T>(t: T) -> T { t }
fn main() {
with_file(|v| v);
with_file(ident);
with_file(|v| ident(v));
// ^ note that Rust currently doesn't have an explicit syntax to introduce
// lifetime parameters for closures, so the only thing we can do here is
// rely on inference for the type passed to `ident`.
let id: Box<dyn for<'a> Fn(&'a mut File) -> &'a mut File> = Box::new(|v| v);
with_file(id);
with_file(|v| || println!("{:?}", v));
} |
|
@natsukagami Good points about where errors are still unclear! Can you make issues describing these problems? Then we can track them. I don't think we have an immediate fix right now. |
Several improvements for error messages signalling level errors.
Also, several refactorings that simplify and unify the schemas for processing error notes.