Skip to content

Commit befeab2

Browse files
authored
[move 2024][alpha] Method syntax (#13933)
## Description See 'Release Notes' for feature description. This PR: - Resurrects original method style syntax - Adds a `defines_primitive` annotation so that method style syntax can be used with primitive/builtin types - Adds use fun declarations Some notes about implementation details - A normal use alias, `use a::m::f as g` introduces an implicit `use fun a::m::f as a::m::S.g` in situations where the first argument of `a::m::f` is `a::m::S`. This ensures that there isn't any weird precedence/shadowing between `use` and `use fun` in a given scope. - There are some nuances here, but the rules are ensuring that once you have a module that calls `x.foo()`, it always resolves to the same function `a::m::bar`, even if new `public use fun`s are added elsewhere. - I had to move `ProgramInfo` into the `naming::ast::program` and `typing::ast::program` to properly resolve `use funs` (particularly with this implicit setup described above) Follow up - `let mut` and `mut` variable modifiers - I think I will rewrite alias maps in expansion to reduce clones (as I did with use fun declarations ## Test Plan - New tests --- If your changes are not user-facing and not a breaking change, you can skip the following section. Otherwise, please indicate what changed, and then add to the Release Notes section as highlighted during the release process. ### Type of Change (Check all that apply) - [ ] protocol change - [X] user-visible impact - [ ] breaking change for a client SDKs - [ ] breaking change for FNs (FN binary must upgrade) - [ ] breaking change for validators or node operators (must upgrade binaries) - [ ] breaking change for on-chain data layout - [ ] necessitate either a data wipe or data migration ### Release notes Method style syntax has been added to Move 2024.alpha. This means functions can now be invoked with the syntax, `e.foo(arg1, arg2)`. Assuming `e: a::m::S` (or `&a::m::S` or `&mut a::m::S`), `e.foo(arg1, arg2)` will resolve to `a::m::foo(e, arg1, arg2)`. Additionally, the compiler will borrow `e` when necessary. For instances where the desired target function is not declared in the same module as the type (or is not declared with the desired name), a `use fun` alias can be used instead. For example, `use b::n::bar as S.baz` will allow `e.baz()` to resolve as `b::n::bar(e)`. A `public use fun` can be declared in the types defining module, allowing the alias to be used outside of the module.
1 parent a4f01c4 commit befeab2

File tree

129 files changed

+4300
-438
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

129 files changed

+4300
-438
lines changed

move-analyzer/src/symbols.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,7 @@ impl Symbolicator {
702702
}
703703
}
704704

705-
let modules = &typed_ast.unwrap().modules;
705+
let modules = &typed_ast.unwrap().inner.modules;
706706

707707
let mut mod_outer_defs = BTreeMap::new();
708708
let mut mod_use_defs = BTreeMap::new();

move-compiler/src/cfgir/cfg.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ impl<T: Deref<Target = BasicBlocks>> CFG for ForwardCFG<T> {
272272
}
273273

274274
fn debug(&self) {
275-
crate::shared::ast_debug::print(self);
275+
self.print();
276276
}
277277
}
278278

@@ -733,7 +733,7 @@ impl<'forward, Blocks: Deref<Target = BasicBlocks>> CFG for ReverseCFG<'forward,
733733
}
734734

735735
fn debug(&self) {
736-
crate::shared::ast_debug::print(self);
736+
self.print();
737737
}
738738
}
739739

