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

Implicitly include std and core when undeclared in the Forc.toml #330

Closed
sezna opened this issue Oct 26, 2021 · 1 comment · Fixed by #1137
Closed

Implicitly include std and core when undeclared in the Forc.toml #330

sezna opened this issue Oct 26, 2021 · 1 comment · Fixed by #1137
Assignees
Labels
enhancement New feature or request forc

Comments

@sezna
Copy link
Contributor

sezna commented Oct 26, 2021

Currently, the standard library needs to be manually imported in the Forc.toml file. We should actually automatically import that.

@sezna sezna added the good first issue Good for newcomers label Oct 26, 2021
@sezna sezna added forc and removed good first issue Good for newcomers labels Jan 3, 2022
@adlerjohn adlerjohn added the enhancement New feature or request label Jan 7, 2022
@adlerjohn adlerjohn moved this to Todo in Fuel Network Jan 7, 2022
@mitchmindtree mitchmindtree changed the title automatically package the standard library without needing it in the toml Implicitly include std and core when undeclared in the Forc.toml Mar 16, 2022
@mitchmindtree mitchmindtree self-assigned this Mar 16, 2022
@mitchmindtree
Copy link
Contributor

I think this work is best suited to the forc_pkg crate, as it handles the forc package dependency graph.

User-specified core and std

We want to keep support for allowing users to specify custom versions of std or core. For now, this is only really important for the sway repo's test suite. We can do so by keeping the current behaviour, only implicitly including core and std in the case that they're not specified. That said, there are a few cases to consider:

  • If neither std or core are declared, we include them both implicitly.
  • If both std and core are declared, we use the user specified versions of each.
  • If only std is declared, we use the user specified std and that std's core dependency.
  • If only core is declared, the approach for choosing std is less clear. This is because if we use the implicit std, it may have a different core dependency that could result in conflicts.
    We could potentially replace the implicit std's core dependency with the user-specified core acting like a "patch", but we don't have a proper patching support, and depending on how core is modified, it could result in errors when building std.
    Due to the potential ambiguity in behaviour, we should probably just produce a build error in this case stating that if core is declared, then std must also be declared.

Where to find implicit std and core packages?

1. Included in forc executable

At first I thought we could potentially use std::include_str! or std::include_bytes! to include manifests and source code for std and core in the forc binary itself. This could be an easy way of ensuring std and core are always pinned with forc. However, this isn't quite feasible as sway-core performs dep module lookup via the file system during parsing, and it might be overkill to add support for "in-memory" module lookup just for core and std.

2. User forc directory

A better approach might be to install std and core under the user's forc directory. E.g.

  • ~/.forc/lib/core-<semver>
  • ~/.forc/lib/std-<semver>

where <semver> matches the version of forc installed. By synchronising the version of std and core with forc's semver version, we can ensure that the manifest used for each is always tested and valid, and makes version compatibility between each much clearer.

Ideally installing these would occur in the same step at which forc is installed, but we don't have a dedicated installer for forc just yet. In the meantime, we could provide a second fallback in the case that the local src doesn't exist, but in that case we might as well just treat them as general git dependencies as git dependencies are already cached locally.

3. As git dependencies

We could fetch core and std like regular git dependencies, pinned to forc's associated semver tag. If we address #830 at the same time and use a semver git tag to fetch both crates from the same commit at which forc was published, we can guarantee that their manifest layout will be compatible with the version of forc in use.

The downside of this approach is that users won't be able to start new projects offline. This could potentially be solved by addressing #895, in which case as long as the pinned core and std versions have been fetched at least once in any of the user's forc projects, they should then always be accessible by all other projects on the system.

This will require forc to support fetching dependencies from sub-directories of git repos, so we should address #952 first as core and std would live within sway-lib-core and sway-lib-std sub-directories of the sway repository.

How does Rust do it?

I've asked in the internals forum about how Rust handles this here, however my suspicion is that their approach might be a little more complicated than ours as I suspect they might ship std and core pre-compiled, plus both have been implicitly included since long before cargo existed, and they also have bootstrapping to consider.

Edit: It looks like they're aiming to move towards an approach similar to the User forc directory above, but currently rustc knows about them inherently for historical reasons.

Summary

For now I think we should go with the approach of moving core and std into the forc repo and refer to them via pinned git dependencies (option 3).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request forc
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

3 participants