Skip to content

Commit

Permalink
Merge branch 'main' into rebuild-platform
Browse files Browse the repository at this point in the history
  • Loading branch information
lukewilliamboswell committed Jul 3, 2024
2 parents ef364f3 047453c commit cd13762
Show file tree
Hide file tree
Showing 75 changed files with 2,641 additions and 5,659 deletions.
58 changes: 35 additions & 23 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 2,22 @@

## Code of Conduct

We are committed to providing a friendly, safe and welcoming environment for all. Make sure to take a look at the [Code of Conduct](CODE_OF_CONDUCT.md)!
We are committed to providing a friendly, safe and welcoming environment for all. See our [Code of Conduct](CODE_OF_CONDUCT.md) for details.

## How to contribute

All contributions are appreciated! Typo fixes, bug fixes, feature requests,
bug reports are all helpful for the project.
bug reports...

If you are looking for a good place to start, consider reaching out on the `#contributing` channel on [Roc Zulip][roc-zulip].
Before making your first pull request, definitely talk to an existing contributor on [Roc Zulip][roc-zulip] first about what you plan to do! This can not only avoid duplicated effort, it can also avoid making a whole PR only to discover it won't be accepted because the change doesn't fit with the goals of the language's design or implementation.
For ideas, proposals and feature request, [click here](https://www.roc-lang.org/community#ideas), for all other contributions, read on.

For a good place to start, check out [good first issues](https://github.com/roc-lang/roc/issues?q=is:open is:issue label:"good first issue") or reach out on the `#contributing` channel on [our zulip group chat][roc-zulip].
Before making your first pull request, talk to an existing contributor on [zulip][roc-zulip] about what you plan to do! This can avoid duplicated effort or a rejection because the change doesn't fit with the goals of the language.

If you are interested in larger, implementation- or research-heavy projects
related to Roc, check out [Roc Project Ideas][project-ideas] and reach out to us
on Zulip! These projects may be suitable for academic theses, independent
research, or even just valuable projects to learn from and improve Roc with.
on [zulip][roc-zulip]! These projects may be suitable for academic theses, internships,
independent research, or just valuable projects to learn from and improve Roc with.

## Building from Source

Expand All @@ -33,29 35,35 @@ cargo clippy --workspace --tests -- --deny warnings

Execute `cargo fmt --all` to fix the formatting.

## Generating Docs

If you make changes to [Roc's Standard Library](https://www.roc-lang.org/builtins/Str), you can add comments to the code following [the CommonMark Spec](https://spec.commonmark.org/current/) to further explain your intentions. You can view these changes locally with:

```sh
cargo run docs crates/compiler/builtins/roc/main.roc
```

This command will generate the documentation in the [`generated-docs`](generated-docs) directory.

## Contribution Tips

- If you've never made a pull request on github before, [this](https://www.freecodecamp.org/news/how-to-make-your-first-pull-request-on-github-3/) will be a good place to start.
- Create an issue if the purpose of a struct/field/type/function/... is not immediately clear from its name or nearby comments.
- You can find good first issues [here][good-first-issues]. Once you have gained some experience you can take a look at the [intermediate issues](https://github.com/roc-lang/roc/issues?q=is:open is:issue label:"intermediate issue").
- [Fork](https://github.com/roc-lang/roc/fork) the repo so that you can apply your changes first on your own copy of the roc repo.
- It's a good idea to open a draft pull request as you begin working on something. This way, others can see that you're working on it, which avoids duplicate effort, and others can give feedback sooner rather than later if they notice a problem in the direction things are going. Click the button "ready for review" when it's ready.
- It's a good idea to open a draft pull request as you begin working on something. This way, others can see that you're working on it, which avoids duplicate effort, and others can give important feedback sooner rather than later. Click the button "ready for review" when it's ready.
- The [compiler's README](https://github.com/roc-lang/roc/tree/main/crates/compiler) contains important info.
- The AI chat in the [cursor editor](https://www.cursor.com/) can also help you find your way in the codebase.

<details>
<summary>:beetle: Debugging Tips</summary>

- At the bottom of [.cargo/config.toml](https://github.com/roc-lang/roc/blob/main/.cargo/config.toml) we have useful debug flags that activate certain debug prints.
- For Roc code; minimize the code that produces the issue.
- For segmentation faults:
In general we recommend using linux to investigate, it has better tools for this.
Use `roc build myApp.roc --linker=legacy` followed by `valgrind ./myApp`.
Use gdb to step through the code, [this gdb script](https://roc.zulipchat.com/#narrow/stream/395097-compiler-development/topic/gdb.20script/near/424422545) can be helpful.
Inspect the generated LLVM IR (`roc build myApp.roc --emit-llvm-ir`) between Roc code that encounters the segfault and code that doesn't.


</details>

### Commit signing

All your commits need to be signed [to prevent impersonation](https://dev.to/martiliones/how-i-got-linus-torvalds-in-my-contributors-on-github-3k4g). Check out [our guide for commit signing](devtools/signing.md).
All your commits need to be signed [to prevent impersonation](https://dev.to/martiliones/how-i-got-linus-torvalds-in-my-contributors-on-github-3k4g).
Check out [our guide for commit signing](devtools/signing.md).

#### Commit signing on NixOS
<details>
<summary>⚠️ Tip for NixOS users</summary>

On NixOS pinentry can cause problems, the following setup works well for those with a KDE desktop. From `/etc/nixos/configuration.nix`:
```
Expand All @@ -65,8 73,10 @@ programs.gnupg.agent = {
enableSSHSupport = true;
};
```
</details>

### Forgot to sign commits?
<details>
<summary>Forgot to sign commits?</summary>

You can view your commits on github, those without the "Verified" badge still need to be signed.
If any of those is a merge commit, follow [these steps](https://stackoverflow.com/a/9958215/4200103) instead of the ones below.
Expand All @@ -88,9 98,11 @@ In case you have multiple commits, you can sign them in two ways:

If you already pushed unsigned commits, you may have to do a force push with `git push origin -f <branch_name>`.

</details>

## Can we do better?

Feel free to open an issue if you think this document can be improved or is unclear in any way.
Feel free to open an issue if you think this document can be improved!

[roc-zulip]: https://roc.zulipchat.com
[good-first-issues]: https://github.com/roc-lang/roc/issues?q=is:open is:issue label:"good first issue"
Expand Down
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 9,7 @@
- [**faq**: frequently asked questions](https://github.com/roc-lang/roc/blob/main/www/content/faq.md)
- [**group chat**](https://roc.zulipchat.com) for help, questions and discussions

If you'd like to contribute, check out [good first issues](https://github.com/roc-lang/roc/issues?q=is:open is:issue label:"good first issue"). Don't hesitate to ask for help on our [group chat](https://roc.zulipchat.com), we're friendly!
If you'd like to contribute, [get started here](CONTRIBUTING.md). Don't hesitate to ask for help on our [group chat](https://roc.zulipchat.com), we're friendly!

## Sponsors

Expand All @@ -35,6 35,8 @@ If you would like your company to become a corporate sponsor of Roc's developmen

We'd also like to express our gratitude to our generous [individual sponsors](https://github.com/sponsors/roc-lang/)! A special thanks to those sponsoring $25/month or more:

- [Barry Moore](https://github.com/chiroptical)
- Eric Andresen
- [Jackson Lucky](https://github.com/jluckyiv)
- [Agus Zubiaga](https://github.com/agu-z)
- [Angelo Ceccato](https://github.com/AngeloChecked)
Expand Down
48 changes: 25 additions & 23 deletions crates/cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1106,28 1106,26 @@ fn roc_run_native<I: IntoIterator<Item = S>, S: AsRef<OsStr>>(
) -> std::io::Result<i32> {
use bumpalo::collections::CollectIn;

unsafe {
let executable = roc_run_executable_file_path(binary_bytes)?;
let (argv_cstrings, envp_cstrings) = make_argv_envp(arena, &executable, args);
let executable = roc_run_executable_file_path(binary_bytes)?;
let (argv_cstrings, envp_cstrings) = make_argv_envp(arena, &executable, args);

let argv: bumpalo::collections::Vec<*const c_char> = argv_cstrings
.iter()
.map(|s| s.as_ptr())
.chain([std::ptr::null()])
.collect_in(arena);
let argv: bumpalo::collections::Vec<*const c_char> = argv_cstrings
.iter()
.map(|s| s.as_ptr())
.chain([std::ptr::null()])
.collect_in(arena);

let envp: bumpalo::collections::Vec<*const c_char> = envp_cstrings
.iter()
.map(|s| s.as_ptr())
.chain([std::ptr::null()])
.collect_in(arena);
let envp: bumpalo::collections::Vec<*const c_char> = envp_cstrings
.iter()
.map(|s| s.as_ptr())
.chain([std::ptr::null()])
.collect_in(arena);

match opt_level {
OptLevel::Development => roc_dev_native(arena, executable, argv, envp, expect_metadata),
OptLevel::Normal | OptLevel::Size | OptLevel::Optimize => {
roc_run_native_fast(executable, &argv, &envp);
}
}
match opt_level {
OptLevel::Development => roc_dev_native(arena, executable, argv, envp, expect_metadata),
OptLevel::Normal | OptLevel::Size | OptLevel::Optimize => unsafe {
roc_run_native_fast(executable, &argv, &envp);
},
}

Ok(1)
Expand Down Expand Up @@ -1214,14 1212,11 @@ fn roc_dev_native(
layout_interner,
} = expect_metadata;

// let shm_name =
let shm_name = format!("/roc_expect_buffer_{}", std::process::id());
let mut memory = ExpectMemory::create_or_reuse_mmap(&shm_name);

let layout_interner = layout_interner.into_global();

let mut writer = std::io::stdout();

match unsafe { libc::fork() } {
0 => unsafe {
// we are the child
Expand Down Expand Up @@ -1253,9 1248,16 @@ fn roc_dev_native(
let options = 0;
unsafe { libc::waitpid(pid, &mut status, options) };

break status;
// if `WIFEXITED` returns false, `WEXITSTATUS` will just return junk
break if libc::WIFEXITED(status) {
libc::WEXITSTATUS(status)
} else {
// we don't have an exit code, so we probably shouldn't make one up
0
};
}
ChildProcessMsg::Expect => {
let mut writer = std::io::stdout();
roc_repl_expect::run::render_expects_in_memory(
&mut writer,
arena,
Expand Down
12 changes: 3 additions & 9 deletions crates/compiler/build/src/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1013,20 1013,14 @@ fn link_linux(
LinkType::Executable => (
// Presumably this S stands for Static, since if we include Scrt1.o
// in the linking for dynamic builds, linking fails.
vec![scrt1_path_str.to_string()],
[scrt1_path_str.as_ref()],
output_path,
),
LinkType::Dylib => {
let mut output_path = output_path;
output_path.set_extension("so");

(
// TODO: find a way to avoid using a vec! here - should theoretically be
// able to do this somehow using &[] but the borrow checker isn't having it.
// Also find a way to have these be string slices instead of Strings.
vec!["-shared".to_string()],
output_path,
)
(["-shared"], output_path)
}
LinkType::None => internal_error!("link_linux should not be called with link type of none"),
};
Expand Down Expand Up @@ -1057,7 1051,7 @@ fn link_linux(
&crti_path_str,
&crtn_path_str,
])
.args(&base_args)
.args(base_args)
.args(["-dynamic-linker", ld_linux_path_str])
.args(input_paths)
.args(extra_link_flags())
Expand Down
1 change: 0 additions & 1 deletion crates/compiler/builtins/roc/main.roc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 10,5 @@ package [
Encode,
Hash,
Box,
TotallyNotJson,
Inspect,
] {}
2 changes: 0 additions & 2 deletions crates/compiler/builtins/src/roc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 16,6 @@ pub fn module_source(module_id: ModuleId) -> &'static str {
ModuleId::DECODE => DECODE,
ModuleId::HASH => HASH,
ModuleId::INSPECT => INSPECT,
ModuleId::JSON => JSON,
_ => internal_error!(
"ModuleId {:?} is not part of the standard library",
module_id
Expand All @@ -36,4 35,3 @@ const ENCODE: &str = include_str!("../roc/Encode.roc");
const DECODE: &str = include_str!("../roc/Decode.roc");
const HASH: &str = include_str!("../roc/Hash.roc");
const INSPECT: &str = include_str!("../roc/Inspect.roc");
const JSON: &str = include_str!("../roc/TotallyNotJson.roc");
22 changes: 0 additions & 22 deletions crates/compiler/can/src/desugar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -755,28 755,6 @@ pub fn desugar_expr<'a>(
})
}

// Replace an empty final def with a `Task.ok {}`
EmptyDefsFinal => {
let mut apply_args: Vec<&'a Loc<Expr<'a>>> = Vec::new_in(arena);
apply_args
.push(arena.alloc(Loc::at(loc_expr.region, Expr::Record(Collection::empty()))));

arena.alloc(Loc::at(
loc_expr.region,
Expr::Apply(
arena.alloc(Loc::at(
loc_expr.region,
Expr::Var {
module_name: ModuleName::TASK,
ident: "ok",
},
)),
arena.alloc(apply_args),
CalledVia::BangSuffix,
),
))
}

// note this only exists after desugaring
LowLevelDbg(_, _, _) => loc_expr,
}
Expand Down
6 changes: 1 addition & 5 deletions crates/compiler/can/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -621,9 621,6 @@ pub fn canonicalize_expr<'a>(
use Expr::*;

let (expr, output) = match expr {
&ast::Expr::EmptyDefsFinal => {
internal_error!("EmptyDefsFinal should have been desugared")
}
&ast::Expr::Num(str) => {
let answer = num_expr_from_result(var_store, finish_parsing_num(str), region, env);

Expand Down Expand Up @@ -2392,8 2389,7 @@ pub fn is_valid_interpolation(expr: &ast::Expr<'_>) -> bool {
| ast::Expr::Backpassing(_, _, _)
| ast::Expr::SpaceBefore(_, _)
| ast::Expr::Str(StrLiteral::Block(_))
| ast::Expr::SpaceAfter(_, _)
| ast::Expr::EmptyDefsFinal => false,
| ast::Expr::SpaceAfter(_, _) => false,
// These can contain subexpressions, so we need to recursively check those
ast::Expr::Str(StrLiteral::Line(segments)) => {
segments.iter().all(|segment| match segment {
Expand Down
9 changes: 7 additions & 2 deletions crates/compiler/can/src/pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 207,7 @@ pub struct ListPatterns {
/// [ .., A, B ] -> patterns = [A, B], rest = 0
/// [ A, .., B ] -> patterns = [A, B], rest = 1
/// [ A, B, .. ] -> patterns = [A, B], rest = 2
pub opt_rest: Option<(usize, Option<Symbol>)>,
pub opt_rest: Option<(usize, Option<Loc<Symbol>>)>,
}

impl ListPatterns {
Expand Down Expand Up @@ -793,7 793,8 @@ pub fn canonicalize_pattern<'a>(
pattern_as.identifier.value,
) {
Ok(symbol) => {
rest_name = Some(symbol);
rest_name =
Some(Loc::at(pattern_as.identifier.region, symbol));
}
Err(pattern) => {
opt_erroneous = Some(pattern);
Expand Down Expand Up @@ -997,6 998,10 @@ impl<'a> BindingsFromPattern<'a> {
| OpaqueNotInScope(..) => (),
List { patterns, .. } => {
stack.extend(patterns.patterns.iter().rev().map(Pattern));

if let Some((_, Some(rest_sym))) = &patterns.opt_rest {
return Some((rest_sym.value, rest_sym.region));
}
}
}
}
Expand Down
Loading

0 comments on commit cd13762

Please sign in to comment.