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

diag: methods sharing names with struct fields produce confusing diagnostic message #118

Closed
bqwstt opened this issue Oct 13, 2024 · 2 comments · Fixed by #119
Closed

diag: methods sharing names with struct fields produce confusing diagnostic message #118

bqwstt opened this issue Oct 13, 2024 · 2 comments · Fixed by #119

Comments

@bqwstt
Copy link

bqwstt commented Oct 13, 2024

Unsure if this is a diagnostic or IR issue.

When lowering calls, we are not handling callable items that share names with identifiers. For example, struct methods called the same as one of their fields get treated as identifiers, thus lowering fails.

To me, this looks like an IR issue, but following the Language Guide, this may well be expected. If this is intentional, we should improve the error diagnostic to mention these name collisions (which can be confusing).

Example (playground example below):

struct A {
    field: u32,
}

impl A {
    fn field(self: &A) -> u32 {
        self.field
    }
}

fn main() {
    let a = A { field: 42 };
    println!("a.field={}", a.field());
}

Output:

error: function or static expected
  --> [program.alu:13:28](https://play.alumina-lang.net/#)

This happens in ir/mono/mod.rs's lower_call:

let (arg_types, return_type, callee) = match callee.ty {
ir::Ty::FunctionPointer(arg_types, return_type) => (*arg_types, *return_type, callee),
ir::Ty::Item(item) => match item.get().with_backtrace(&self.diag)? {
ir::Item::Closure(closure) => {
self_arg = Some(self.r#ref(callee, callee.span));
let fun_item = closure.function.get().unwrap();
let fun = fun_item.get_function().with_backtrace(&self.diag)?;
fn_arg_types = fun.args.iter().skip(1).map(|p| p.ty).collect();
(
&fn_arg_types[..],
fun.return_type,
self.exprs.function(fun_item, callee.span),
)
}
ir::Item::Function(fun) => {
if fun.varargs {
varargs = true;
}
fn_arg_types = fun.args.iter().map(|p| p.ty).collect();
(&fn_arg_types[..], fun.return_type, callee)
}
_ => {
bail!(self, CodeDiagnostic::FunctionOrStaticExpectedHere);
}

Reproducible Example

https://play.alumina-lang.net/?code=1695451deb28b0f0

The above is a rather silly example (could just use field directly), but similar situations may happen (e.g., with a builder struct).

Compilation Info

Revision: 304bf3f4ff1f77739f31f3f7fe8c88c0f5b9e9fb

304bf3f4 (HEAD -> master, origin/master, origin/HEAD) chore: Add settings for Github Linguist (#117)
@tibordp
Copy link
Member

tibordp commented Oct 13, 2024

Fields have precedence over methods in name resolution, so from the behavior perspective, this is expected, but I agree that it deserves a better error message.

Check out #119 for an improvement.

@bqwstt
Copy link
Author

bqwstt commented Oct 13, 2024

That was quick! Thanks, it's much more clear now.

@bqwstt bqwstt changed the title diag/ir: methods sharing names with struct fields produce unexpected results/messages diag: methods sharing names with struct fields produce confusing diagnostic message Oct 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants