Skip to content

Expansion-driven outline module parsing#69838

Merged
bors merged 26 commits intorust-lang:masterfrom
Centril:expand-module
Mar 19, 2020
Merged

Expansion-driven outline module parsing#69838
bors merged 26 commits intorust-lang:masterfrom
Centril:expand-module

Conversation

@Centril
Copy link
Contributor

@Centril Centril commented Mar 8, 2020

After this PR, the parser will not do any conditional compilation or loading of external module files when mod foo; is encountered. Instead, the parser only leaves mod foo; in place in the AST, with no items filled in. Expansion later kicks in and will load the actual files and do the parsing. This entails that the following is now valid:

#[cfg(FALSE)]
mod foo {
    mod bar {
        mod baz; // `foo/bar/baz.rs` doesn't exist, but no error!
    }
}

Fixes #64197.

r? @petrochenkov

@Centril Centril added T-lang Relevant to the language team relnotes Marks issues that should be documented in the release notes of the next release. labels Mar 8, 2020
@Centril Centril added this to the 1.43 milestone Mar 8, 2020
@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 8, 2020
@Centril
Copy link
Contributor Author

Centril commented Mar 8, 2020

cc @matklad

@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 8, 2020
@rust-highfive

This comment has been minimized.

@petrochenkov
Copy link
Contributor

r=me with #69838 (comment) addressed.

@rust-highfive

This comment has been minimized.

@Centril
Copy link
Contributor Author

Centril commented Mar 9, 2020

So the pretty test (src/test/pretty/issue-12590-a.rs) is failing and I'm not quite sure why it happens.

// exec-env:RUSTC_LOG=rustc_expand=debug
// rustc-env:RUST_BACKTRACE=1
// rustc-env:RUSTC_LOG=rustc_expand=debug
// compile-flags:-Ztreat-err-as-bug
// pp-exact

// The next line should not be expanded

#[path = "issue-12590-b.rs"]
mod issue_12590_b;

fn main() { }

In the same directory, there is a file (src/test/pretty/issue-12590-b.rs) whose contents are unimportant.

Running the test with results in:

---- [pretty] pretty/issue-12590-a.rs stdout ----

error: pretty-printed source does not typecheck
status: exit code: 101
command: "/home/centril/programming/rust/rust-gamma/build/x86_64-unknown-linux-gnu/stage1/bin/rustc" "-" "-Zno-codegen" "--out-dir" "/home/centril/programming/rust/rust-gamma/build/x86_64-unknown-linux-gnu/test/pretty/issue-12590-a/issue-12590-a.pretty-out" "--target=x86_64-unknown-linux-gnu" "-L" "/home/centril/programming/rust/rust-gamma/build/x86_64-unknown-linux-gnu/test/pretty" "-L" "/home/centril/programming/rust/rust-gamma/build/x86_64-unknown-linux-gnu/test/pretty/issue-12590-a/auxiliary.pretty" "-Crpath" "-O" "-Cdebuginfo=0" "-Zunstable-options" "-Lnative=/home/centril/programming/rust/rust-gamma/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-Ztreat-err-as-bug"
stdout:
------------------------------------------

