diff --git a/Cargo.lock b/Cargo.lock
index b1fef2e80a6..b2d009e38fb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -486,6 +486,7 @@ dependencies = [
  "log",
  "profile",
  "rustc-hash",
+ "smallvec",
  "stdx",
  "syntax",
  "tt",
diff --git a/crates/hir/Cargo.toml b/crates/hir/Cargo.toml
index d4ea7327ebe..55e9c3f0cf9 100644
--- a/crates/hir/Cargo.toml
+++ b/crates/hir/Cargo.toml
@@ -15,6 +15,7 @@ rustc-hash = "1.1.0"
 either = "1.5.3"
 arrayvec = "0.5.1"
 itertools = "0.10.0"
+smallvec = "1.4.0"
 
 stdx = { path = "../stdx", version = "0.0.0" }
 syntax = { path = "../syntax", version = "0.0.0" }
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 945638cc565..519339c0c86 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -259,6 +259,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
     }
 
     pub fn to_module_def(&self, file: FileId) -> Option<Module> {
+        self.imp.to_module_def(file).next()
+    }
+
+    pub fn to_module_defs(&self, file: FileId) -> impl Iterator<Item = Module> {
         self.imp.to_module_def(file)
     }
 
@@ -537,8 +541,8 @@ impl<'db> SemanticsImpl<'db> {
         f(&mut ctx)
     }
 
