Skip to content

handle extern crate in name resolution #523

Description

@killercup

Currently, std::sync::Arc cannot be resolved.

In #522 (comment), @flodiebold speculates:

std::sync gets properly resolved, but it reexports Arc from alloc_crate, which is an extern crate rename: extern crate alloc as alloc_crate. I guess that's the problem.


Here's a simple test case:

diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs
index 2968b807..2ca1d6d9 100644
--- a/crates/ra_ide_api/src/hover.rs
+++ b/crates/ra_ide_api/src/hover.rs
@@ -230,6 +230,20 @@ mod tests {
         assert_eq!("u32", &type_name);
     }
 
+    #[test]
+    fn test_type_of_arc() {
+        let (analysis, position) = single_file_with_position(
+            r"
+            use std::sync::A<|>rc;
+
+            fn main() {}
+            ",
+        );
+
+        let hover = analysis.hover(position).unwrap().unwrap();
+        assert!(!hover.info.contains("Failed to exactly resolve"));
+    }
+
     // FIXME: improve type_of to make this work
     #[test]
     fn test_type_of_for_expr_1() {

Activity

  1. changed the title [-]cannot resolve std::sync::Arc[/-] [+]handle `extern crate` in name resolution[/+] on Jan 26, 2019
  2. matklad commented on Feb 3, 2019

    @matklad
    Contributor
  3. added
    E-has-instructionsIssue has some instructions and pointers to code to get started
    on Feb 3, 2019
  4. flodiebold commented on Feb 3, 2019

    @flodiebold
    Member

    @matklad I've got a branch which does handle extern crate (by lowering them to imports with absolute paths), but it doesn't fix this problem, because it turns out we also need to fall back to resolving imports in the crate root. In this particular case, it looks like this:
    lib.rs:

    extern crate alloc as alloc_crate;
    mod sync;

    sync.rs:

    pub use alloc_crate::sync::Arc;

    In general, even in the 2018 edition, plain paths can be resolved either from the current scope or from the crate root.

  5. matklad commented on Feb 3, 2019

    @matklad
    Contributor

    In general, even in the 2018 edition, plain paths can be resolved either from the current scope or from the crate root.

    Just checked locally, and it seems that on 2018 ::foo or use foo don't resolve from the crate root. Could it be that as in extern crate acts as as renamer of the whole crate?

  6. flodiebold commented on Feb 3, 2019

    @flodiebold
    Member

    Hm, you're right, it just works for extern crate apparently. But extern crate foo as bar doesn't just rename the crate in the extern prelude, because 1. it only has an effect if it's in the crate root or the current module, and 2. the original name is still usable. Back to reading rustc, I guess...

  7. flodiebold commented on Feb 3, 2019

    @flodiebold
    Member

    I think extern crates in the crate root are special-cased to insert entries in the extern prelude, if I read this correctly:
    https://github.com/rust-lang/rust/blob/fc6e9a2845e8bb4560811ed21136483a596505bb/src/librustc_resolve/build_reduced_graph.rs#L390-L408

  8. bjorn3 commented on Feb 3, 2019

    @bjorn3
    Member
  9. flodiebold commented on Feb 3, 2019

    @flodiebold
    Member

    Though std isn't actually a case of this, since it's still edition 2015, but I guess if we implemented it that way we could still avoid implementing 2015 name resolution...

  10. added a commit that references this issue on Feb 5, 2019
    4d4c46a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    E-has-instructionsIssue has some instructions and pointers to code to get startedE-medium

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions