Skip to content

Commit c9109eb

Browse files
authored
Compare modes semantically instead of literally (#29300)
Add logic to compare modes semantically to avoid erroring on comparing a lack of mode (which defaults to private) to an explicit private mode. Fixes #29288
1 parent af59efe commit c9109eb

File tree

4 files changed

+32
-7
lines changed

4 files changed

+32
-7
lines changed

crates/ast/src/functions/mode.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,18 @@ pub enum Mode {
2626
Public,
2727
}
2828

29+
impl Mode {
30+
/// Are the modes considered equal as far as the Leo user is concerned?
31+
///
32+
/// In particular, `None` defaults to `Private`.
33+
pub fn eq_user(&self, other: &Mode) -> bool {
34+
match (self, other) {
35+
(Self::None | Self::Private, Self::None | Self::Private) => true,
36+
(a, b) => a == b,
37+
}
38+
}
39+
}
40+
2941
impl fmt::Display for Mode {
3042
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3143
use Mode::*;

crates/passes/src/check_interfaces/visitor.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,8 @@ impl<'a> CheckInterfacesVisitor<'a> {
161161
return None;
162162
}
163163
Some(cm)
164-
if !cm.type_.eq_user(&parent_member.type_) || cm.mode != parent_member.mode =>
164+
if !cm.type_.eq_user(&parent_member.type_)
165+
|| !cm.mode.eq_user(&parent_member.mode) =>
165166
{
166167
self.state.handler.emit_err(
167168
CheckInterfacesError::conflicting_record_field(
@@ -424,12 +425,12 @@ impl<'a> CheckInterfacesVisitor<'a> {
424425
// Parameter types must match.
425426
input_a.type_.eq_user(&input_b.type_) &&
426427
// Parameter modes must match.
427-
input_a.mode == input_b.mode
428+
input_a.mode.eq_user(&input_b.mode)
428429
}) &&
429430

430431
// Output must match.
431432
a.output.len() == b.output.len() &&
432-
a.output.iter().zip(b.output.iter()).all(|(output_a, output_b)| output_a.type_.eq_user(&output_b.type_) && output_a.mode == output_b.mode) &&
433+
a.output.iter().zip(b.output.iter()).all(|(output_a, output_b)| output_a.type_.eq_user(&output_b.type_) && output_a.mode.eq_user(&output_b.mode)) &&
433434

434435
// Const parameters must match.
435436
a.const_parameters.len() == b.const_parameters.len() &&
@@ -456,14 +457,14 @@ impl<'a> CheckInterfacesVisitor<'a> {
456457
// Parameter types must match.
457458
func_input.type_.eq_user(&proto_input.type_) &&
458459
// Parameter modes must match.
459-
func_input.mode == proto_input.mode
460+
func_input.mode.eq_user(&proto_input.mode)
460461
}) &&
461462

462463
// Output must match.
463464
func.output.len() == proto.output.len() &&
464465

465466
func.output.iter().zip(proto.output.iter()).all(
466-
|(func_output, proto_output)| func_output.type_.eq_user(&proto_output.type_) && func_output.mode == proto_output.mode) &&
467+
|(func_output, proto_output)| func_output.type_.eq_user(&proto_output.type_) && func_output.mode.eq_user(&proto_output.mode)) &&
467468

468469
// Const parameters must match.
469470
func.const_parameters.len() == proto.const_parameters.len() &&
@@ -506,7 +507,7 @@ impl<'a> CheckInterfacesVisitor<'a> {
506507
child.members.iter().any(|child_member| {
507508
child_member.identifier.name == parent_member.identifier.name
508509
&& child_member.type_.eq_user(&parent_member.type_)
509-
&& child_member.mode == parent_member.mode
510+
&& child_member.mode.eq_user(&parent_member.mode)
510511
})
511512
})
512513
}
@@ -523,7 +524,7 @@ impl<'a> CheckInterfacesVisitor<'a> {
523524
None => return Some((required_member.identifier.name, required_member, None)),
524525
Some(actual_member) => {
525526
if !actual_member.type_.eq_user(&required_member.type_)
526-
|| actual_member.mode != required_member.mode
527+
|| !actual_member.mode.eq_user(&required_member.mode)
527528
{
528529
return Some((required_member.identifier.name, required_member, Some(actual_member)));
529530
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
program scratch.aleo;
2+
3+
function foo:
4+
input r0 as u8.private;
5+
output 0u8 as u8.private;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
interface Foo {
2+
fn foo(private a: u8) -> private u8;
3+
}
4+
5+
program scratch.aleo : Foo {
6+
fn foo(a: u8) -> u8 { return 0; }
7+
}

0 commit comments

Comments
 (0)