# 2022-01-20 ## Today's plan ### Idea * Niko explains some interesting things (15 minutes) * Experimental period (15 minutes): * Come up with a working theory for how things work * Come up with 2 or 3 interesting examples * Sharing period (30 minutes): * Read people's examples * Niko picks one and * Reading period (15 minutes): * Try to trace through the code for that example * Can use a pernosco link that Niko prepares ### Next session * Resume from one of these examples * Trace through the code * Niko will have a pernosco link prepared ## Notes ### Niko <details> <summary>all</summary> A: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=0676b4a1a40fff205dd7ebe2282f0b2d -- when/where/how do we detect this error? B: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=1e5229e795f2bde67e2afe6332f64b60 C: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=2e3eeb0c8542bf7cd036ca16b3232ba5 glob + macro-generated item that relies on glob errors out at `use b::foo`: D: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=9fe12f62c17dbdd91b63a00a50ca7580 explicit use + macro-generated item that relies on that path *also* errors out at `use b::foo`: E: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=d34fea87c08b62054c8ab7d13915715f above examples turn out to be hygiene related: F: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=238538ccc02fbc55af3d30e9ebf5c711 obvious error: G: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=1b32ae8863106bd86fdf1d12b1c41da2 explicit use + macro-generated item resolves to `b::foo`: H: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=0139155e189738fabee23b1029d580c7 glob + macro-generated item *also* resolves to `b::foo`: I: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=964e01a30dbb0a8ceef08630243dfce1 macros generating macros: J: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=bcbd9d8dd8fc46a37a8f0b4126211e12 injecting a use: K: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=d4002eedab5de91d9af146b275e6dc8d injecting a use, no shadow: L: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=8c4d640f80a72d50a343a6b1da08503a use of a (private) use M: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=21a02f8ca3412eee4acb74b43f30f38b </details> (below samples are taken from above character labelled list) use of a (private) use M: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=21a02f8ca3412eee4acb74b43f30f38b * Note from pnkfelix: I don't think the linked example is complete. It references an `inject_use!` macro that is not in the given source code, presumably the one from the example labelled 'K' glob + macro-generated item *also* resolves to `b::foo`: I: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=964e01a30dbb0a8ceef08630243dfce1 injecting a use: K: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=d4002eedab5de91d9af146b275e6dc8d ### metajack - are there multiple priority levels? or just explicit and low - if all resolutions are ambiguous, it is an error: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=4ed9794cbcb1b67e2dec7711b518a54a - why doesn't this work? https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=76e62533017556662afce760b47107ba or this: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=dc8447b001da15401e1ea7ecac04dcc4 - ambiguity kind is GlobVsGlob: https://github.com/rust-lang/rust/blob/master/compiler/rustc_resolve/src/lib.rs#L749 - error comes from https://github.com/rust-lang/rust/blob/master/compiler/rustc_resolve/src/diagnostics.rs#L1224 `report_ambiguity_error()` called from `report_errors()` https://github.com/rust-lang/rust/blob/master/compiler/rustc_resolve/src/lib.rs#L2964 called from `resolve_crate()` - ambiguity errors are created at https://github.com/rust-lang/rust/blob/master/compiler/rustc_resolve/src/lib.rs#L1692 inside `record_use()` - the ambiguity is stored in `NameBinding.ambiguity` - `record_use()` called from `resolve_main()` and `extern_prelude_get()`. - what calls `extern_prelude_get()`? ### forest - Walking through this "loop", how can I think of precedence of macros vs imports? <-- note that you can import from crates on play I got one to compile! (deeper nesting of crates) https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=8638adbaac70b8e0ee7a1eeb4612e477 Same as above, but I get to import everything https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=7b4226c03d5ab5f69bc31d5e55c840f6 Trying to just import in modules directly https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=7e87a8662967caca5ff63837605e705d Surprisingly, my original code works when I call all functions foo? https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=5571c06a7e43b9ba6dee0ed84ecd6243 Trying to clean stuff up, but it's not working just yet (too many glob imports) https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=0318519b807f1e033885c11e039c3042 Cleaned up https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=2b1f8911ec5a91d873a23e777a831113 **key examples** Using crates inside of the macro (cleaned up version): https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=54a0f01c3832f9c370bebda0c4475ba8 ### Olivia Seems to resolve the latest use https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=7303f57de07e65c78b826adc37ef7621 Traits collide with structs, kind of what I expected https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=8b4d838c3952c11e005883014e17f31b Functions and structs/traits do not collide, not what I expected https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=728b89c02bb39aced1731b15d53aaabd https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6c4837d58f5147ddd1c1f42dacdb2f10 what happens when you use two globs https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=5f1159a9a064b38a5c7061cb6ba0f5a1 ### Santiago Pastorino Was expecting ambiguous and indeed we get ambiguous ... https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=c9c4938e035a1176d3f4bb3b235625cd Same thing using macros ... https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6990c9a5da0238047b0146e5cd8789f7 It works if you're explicit ... https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=68d2c804bbb8dc53f02eb49bdfd14c55 What should happen here? ... https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=55de697cb4a28f7f5fbfb52b8f741fe6 ### rémy The macros namespace is kinda "last come first served" https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=73416ad63ddb9ea890ccb0cfd94c48ce but not when the duplicate names come from macro expansion ? https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b99bbf676dc9d64d8ea651e2252e4651 is now ambiguous, but the "amount" of expansion matters here only. Modules seem to have the same glob vs explicit import priority mechanism https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=dc301bb7689f92baab65683382512586 ### Sean `b::foo` resolves based on what is passed into `crate::c::m!`? ``` pub mod b { crate::c::m!(foo); } ``` This fails to compile: ``` pub mod b { crate::c::m!(blah); } ``` Ah, never mind, it makes sense. It was just weird to me at first that the module was resolving based off of what is being passed into the macro. ## Niko's plan Start with this simple case of ambiguity: N1: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ab7fab835eb45e899af54b7aaf3cf00f Add in macro-rules: N2: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=a848d5f22fcaf5fc9c2766b2f6e04043 Add in pub macro instead: N3: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=e8bbf0dfe6e444d9ff99e5959e067eda Add in hygiene: N4: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=5066bd6e137e7624401d1bd2ef6f1b11 ## Do the read * Find where the error is generated * `RUST_BACKTRACE=1 rustc +nightly -Ztreat-err-as-bug foo.rs` * Read the context and note a few things that you find interesting * e.g., a hunch at how the data structure works * something about the names * etc ### Niko * Interesting points: * [`record_use`](https://github.com/rust-lang/rust/blob/74fbbefea8d13683cca5eee62e4740706cb3144a/compiler/rustc_resolve/src/lib.rs#L1685) * So where is the call where `used_binding.ambiguity` is some? * Pernosco would be helpful! * probably `try_resolve_as_non_binding`... no, this is not a pattern * probably [`record_use`](https://github.com/rust-lang/rust/blob/74fbbefea8d13683cca5eee62e4740706cb3144a/compiler/rustc_resolve/src/lib.rs#L1685)...wait what * I have no idea :) * probably [`try_resolve_as_non_binding`](https://github.com/rust-lang/rust/blob/74fbbefea8d13683cca5eee62e4740706cb3144a/compiler/rustc_resolve/src/late.rs#L1803) https://rustc-dev-guide.rust-lang.org/building/suggested.html#configuring-rust-analyzer-for-rustc niko's vscode settings: ```bash > cat .vscode/settings.json { "rust-analyzer.checkOnSave.overrideCommand": [ "vscode.sh" ], "rust-analyzer.rustfmt.overrideCommand": [ "./build/x86_64-unknown-linux-gnu/stage0/bin/rustfmt", "--edition=2018" ], "editor.formatOnSave": true, "rust-analyzer.cargo.runBuildScripts": false, "rust-analyzer.rustcSource": "./Cargo.toml", "rust-analyzer.procMacro.enable": false } > cat $(which vscode.sh) #!/bin/bash mkdir -p build/vscode cd build/vscode ../../x.py check --json-output ``` ### rémy - backtrace: not great - `configure_and_expand` - `rustc_resolve::diagnostics::report_ambiguity_error` - `rustc_resolve::record_use` -> emits error per `used_binding.ambiguity` - `rustc_resolve::imports::ambiguity` - `rustc_resolve::imports::try_define` [`// Define the name or return the existing binding if there is a collision.`](https://github.com/rust-lang/rust/blob/74fbbefea8d13683cca5eee62e4740706cb3144a/compiler/rustc_resolve/src/imports.rs#L492-L560) ### olivia error code leads to https://github.com/rust-lang/rust/blob/48e89b00caa94829a5f07e0f1ecb33bf37431244/compiler/rustc_resolve/src/lib.rs GlobVsGlob - import.rs - try_define