move-compiler/src/diagnostics/codes.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ codes!(
204204
InvalidAttribute: { msg: "invalid attribute", severity: NonblockingError },
205205
InvalidVisibilityModifier:
206206
{ msg: "invalid visibility modifier", severity: NonblockingError },
207+
InvalidUseFun: { msg: "invalid 'use fun' declaration", severity: NonblockingError },
207208
],
208209
// errors name resolution, mostly expansion/translate and naming/translate
209210
NameResolution: [
@@ -250,6 +251,7 @@ codes!(
250251
(NOTE: this may become an error in the future)",
251252
severity: Warning
252253
},
254+
InvalidMethodCall: { msg: "invalid method call", severity: BlockingError },
253255
],
254256
// errors for ability rules. mostly typing/translate
255257
AbilitySafety: [

move-compiler/src/editions/mod.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub enum FeatureGate {
3030
PublicPackage,
3131
PostFixAbilities,
3232
StructTypeVisibility,
33+
DotCall,
3334
}
3435

3536
#[derive(PartialEq, Eq, Clone, Copy, Debug, PartialOrd, Ord, Default)]
@@ -46,7 +47,7 @@ pub enum Flavor {
4647
pub fn check_feature(
4748
env: &mut CompilationEnv,
4849
edition: Edition,
49-
feature: &FeatureGate,
50+
feature: FeatureGate,
5051
loc: Loc,
5152
) -> bool {
5253
let supports_feature = edition.supports(feature);
@@ -61,8 +62,9 @@ pub fn check_feature(
6162
(
6263
loc,
6364
format!(
64-
"{feature} not supported by current edition '{edition}', \
65-
only '{valid_editions}' support this feature"
65+
"{} not supported by current edition '{edition}', \
66+
only '{valid_editions}' support this feature",
67+
feature.error_prefix(),
6668
)
6769
)
6870
);
@@ -75,7 +77,7 @@ pub fn check_feature(
7577
supports_feature
7678
}
7779

78-
pub fn valid_editions_for_feature(feature: &FeatureGate) -> Vec<Edition> {
80+
pub fn valid_editions_for_feature(feature: FeatureGate) -> Vec<Edition> {
7981
Edition::ALL
8082
.iter()
8183
.filter(|e| e.supports(feature))
@@ -94,6 +96,7 @@ const E2024_ALPHA_FEATURES: &[FeatureGate] = &[
9496
FeatureGate::PublicPackage,
9597
FeatureGate::PostFixAbilities,
9698
FeatureGate::StructTypeVisibility,
99+
FeatureGate::DotCall,
97100
];
98101

99102
impl Edition {
@@ -110,8 +113,8 @@ impl Edition {
110113

111114
pub const ALL: &[Self] = &[Self::LEGACY, Self::E2024_ALPHA];
112115

113-
pub fn supports(&self, feature: &FeatureGate) -> bool {
114-
SUPPORTED_FEATURES.get(self).unwrap().contains(feature)
116+
pub fn supports(&self, feature: FeatureGate) -> bool {
117+
SUPPORTED_FEATURES.get(self).unwrap().contains(&feature)
115118
}
116119

117120
// Intended only for implementing the lazy static (supported feature map) above
@@ -159,6 +162,17 @@ impl Flavor {
159162
pub const ALL: &[Self] = &[Self::GlobalStorage, Self::Sui];
160163
}
161164

165+
impl FeatureGate {
166+
fn error_prefix(&self) -> &'static str {
167+
match self {
168+
FeatureGate::PublicPackage => "'public(package)' is",
169+
FeatureGate::PostFixAbilities => "Postfix abilities are",
170+
FeatureGate::StructTypeVisibility => "Struct visibility modifiers are",
171+
FeatureGate::DotCall => "Method syntax is",
172+
}
173+
}
174+
}
175+
162176
//**************************************************************************************************
163177
// Parsing/Deserialize
164178
//**************************************************************************************************
@@ -263,12 +277,6 @@ impl Serialize for Flavor {
263277
}
264278
}
265279

266-
impl Display for FeatureGate {
267-
fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
268-
Ok(())
269-
}
270-
}
271-
272280
//**************************************************************************************************
273281
// traits
274282
//**************************************************************************************************

move-compiler/src/expansion/aliases.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
// SPDX-License-Identifier: Apache-2.0
44

55
use crate::{
6-
expansion::ast::{ModuleIdent, ModuleIdent_},
7-
parser::ast::ModuleName,
6+
expansion::ast::{self as E, ModuleIdent, ModuleIdent_},
7+
parser::ast::{self as P, ModuleName},
88
shared::{unique_map::UniqueMap, unique_set::UniqueSet, *},
99
};
1010
use move_ir_types::location::*;
@@ -33,6 +33,20 @@ pub struct AliasMap {
3333

3434
pub struct OldAliasMap(Option<AliasMap>);
3535

36+
pub struct ParserExplicitUseFun {
37+
pub loc: Loc,
38+
pub attributes: E::Attributes,
39+
pub is_public: Option<Loc>,
40+
pub function: Box<P::NameAccessChain>,
41+
pub ty: Box<P::NameAccessChain>,
42+
pub method: Name,
43+
}
44+
45+
pub struct UseFunsBuilder {
46+
pub explicit: Vec<ParserExplicitUseFun>,
47+
pub implicit: UniqueMap<Name, E::ImplicitUseFunCandidate>,
48+
}
49+
3650
impl AliasSet {
3751
pub fn new() -> Self {
3852
Self {
@@ -276,3 +290,12 @@ impl OldAliasMap {
276290
}
277291
}
278292
}
293+
294+
impl UseFunsBuilder {
295+
pub fn new() -> Self {
296+
Self {
297+
explicit: vec![],
298+
implicit: UniqueMap::new(),
299+
}
300+
}
301+
}

0 commit comments

Comments
 (0)