------------------------------------------
stderr:
------------------------------------------
[DEBUG rustc_expand::expand] expand_crate, module #0 = ModuleData { mod_path: [rust_out#0], directory: "<anon>" }
[DEBUG rustc_expand::expand] expand_crate, module #1 = ModuleData { mod_path: [rust_out#0], directory: "" }
[DEBUG rustc_expand::module] parse_external_mod(id=issue_12590_b#0, span=Span { lo: BytePos(248), hi: BytePos(266), ctxt: 
#0 }, ownership=Owned { relative: None }, path="", attrs=[Attribute { kind: Normal(AttrItem { path: Path { span: Span { lo: BytePos(221), hi: BytePos(225), ctxt: #0 }, segments: [PathSegment { ident: path#0, id: NodeId(4294967040), args: None }] }, args: Eq(Span { lo: BytePos(226), hi: BytePos(227), ctxt: #0 }, TokenStream([(Token(Token { kind: Literal(Lit { kind: Str, symbol: "issue-12590-b.rs", suffix: None }), span: Span { lo: BytePos(228), hi: BytePos(246), ctxt: #0 } }), NonJoint)])) }), id: AttrId(0), style: Outer, span: Span { lo: BytePos(219), hi: BytePos(247), ctxt: #0 } }]
[DEBUG rustc_expand::module] parse_external_mod, mp(ownership=Owned { relative: None }, path="issue-12590-b.rs")
error: couldn't read issue-12590-b.rs: No such file or directory (os error 2)
  --> <anon>:10:1
   |
10 | mod issue_12590_b;
   | ^^^^^^^^^^^^^^^^^^

thread 'rustc' panicked at 'aborting due to `-Z treat-err-as-bug=1`', src/librustc_errors/lib.rs:901:13

and it fails on let mut p0 = new_sub_parser_from_file(sess, &mp.path, Some(id.to_string()), span);.

For debugging purposes I have added:

    log::debug!(
        "parse_external_mod(id={:?}, span={:?}, ownership={:?}, path={:?}, attrs={:?}",
        id,
        span,
        ownership,
        path,
        attrs
    );

on function entry and I have:

        log::debug!("parse_external_mod, mp(ownership={:?}, path={:?})", mp.ownership, mp.path);

        // Actually parse the external file as amodule.
        let mut p0 = new_sub_parser_from_file(sess, &mp.path, Some(id.to_string()), span);

In MacroExpander::expand_crate we have:

    pub fn expand_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
        let mut module = ModuleData {
            mod_path: vec![Ident::from_str(&self.cx.ecfg.crate_name)],
            directory: match self.cx.source_map().span_to_unmapped_path(krate.span) {
                FileName::Real(path) => path,
                other => PathBuf::from(other.to_string()),
            },
        };
        log::debug!("expand_crate, module #0 = {:?}", module);
        module.directory.pop();
        log::debug!("expand_crate, module #1 = {:?}", module);
        self.cx.root_path = module.directory.clone();
        self.cx.current_expansion.module = Rc::new(module);

I suspect there may be a deficiency in compiletest itself... investigating further.

@Centril
Copy link
Contributor Author

Centril commented Mar 9, 2020

So run_pretty_test has:

        // Finally, let's make sure it actually appears to remain valid code
        let proc_res = self.typecheck_source(actual);
        if !proc_res.status.success() {
            self.fatal_proc_rec("pretty-printed source does not typecheck", &proc_res);
        }

where actual: String (the source code, not a path). So basically we're sending the stuff to type check via stdin. For some reason (incremental stuff?) it also seems like we never actually try to parse a module when doing the type checking of actual.

@Centril
Copy link
Contributor Author

Centril commented Mar 9, 2020

Hmm, so the #12590 test is purely about pretty printing. One easy fix which would make the PR green is to use // pretty-compare-only -- but do we think that would be correct? cc also @eddyb

@Centril Centril added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Mar 9, 2020
@Centril
Copy link
Contributor Author

Centril commented Mar 10, 2020

Hmm, so the #12590 test is purely about pretty printing. One easy fix which would make the PR green is to use // pretty-compare-only -- but do we think that would be correct? [...]

@petrochenkov I've done this in 42ab820 but would like feedback on it before r=you-ing.

@eddyb
Copy link
Member

eddyb commented Mar 10, 2020

Using stdin seems odd, maybe compiletest should set the cwd of the rustc process it runs to the directory of the test, which might make file loading work correctly.

// pretty-compare-only seems like the appropriate workaround, in any case.

@Centril
Copy link
Contributor Author

Centril commented Mar 10, 2020

// pretty-compare-only seems like the appropriate workaround, in any case.

Alright; then let's do: @bors r=petrochenkov,eddyb

@bors
Copy link
Collaborator

bors commented Mar 10, 2020

📌 Commit 42ab820 has been approved by petrochenkov,eddyb

@bors
Copy link
Collaborator

bors commented Mar 10, 2020

🌲 The tree is currently closed for pull requests below priority 1000, this pull request will be tested once the tree is reopened

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 10, 2020
Centril added a commit to Centril/rust that referenced this pull request Mar 10, 2020
…ov,eddyb

Expansion-driven outline module parsing

After this PR, the parser will not do any conditional compilation or loading of external module files when `mod foo;` is encountered. Instead, the parser only leaves `mod foo;` in place in the AST, with no items filled in. Expansion later kicks in and will load the actual files and do the parsing. This entails that the following is now valid:

```rust
#[cfg(FALSE)]
mod foo {
    mod bar {
        mod baz; // `foo/bar/baz.rs` doesn't exist, but no error!
    }
}
```

Fixes rust-lang#64197.

r? @petrochenkov
Centril added a commit to Centril/rust that referenced this pull request Mar 10, 2020
…ov,eddyb

Expansion-driven outline module parsing

After this PR, the parser will not do any conditional compilation or loading of external module files when `mod foo;` is encountered. Instead, the parser only leaves `mod foo;` in place in the AST, with no items filled in. Expansion later kicks in and will load the actual files and do the parsing. This entails that the following is now valid:

```rust
#[cfg(FALSE)]
mod foo {
    mod bar {
        mod baz; // `foo/bar/baz.rs` doesn't exist, but no error!
    }
}
```

Fixes rust-lang#64197.

r? @petrochenkov
bors added a commit to rust-lang/rust-clippy that referenced this pull request Mar 19, 2020
Rollup of 4 pull requests

Successful merges:

 - #5326 (rustup rust-lang/rust#69838)
 - #5333 (rustup rust-lang/rust#69189)
 - #5336 (rustup rust-lang/rust#69920)
 - #5341 (Rustup to rust-lang/rust#66131)

Failed merges:

r? @ghost

changelog: none
bors added a commit to rust-lang/rust-clippy that referenced this pull request Mar 19, 2020
Rollup of 4 pull requests

Successful merges:

 - #5326 (rustup rust-lang/rust#69838)
 - #5333 (rustup rust-lang/rust#69189)
 - #5336 (rustup rust-lang/rust#69920)
 - #5341 (Rustup to rust-lang/rust#66131)

Failed merges:

r? @ghost

changelog: none
bors added a commit to rust-lang/rust-clippy that referenced this pull request Mar 19, 2020
Rollup of 4 pull requests

Successful merges:

 - #5326 (rustup rust-lang/rust#69838)
 - #5333 (rustup rust-lang/rust#69189)
 - #5336 (rustup rust-lang/rust#69920)
 - #5341 (Rustup to rust-lang/rust#66131)

Failed merges:

r? @ghost

changelog: none
bors added a commit to rust-lang/rust-clippy that referenced this pull request Mar 19, 2020
Rollup of 4 pull requests

Successful merges:

 - #5326 (rustup rust-lang/rust#69838)
 - #5333 (rustup rust-lang/rust#69189)
 - #5336 (rustup rust-lang/rust#69920)
 - #5341 (Rustup to rust-lang/rust#66131)

Failed merges:

r? @ghost

changelog: none
};
let directory_ownership = DirectoryOwnership::Owned { relative: None };
let p = new_sub_parser_from_file(cx.parse_sess(), &file, directory_ownership, None, sp);
let p = new_sub_parser_from_file(cx.parse_sess(), &file, None, sp);
Copy link
Member