-    fn to_module_def(&self, file: FileId) -> Option<Module> {
-        self.with_ctx(|ctx| ctx.file_to_def(file)).map(Module::from)
+    fn to_module_def(&self, file: FileId) -> impl Iterator<Item = Module> {
+        self.with_ctx(|ctx| ctx.file_to_def(file)).into_iter().map(Module::from)
     }
 
     fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db> {
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs
index 6c612ee8635..e9d8201403c 100644
--- a/crates/hir/src/semantics/source_to_def.rs
+++ b/crates/hir/src/semantics/source_to_def.rs
@@ -12,6 +12,7 @@ use hir_def::{
 };
 use hir_expand::{name::AsName, AstId, MacroDefKind};
 use rustc_hash::FxHashMap;
+use smallvec::SmallVec;
 use stdx::impl_from;
 use syntax::{
     ast::{self, NameOwner},
@@ -28,14 +29,19 @@ pub(super) struct SourceToDefCtx<'a, 'b> {
 }
 
 impl SourceToDefCtx<'_, '_> {
-    pub(super) fn file_to_def(&mut self, file: FileId) -> Option<ModuleId> {
+    pub(super) fn file_to_def(&mut self, file: FileId) -> SmallVec<[ModuleId; 1]> {
         let _p = profile::span("SourceBinder::to_module_def");
-        self.db.relevant_crates(file).iter().find_map(|&crate_id| {
+        let mut mods = SmallVec::new();
+        for &crate_id in self.db.relevant_crates(file).iter() {
             // FIXME: inner items
             let crate_def_map = self.db.crate_def_map(crate_id);
-            let local_id = crate_def_map.modules_for_file(file).next()?;
-            Some(crate_def_map.module_id(local_id))
-        })
+            mods.extend(
+                crate_def_map
+                    .modules_for_file(file)
+                    .map(|local_id| crate_def_map.module_id(local_id)),
+            )
+        }
+        mods
     }
 
     pub(super) fn module_to_def(&mut self, src: InFile<ast::Module>) -> Option<ModuleId> {
@@ -55,7 +61,7 @@ impl SourceToDefCtx<'_, '_> {
             Some(parent_declaration) => self.module_to_def(parent_declaration),
             None => {
                 let file_id = src.file_id.original_file(self.db.upcast());
-                self.file_to_def(file_id)
+                self.file_to_def(file_id).get(0).copied()
             }
         }?;
 
@@ -185,7 +191,7 @@ impl SourceToDefCtx<'_, '_> {
     ) -> Option<MacroDefId> {
         let kind = MacroDefKind::Declarative;
         let file_id = src.file_id.original_file(self.db.upcast());
-        let krate = self.file_to_def(file_id)?.krate();
+        let krate = self.file_to_def(file_id).get(0).copied()?.krate();
         let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value);
         let ast_id = Some(AstId::new(src.file_id, file_ast_id.upcast()));
         Some(MacroDefId { krate, ast_id, kind, local_inner: false })
@@ -245,7 +251,7 @@ impl SourceToDefCtx<'_, '_> {
             return Some(res);
         }
 
-        let def = self.file_to_def(src.file_id.original_file(self.db.upcast()))?;
+        let def = self.file_to_def(src.file_id.original_file(self.db.upcast())).get(0).copied()?;
         Some(def.into())
     }
 
diff --git a/crates/ide/src/parent_module.rs b/crates/ide/src/parent_module.rs
index 03d71b3807a..22b0d6ecbef 100644
--- a/crates/ide/src/parent_module.rs
+++ b/crates/ide/src/parent_module.rs
@@ -1,6 +1,7 @@
 use hir::Semantics;
 use ide_db::base_db::{CrateId, FileId, FilePosition};
 use ide_db::RootDatabase;
+use itertools::Itertools;
 use syntax::{
     algo::find_node_at_offset,
     ast::{self, AstNode},
@@ -18,8 +19,7 @@ use crate::NavigationTarget;
 // | VS Code | **Rust Analyzer: Locate parent module**
 // |===
 
-/// This returns `Vec` because a module may be included from several places. We
-/// don't handle this case yet though, so the Vec has length at most one.
+/// This returns `Vec` because a module may be included from several places.
 pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec<NavigationTarget> {
     let sema = Semantics::new(db);
     let source_file = sema.parse(position.file_id);
@@ -37,27 +37,23 @@ pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec<Na
         }
     }
 
-    let module = match module {
-        Some(module) => sema.to_def(&module),
-        None => sema.to_module_def(position.file_id),
-    };
-    let module = match module {
-        None => return Vec::new(),
-        Some(it) => it,
-    };
-    let nav = NavigationTarget::from_module_to_decl(db, module);
-    vec![nav]
+    match module {
+        Some(module) => sema
+            .to_def(&module)
+            .into_iter()
+            .map(|module| NavigationTarget::from_module_to_decl(db, module))
+            .collect(),
+        None => sema
+            .to_module_defs(position.file_id)
+            .map(|module| NavigationTarget::from_module_to_decl(db, module))
+            .collect(),
+    }
 }
 
 /// Returns `Vec` for the same reason as `parent_module`
 pub(crate) fn crate_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> {
     let sema = Semantics::new(db);
-    let module = match sema.to_module_def(file_id) {
-        Some(it) => it,
-        None => return Vec::new(),
-    };
-    let krate = module.krate();
-    vec![krate.into()]
+    sema.to_module_defs(file_id).map(|module| module.krate().into()).unique().collect()
 }
 
 #[cfg(test)]
@@ -67,11 +63,13 @@ mod tests {
     use crate::fixture;
 
     fn check(ra_fixture: &str) {
-        let (analysis, position, expected) = fixture::nav_target_annotation(ra_fixture);
-        let mut navs = analysis.parent_module(position).unwrap();
-        assert_eq!(navs.len(), 1);
-        let nav = navs.pop().unwrap();
-        assert_eq!(expected, FileRange { file_id: nav.file_id, range: nav.focus_or_full_range() });
+        let (analysis, position, expected) = fixture::annotations(ra_fixture);
+        let navs = analysis.parent_module(position).unwrap();
+        let navs = navs
+            .iter()
+            .map(|nav| FileRange { file_id: nav.file_id, range: nav.focus_or_full_range() })
+            .collect::<Vec<_>>();
+        assert_eq!(expected.into_iter().map(|(fr, _)| fr).collect::<Vec<_>>(), navs);
     }
 
     #[test]
@@ -120,15 +118,46 @@ mod foo {
     }
 
     #[test]
-    fn test_resolve_crate_root() {
-        let (analysis, file_id) = fixture::file(
+    fn test_resolve_multi_parent_module() {
+        check(
             r#"
 //- /main.rs
 mod foo;
+  //^^^
+#[path = "foo.rs"]
+mod bar;
+  //^^^
 //- /foo.rs
 $0
+"#,
+        );
+    }
+
+    #[test]
+    fn test_resolve_crate_root() {
+        let (analysis, file_id) = fixture::file(
+            r#"
+//- /foo.rs
+$0
+//- /main.rs
+mod foo;
 "#,
         );
         assert_eq!(analysis.crate_for(file_id).unwrap().len(), 1);
     }
+
+    #[test]
+    fn test_resolve_multi_parent_crate() {
+        let (analysis, file_id) = fixture::file(
+            r#"
+//- /baz.rs
+$0
+//- /foo.rs crate:foo
+mod baz;
+//- /bar.rs crate:bar
+mod baz;
+"#,
+        );
+        assert_eq!(analysis.crate_for(file_id).unwrap().len(), 2);
+    }
 }
diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts
index 694f445bc36..bed1f01169c 100644
--- a/editors/code/src/commands.ts
+++ b/editors/code/src/commands.ts
@@ -170,22 +170,28 @@ export function parentModule(ctx: Ctx): Cmd {
         const client = ctx.client;
         if (!editor || !client) return;
 
-        const response = await client.sendRequest(ra.parentModule, {
+        const locations = await client.sendRequest(ra.parentModule, {
             textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
             position: client.code2ProtocolConverter.asPosition(
                 editor.selection.active,
             ),
         });
-        const loc = response[0];
-        if (!loc) return;
 
-        const uri = client.protocol2CodeConverter.asUri(loc.targetUri);
-        const range = client.protocol2CodeConverter.asRange(loc.targetRange);
+        if (locations.length === 1) {
+            const loc = locations[0];
 
-        const doc = await vscode.workspace.openTextDocument(uri);
-        const e = await vscode.window.showTextDocument(doc);
-        e.selection = new vscode.Selection(range.start, range.start);
-        e.revealRange(range, vscode.TextEditorRevealType.InCenter);
+            const uri = client.protocol2CodeConverter.asUri(loc.targetUri);
+            const range = client.protocol2CodeConverter.asRange(loc.targetRange);
+
+            const doc = await vscode.workspace.openTextDocument(uri);
+            const e = await vscode.window.showTextDocument(doc);
+            e.selection = new vscode.Selection(range.start, range.start);
+            e.revealRange(range, vscode.TextEditorRevealType.InCenter);
+        } else {
+            const uri = editor.document.uri.toString();
+            const position = client.code2ProtocolConverter.asPosition(editor.selection.active);
+            await showReferencesImpl(client, uri, position, locations.map(loc => lc.Location.create(loc.targetUri, loc.targetRange)));
+        }
     };
 }