Skip to content

Commit c76ad0b

Browse files
committed
incorporating feedbacks
1 parent 9d320e8 commit c76ad0b

File tree

1 file changed

+86
-50
lines changed

1 file changed

+86
-50
lines changed

rfcs/0000-changes-lifecyle.md

Lines changed: 86 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -43,31 +43,29 @@ A breaking change is a difference in functionality from the previous version of
4343

4444
The following changes are defined to be breaking changes, and will need to follow the process of being gated by features flags.
4545

46-
1 - Code without deprecated warning to be flagged as error;
47-
2 - ABI json properties to be removed or have their type changed;
48-
3 - Binary encoding that will break how SDK (and others) communicate with the compiler, that includes
49-
50-
- How scripts/predicates accept arguments on `main`;
51-
- How scripts/predicates return data from `main`;
52-
- How the `contract method selector` is encoded;
53-
- How `contract method` arguments are encoded;
54-
- How `log` data is encoded;
55-
- How `message` data is encoded;
56-
57-
4 - Utilization of new VM opcodes;
58-
5 - IR changes
59-
6 - Receipt parsers to break;
60-
7 - When a compiler feature or a standard library produce different behavior for the same code (semantic changes);
46+
1. Code without deprecated warning to be flagged as error;
47+
2. ABI json properties to be removed or have their type changed;
48+
3. Binary encoding that will break how SDK (and others) communicate with the compiler, that includes
49+
- How scripts/predicates accept arguments on `main`;
50+
- How scripts/predicates return data from `main`;
51+
- How the `contract method selector` is encoded;
52+
- How `contract method` arguments are encoded;
53+
- How `log` data is encoded;
54+
- How `message` data is encoded;
55+
4. Utilization of new VM opcodes;
56+
5. IR changes
57+
6. Receipt parsers to break;
58+
7. When a compiler feature or a standard library produce different behavior for the same code (semantic changes);
6159

6260
## Feature flags
6361

6462
Any complex change that needed to be gated will need the following steps.
6563

66-
1 - A specific github issue labeled with `feature-*` and `track-feature`. This issue should be the umbrella for everything related with this feature;
67-
2 - A preliminary PR enabling the feature flag should be created and linked in to the umbrella issue; This PR will enable the feature flag `--experimental <comma-separated-list>` on all tools.
68-
3 - As many PRs will be created and merged an normal;
69-
4 - When the feature is ready, a closing PR will be created and wait until the feature flag is enabled by default.
70-
5 - On a later date, the feature flag can be removed making the feature the default behavior of the compiler.
64+
1. A specific github issue labeled with `feature-*` and `track-feature`. This issue should be the umbrella for everything related with this feature;
65+
2. A preliminary PR enabling the feature flag should be created and linked in to the umbrella issue; This PR will enable the feature flag `--experimental <comma-separated-list>` on all tools.
66+
3. As many PRs will be created and merged an normal;
67+
4. When the feature is ready, a closing PR will be created and wait until the feature flag is enabled by default.
68+
5. On a later date, the feature flag can be removed making the feature the default behavior of the compiler.
7169

7270
# Enabling features on `sway`
7371