@eddyb eddyb Mar 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This apparently broke Servo's script crate, or at least the copy on perf.rust-lang.org.
cc @Mark-Simulacrum can you post some details?

IIUC, this can't be fixed locally either, because the mod bar; parsed by include!("directory/included.rs"); will be expanded later, so for expanding mod bar; to load directory/bar.rs (which is apparently the old behavior? how are we not testing for it), we'd need to detect that an include! happened, or something similar.

EDIT: adjusted example to fit @Mark-Simulacrum's reproduction.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a minimal reproduction:

$ tree .
.
|-- directory
|   |-- bar.rs
|   `-- included.rs
`-- foo.rs
// foo.rs
include!("directory/included.rs");

fn main() {}

// directory/included.rs
mod bar;

// directory/bar.rs
// empty
$ rustc +3c6f982cc908aacc39c3ac97f31c989f81cc213c foo.rs
error[E0583]: file not found for module `bar`
 --> directory/included.rs:1:1
  |
1 | mod bar;
  | ^^^^^^^^
  |
  = help: to create the module `bar`, create file "bar.rs"

error: aborting due to previous error

For more information about this error, try `rustc --explain E0583`.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just recalled a related issue - #58818.
Could you check whether this PR fixed it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we'd need to detect that an include! happened, or something similar.

FWIW, we have Definitions::expansions_that_defined that can link from the mod bar; item to the macro that produced it. Then we have ExpnData::parent that can link from that macro to the macro that produced it (recursively).

Perhaps using these data we can hack up something reproducing the old behavior.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can only detect include comparing the macro's name in ExpnData with sym::include.
fn expansion_cause used in for a bunch of various stuff also hard-codes the name include like this, so it should be ok for now.

(The proper fix is a flag in struct SyntaxExtension, other file-including built-in macros should have it as well.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@petrochenkov So I tried two different approaches to set ownership before loading the external module. The first one was adding Incovation::is_current_expansion_macro_named defined like so:

    fn is_current_expansion_macro_named(&self, sym: Symbol) -> bool {
        let mut curr = self.cx.current_expansion.id;
        loop {
            let expn_data = curr.expn_data();
            if expn_data.kind == ExpnKind::Macro(MacroKind::Bang, sym) {
                // Stop going up the backtrace once `sym` is encountered.
                return true;
            }
            if expn_data.is_root() {
                // Reached root, need to bail to ensure termination.
                return false;
            }
            curr = expn_data.call_site.ctxt().outer_expn();
        }
    }

and then using it in flat_map_item before parse_external_mod happens:

                let pushed = &mut false; // Record `parse_external_mod` pushing so we can pop.
                let mut dir = Directory { ownership: orig_ownership, path: module.directory };

                if self.is_current_expansion_macro_named(sym::include) {
                    log::debug!("flat_map_item, is_current_expansion_macro_named = true");
                    dir.ownership = DirectoryOwnership::Owned { relative: None };
                }

The log message here does trigger on @Mark-Simulacrum's regression test, but this doesn't fix the issue.

I also tweaked SyntaxExtension, adding a flag foobar: bool which is used in fully_expand_fragment:

            let (expanded_fragment, new_invocations) = match res {
                InvocationRes::Single(ext) => match self.expand_invoc(invoc, &ext.kind) {
                    ExpandResult::Ready(fragment) => {
                        if ext.foobar {
                            self.cx.current_expansion.directory_ownership =
                                DirectoryOwnership::Owned { relative: None };
                            log::debug!("fully_expand_fragment, using foobar");
                        }
                        self.collect_invocations(fragment, &[])

and which is set in compile_macro:

        if result.is_builtin {
            // The macro was marked with `#[rustc_builtin_macro]`.
            if let Some(ext) = self.builtin_macros.remove(&item.ident.name) {
                // The macro is a built-in, replace its expander function
                // while still taking everything else from the source code.
                result.kind = ext.kind;

                if item.ident.name == sym::include {
                    result.foobar = true;
                    log::debug!("compile_macro, setting foobar");
                }

The log message also triggers here, but also does nothing to fix the issue, as the approach is the same as the other mechanism.

I'm not sure why it doesn't work. :(

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found a fix, PR up at #70184.

Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Mar 21, 2020
…etrochenkov

expand_include: set `.directory` to dir of included file.

Resolves the regression noted in rust-lang#69838.

r? @petrochenkov
cc @eddyb @Mark-Simulacrum
Centril added a commit to Centril/rust that referenced this pull request Mar 21, 2020
…etrochenkov

expand_include: set `.directory` to dir of included file.

Resolves the regression noted in rust-lang#69838.

r? @petrochenkov
cc @eddyb @Mark-Simulacrum
Centril added a commit to Centril/rust that referenced this pull request Mar 21, 2020
…etrochenkov

expand_include: set `.directory` to dir of included file.

Resolves the regression noted in rust-lang#69838.

r? @petrochenkov
cc @eddyb @Mark-Simulacrum
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Jun 8, 2020
Pkgsrc changes:
 * Remove a couple diffs which are now integrated upstream.
 * Adjust cargo checksums after upstream upgrades.
 * Belatedly bump the curl dependency
 * Unset DESTDIR during the build phase, to work around a mysterious
   build bug deep in the bowels of llvm.
 * Bump nearly all bootstraps to 1.43.1.

Upstream changes:

Version 1.44.0 (2020-06-04)
==========================

Language
--------
- [You can now use `async/.await` with `#[no_std]` enabled.][69033]
- [Added the `unused_braces` lint.][70081]

**Syntax-only changes**

- [Expansion-driven outline module parsing][69838]
```rust
#[cfg(FALSE)]
mod foo {
    mod bar {
        mod baz; // `foo/bar/baz.rs` doesn't exist, but no error!
    }
}
```

These are still rejected semantically, so you will likely receive an error but
these changes can be seen and parsed by macros and conditional compilation.

Compiler
--------
- [Rustc now respects the `-C codegen-units` flag in incremental mode.][70156]
  Additionally when in incremental mode rustc defaults to 256 codegen units.
- [Refactored `catch_unwind`, to have zero-cost unless unwinding is enabled and
  a panic is thrown.][67502]
- [Added tier 3\* support for the `aarch64-unknown-none` and
  `aarch64-unknown-none-softfloat` targets.][68334]
- [Added tier 3 support for `arm64-apple-tvos` and
  `x86_64-apple-tvos` targets.][68191]

Libraries
---------
- [Special cased `vec![]` to map directly to `Vec::new()`.][70632] This allows
  `vec![]` to be able to be used in `const` contexts.
- [`convert::Infallible` now implements `Hash`.][70281]
- [`OsString` now implements `DerefMut` and `IndexMut` returning
  a `&mut OsStr`.][70048]
- [Unicode 13 is now supported.][69929]
- [`String` now implements `From<&mut str>`.][69661]
- [`IoSlice` now implements `Copy`.][69403]
- [`Vec<T>` now implements `From<[T; N]>`.][68692] Where `N` is less than 32.
- [`proc_macro::LexError` now implements `fmt::Display` and `Error`.][68899]
- [`from_le_bytes`, `to_le_bytes`, `from_be_bytes`, `to_be_bytes`,
  `from_ne_bytes`, and `to_ne_bytes` methods are now `const` for all
  integer types.][69373]

Stabilized APIs
---------------
- [`PathBuf::with_capacity`]
- [`PathBuf::capacity`]
- [`PathBuf::clear`]
- [`PathBuf::reserve`]
- [`PathBuf::reserve_exact`]
- [`PathBuf::shrink_to_fit`]
- [`f32::to_int_unchecked`]
- [`f64::to_int_unchecked`]
- [`Layout::align_to`]
- [`Layout::pad_to_align`]
- [`Layout::array`]
- [`Layout::extend`]

Cargo
-----
- [Added the `cargo tree` command which will print a tree graph of
  your dependencies.][cargo/8062] E.g.
  ```
    mdbook v0.3.2 (/Users/src/rust/mdbook)
  +-- ammonia v3.0.0
  |   +-- html5ever v0.24.0
  |   |   +-- log v0.4.8
  |   |   |   +-- cfg-if v0.1.9
  |   |   +-- mac v0.1.1
  |   |   +-- markup5ever v0.9.0
  |   |       +-- log v0.4.8 (*)
  |   |       +-- phf v0.7.24
  |   |       |   +-- phf_shared v0.7.24
  |   |       |       +-- siphasher v0.2.3
  |   |       |       +-- unicase v1.4.2
  |   |       |           [build-dependencies]
  |   |       |           +-- version_check v0.1.5
  ...
  ```
  You can also display dependencies on multiple versions of the same crate with
  `cargo tree -d` (short for `cargo tree --duplicates`).

Misc
----
- [Rustdoc now allows you to specify `--crate-version` to have rustdoc include
  the version in the sidebar.][69494]

Compatibility Notes
-------------------
- [Rustc now correctly generates static libraries on Windows GNU targets with
  the `.a` extension, rather than the previous `.lib`.][70937]
- [Removed the `-C no_integrated_as` flag from rustc.][70345]
- [The `file_name` property in JSON output of macro errors now points the actual
  source file rather than the previous format of `<NAME macros>`.][70969]
  **Note:** this may not point a file that actually exists on the user's system.
- [The minimum required external LLVM version has been bumped to LLVM 8.][71147]
- [`mem::{zeroed, uninitialised}` will now panic when used with types that do
  not allow zero initialization such as `NonZeroU8`.][66059] This was
  previously a warning.
- [In 1.45.0 (the next release) converting a `f64` to `u32` using the `as`
  operator has been defined as a saturating operation.][71269] This was
  previously undefined behaviour, you can use the `{f64, f32}::to_int_unchecked`
  methods to continue using the current behaviour which may desirable in rare
  performance sensitive situations.

Internal Only
-------------
These changes provide no direct user facing benefits, but represent significant
improvements to the internals and overall performance of rustc and
related tools.

- [dep_graph Avoid allocating a set on when the number reads are small.][69778]
- [Replace big JS dict with JSON parsing.][71250]

[69373]: rust-lang/rust#69373
[66059]: rust-lang/rust#66059
[68191]: rust-lang/rust#68191
[68899]: rust-lang/rust#68899
[71147]: rust-lang/rust#71147
[71250]: rust-lang/rust#71250
[70937]: rust-lang/rust#70937
[70969]: rust-lang/rust#70969
[70632]: rust-lang/rust#70632
[70281]: rust-lang/rust#70281
[70345]: rust-lang/rust#70345
[70048]: rust-lang/rust#70048
[70081]: rust-lang/rust#70081
[70156]: rust-lang/rust#70156
[71269]: rust-lang/rust#71269
[69838]: rust-lang/rust#69838
[69929]: rust-lang/rust#69929
[69661]: rust-lang/rust#69661
[69778]: rust-lang/rust#69778
[69494]: rust-lang/rust#69494
[69403]: rust-lang/rust#69403
[69033]: rust-lang/rust#69033
[68692]: rust-lang/rust#68692
[68334]: rust-lang/rust#68334
[67502]: rust-lang/rust#67502
[cargo/8062]: rust-lang/cargo#8062
[`PathBuf::with_capacity`]: https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.with_capacity
[`PathBuf::capacity`]: https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.capacity
[`PathBuf::clear`]: https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.clear
[`PathBuf::reserve`]: https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.reserve
[`PathBuf::reserve_exact`]: https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.reserve_exact
[`PathBuf::shrink_to_fit`]: https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.shrink_to_fit
[`f32::to_int_unchecked`]: https://doc.rust-lang.org/std/primitive.f32.html#method.to_int_unchecked
[`f64::to_int_unchecked`]: https://doc.rust-lang.org/std/primitive.f64.html#method.to_int_unchecked
[`Layout::align_to`]: https://doc.rust-lang.org/std/alloc/struct.Layout.html#method.align_to
[`Layout::pad_to_align`]: https://doc.rust-lang.org/std/alloc/struct.Layout.html#method.pad_to_align
[`Layout::array`]: https://doc.rust-lang.org/std/alloc/struct.Layout.html#method.array
[`Layout::extend`]: https://doc.rust-lang.org/std/alloc/struct.Layout.html#method.extend
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

relnotes Marks issues that should be documented in the release notes of the next release. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-lang Relevant to the language team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consider moving out-of-line module loading from parser to expansion

8 participants