@@ -83,6 +81,12 @@ or using the CLI
8381
> forc ... --experimental some_feature,another_feature
8482
```
8583

84+
or event using the environment variables
85+
86+
```
87+
> FORC_EXPERIMENTAL_SOME_FEATURE forc ...
88+
```
89+
8690
These flags also need to be enabled programmatically by any compiler driver, like tests.
8791

8892
Unlike `Rust` we will not support features inside sway code like the example below, because some features will span across multiple tools. That would demand `forc` to parse, or ask the `sway` compiler if a feature is enabled or not.
@@ -97,6 +101,29 @@ Unlike `Rust` we will not support features inside sway code like the example bel
97101

98102
This section contains the suggested guide on how to introduce changes into different parts of the compiler and associated tools.
99103

104+
## `sway-features` crate
105+
106+
A new crate named `sway-features` will be created and will contains **ALL** features and its metadata. Best suggestion is a macro do define features where enums, documentation etc... will be generated.
107+
108+
This macro also needs to generate code for the errors and warnings related to each error.
109+
110+
Features will be parsed in this order:
111+
112+
```rust
113+
let mut features = ExperimentalFeatures::default();
114+
features.parse_from_toml();
115+
features.parse_from_cli();
116+
features.parse_from_environment_variables();
117+
```
118+
119+
Which means that environment variables overwrite cli arguments, which overwrite toml configuration.
120+
121+
If a feature requires or allow new configurations, these configurations should be optional, and as soon is confirmed the feature is enabled, it should verify if the required configuration is available.
122+
123+
```
124+
> forc ... --experimental a_feature --a-feature-option 1
125+
```
126+
100127
## Lexer and Parser
101128

102129
To allow as user friendly error messages as possible, in all possible cases we want both lexer and parser to parse the new syntax even with the feature off.
@@ -105,39 +132,45 @@ After that, lexer, parser will mark that a experimental feature was lexed/parsed
105132

106133
The error message will have a message explaining that feature is experimental and a github link for more details on the stabilization lifecycle.
107134

135+
```rust
136+
// always parse new syntax
137+
let new_syntax = parse_new_syntax();
138+
if ctx.experimental.is_disabled(Features::NEW_FEATURE) {
139+
handler.emit_error(...);
140+
}
141+
```
142+
108143
## Formatting
109144

110-
When formatting does not depend on a flag, formatting should always format new syntax, even when the flag is off. To avoid breaking other parts of the code, or even worst, removing code.
145+
Formatting should always format new syntax, even when the flag is off. To avoid breaking other parts of the code, or even worst, removing code.
111146

112147
## LSP
113148

114149
LSP can take advantage of specific error messages, and suggest user to enable the corresponding feature.
115150

116-
## TODO
151+
## CST, AST and Typed Tree
117152

118-
3 - Lexer?
119-
4 - Parser?
120-
5 - CST?
121-
6 - AST?
122-
7 - Typed Tree
123-
8 - LSP
124-
9 - Forc and plugins
125-
10 - swayfmt
126-
11 - New error
153+
All tree must always support new features, which means that new nodes will always exist. Their specific behavior, desugaring etc... will be gated by the experimental feature.
154+
155+
More specifically, this means that variants should not be behind compiler flags.
127156

128157
# Drawbacks
129158

130159
[drawbacks]: #drawbacks
131160

132-
Why should we _not_ do this?
161+
This will increase complexity of the compiler. Not all flags used to compile end up in the JSON ABI, or other outputs. Which can make reproducibility harder.
133162

134163
# Rationale and alternatives
135164

136165
[rationale-and-alternatives]: #rationale-and-alternatives
137166

138-
- Why is this design the best in the space of possible designs?
139-
- What other designs have been considered and what is the rationale for not choosing them?
140-
- What is the impact of not doing this?
167+
There only two other alternatives, which we consider worst options:
168+
169+
1. Keep experimental features in branches;
170+
2. Keep experimental features behind compiler flags (conditional compilation);
171+
172+
The first one normally creates more problems than it solves. Integration hell become a reality sooner than later.
173+
The second does not decrease complexity of the code, and it decreases testability of features, given that they will not be in the "release binary".
141174

142175
# Prior art
143176

@@ -149,14 +182,14 @@ These are the sources and stacks used as motivation for this RFC.
149182

150183
https://rustc-dev-guide.rust-lang.org/implementing_new_features.html#stability-in-code
151184

152-
1 - Open a tracking issue;
153-
2 - Pick a name for the feature gate;
154-
3,4 - Add the feature gate to the compiler code;
155-
5 - If the feature gate is not set, you should either maintain the pre-feature behavior or raise an error, depending on what makes sense;
156-
6 - Add a test to ensure the feature cannot be used without a feature gate;
157-
7 - Add a section to the unstable book;
158-
8 - Write a lot of tests for the new feature;
159-
9 - Get your PR reviewed and land it.
185+
1. - Open a tracking issue;
186+
2. - Pick a name for the feature gate;
187+
3. - Add the feature gate to the compiler code;
188+
4. - If the feature gate is not set, you should either maintain the pre-feature behavior or raise an error, depending on what makes sense;
189+
5. - Add a test to ensure the feature cannot be used without a feature gate;
190+
6. - Add a section to the unstable book;
191+
7. - Write a lot of tests for the new feature;
192+
8. - Get your PR reviewed and land it.
160193

161194
## changeset
162195

@@ -167,15 +200,18 @@ https://github.com/changesets/changesets
167200
[unresolved-questions]: #unresolved-questions
168201

169202
Where should we save "release notes"?
170-
1 - In files inside the repo? - Saving in files sounds the best approach, but if we use the same file, all PRs will conflict. To avoid this we can do like `changeset` and use random names.
171-
2 - In github PR descriptions? - This is the easiest approach, but it can be cumbersome to recover these messages.
172-
3 - In git commit messages? - Given that the commit message is "created" when the PR is merged, there is no way to guarantee that "release notes" will exist or be "parseable" when we need them.
203+
204+
1. In files inside the repo? - Saving in files sounds the best approach, but if we use the same file, all PRs will conflict. To avoid this we can do like `changeset` and use random names.
205+
2. In github PR descriptions? - This is the easiest approach, but it can be cumbersome to recover these messages.
206+
3. In git commit messages? - Given that the commit message is "created" when the PR is merged, there is no way to guarantee that "release notes" will exist or be "parseable" when we need them.
207+
- https://git-cliff.org/
173208

174209
Should new warnings be considered breaking changes?
175-
1 - Normally warnings should not be considered breaking changes, because they do not break anything.
176-
2 - But on the other hand, if the team treat warnings as errors, new warnings will break CIs, and demand
177-
developers attention. Not all fixes are trivial, and can demand bigger code changes than the user would expect
178-
from a minor update from the compiler.
210+
211+
1. Normally warnings should not be considered breaking changes, because they do not break anything.
212+
2. But on the other hand, if the team treat warnings as errors, new warnings will break CIs, and demand
213+
developers attention. Not all fixes are trivial, and can demand bigger code changes than the user would expect
214+
from a minor update from the compiler.
179215

180216
# Future possibilities
181217

0 commit comments

Comments
 (0)