@@ -3,8 +3,8 @@ use std::{any::TypeId, mem, str::FromStr, sync};
33
44use base_db:: {
55 Crate , CrateDisplayName , CrateGraphBuilder , CrateName , CrateOrigin , CrateWorkspaceData ,
6- DependencyBuilder , Env , FileChange , FileSet , LangCrateOrigin , SourceDatabase , SourceRoot ,
7- Version , VfsPath , salsa,
6+ DependencyBuilder , Env , FileChange , FileSet , FxIndexMap , LangCrateOrigin , SourceDatabase ,
7+ SourceRoot , Version , VfsPath , salsa,
88} ;
99use cfg:: CfgOptions ;
1010use hir_expand:: {
@@ -20,7 +20,6 @@ use hir_expand::{
2020} ;
2121use intern:: { Symbol , sym} ;
2222use paths:: AbsPathBuf ;
23- use rustc_hash:: FxHashMap ;
2423use span:: { Edition , FileId , Span } ;
2524use stdx:: itertools:: Itertools ;
2625use test_utils:: {
@@ -147,7 +146,7 @@ impl ChangeFixture {
147146
148147 let mut files = Vec :: new ( ) ;
149148 let mut crate_graph = CrateGraphBuilder :: default ( ) ;
150- let mut crates = FxHashMap :: default ( ) ;
149+ let mut crates = FxIndexMap :: default ( ) ;
151150 let mut crate_deps = Vec :: new ( ) ;
152151 let mut default_crate_root: Option < FileId > = None ;
153152 let mut default_edition = Edition :: CURRENT ;
@@ -249,37 +248,7 @@ impl ChangeFixture {
249248 file_id = FileId :: from_raw ( file_id. index ( ) + 1 ) ;
250249 }
251250
252- if crates. is_empty ( ) {
253- let crate_root = default_crate_root
254- . expect ( "missing default crate root, specify a main.rs or lib.rs" ) ;
255- crate_graph. add_crate_root (
256- crate_root,
257- default_edition,
258- Some ( CrateName :: new ( "ra_test_fixture" ) . unwrap ( ) . into ( ) ) ,
259- None ,
260- default_cfg. clone ( ) ,
261- Some ( default_cfg) ,
262- default_env,
263- CrateOrigin :: Local { repo : None , name : None } ,
264- false ,
265- proc_macro_cwd. clone ( ) ,
266- crate_ws_data. clone ( ) ,
267- ) ;
268- } else {
269- for ( from, to, prelude) in crate_deps {
270- let from_id = crates[ & from] ;
271- let to_id = crates[ & to] ;
272- let sysroot = crate_graph[ to_id] . basic . origin . is_lang ( ) ;
273- crate_graph
274- . add_dep (
275- from_id,
276- DependencyBuilder :: with_prelude ( to. clone ( ) , to_id, prelude, sysroot) ,
277- )
278- . unwrap ( ) ;
279- }
280- }
281-
282- if let Some ( mini_core) = mini_core {
251+ let mini_core = mini_core. map ( |mini_core| {
283252 let core_file = file_id;
284253 file_id = FileId :: from_raw ( file_id. index ( ) + 1 ) ;
285254
@@ -289,8 +258,6 @@ impl ChangeFixture {
289258
290259 source_change. change_file ( core_file, Some ( mini_core. source_code ( ) ) ) ;
291260
292- let all_crates = crate_graph. iter ( ) . collect :: < Vec < _ > > ( ) ;
293-
294261 let core_crate = crate_graph. add_crate_root (
295262 core_file,
296263 Edition :: CURRENT ,
@@ -308,16 +275,58 @@ impl ChangeFixture {
308275 crate_ws_data. clone ( ) ,
309276 ) ;
310277
311- for krate in all_crates {
278+ (
279+ move || {
280+ DependencyBuilder :: with_prelude (
281+ CrateName :: new ( "core" ) . unwrap ( ) ,
282+ core_crate,
283+ true ,
284+ true ,
285+ )
286+ } ,
287+ core_crate,
288+ )
289+ } ) ;
290+
291+ if crates. is_empty ( ) {
292+ let crate_root = default_crate_root
293+ . expect ( "missing default crate root, specify a main.rs or lib.rs" ) ;
294+ let root = crate_graph. add_crate_root (
295+ crate_root,
296+ default_edition,
297+ Some ( CrateName :: new ( "ra_test_fixture" ) . unwrap ( ) . into ( ) ) ,
298+ None ,
299+ default_cfg. clone ( ) ,
300+ Some ( default_cfg) ,
301+ default_env,
302+ CrateOrigin :: Local { repo : None , name : None } ,
303+ false ,
304+ proc_macro_cwd. clone ( ) ,
305+ crate_ws_data. clone ( ) ,
306+ ) ;
307+ if let Some ( ( mini_core, _) ) = mini_core {
308+ crate_graph. add_dep ( root, mini_core ( ) ) . unwrap ( ) ;
309+ }
310+ } else {
311+ // Insert minicore first to match with `project-model::workspace`
312+ if let Some ( ( mini_core, core_crate) ) = mini_core {
313+ let all_crates = crate_graph. iter ( ) . collect :: < Vec < _ > > ( ) ;
314+ for krate in all_crates {
315+ if krate == core_crate {
316+ continue ;
317+ }
318+ crate_graph. add_dep ( krate, mini_core ( ) ) . unwrap ( ) ;
319+ }
320+ }
321+
322+ for ( from, to, prelude) in crate_deps {
323+ let from_id = crates[ & from] ;
324+ let to_id = crates[ & to] ;
325+ let sysroot = crate_graph[ to_id] . basic . origin . is_lang ( ) ;
312326 crate_graph
313327 . add_dep (
314- krate,
315- DependencyBuilder :: with_prelude (
316- CrateName :: new ( "core" ) . unwrap ( ) ,
317- core_crate,
318- true ,
319- true ,
320- ) ,
328+ from_id,
329+ DependencyBuilder :: with_prelude ( to. clone ( ) , to_id, prelude, sysroot) ,
321330 )
322331 . unwrap ( ) ;
323332 }
@@ -627,11 +636,23 @@ impl FileMeta {
627636 }
628637}
629638
639+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
640+ enum ForceNoneLangOrigin {
641+ Yes ,
642+ No ,
643+ }
644+
630645fn parse_crate (
631646 crate_str : String ,
632647 current_source_root_kind : SourceRootKind ,
633648 explicit_non_workspace_member : bool ,
634649) -> ( String , CrateOrigin , Option < String > ) {
650+ let ( crate_str, force_non_lang_origin) = if let Some ( s) = crate_str. strip_prefix ( "r#" ) {
651+ ( s. to_owned ( ) , ForceNoneLangOrigin :: Yes )
652+ } else {
653+ ( crate_str, ForceNoneLangOrigin :: No )
654+ } ;
655+
635656 // syntax:
636657 // "my_awesome_crate"
637658 // "my_awesome_crate@0.0.1,http://example.com"
@@ -646,16 +667,25 @@ fn parse_crate(
646667 let non_workspace_member = explicit_non_workspace_member
647668 || matches ! ( current_source_root_kind, SourceRootKind :: Library ) ;
648669
649- let origin = match LangCrateOrigin :: from ( & * name) {
650- LangCrateOrigin :: Other => {
651- let name = Symbol :: intern ( & name) ;
652- if non_workspace_member {
653- CrateOrigin :: Library { repo, name }
654- } else {
655- CrateOrigin :: Local { repo, name : Some ( name) }
670+ let origin = if force_non_lang_origin == ForceNoneLangOrigin :: Yes {
671+ let name = Symbol :: intern ( & name) ;
672+ if non_workspace_member {
673+ CrateOrigin :: Library { repo, name }
674+ } else {
675+ CrateOrigin :: Local { repo, name : Some ( name) }
676+ }
677+ } else {
678+ match LangCrateOrigin :: from ( & * name) {
679+ LangCrateOrigin :: Other => {
680+ let name = Symbol :: intern ( & name) ;
681+ if non_workspace_member {
682+ CrateOrigin :: Library { repo, name }
683+ } else {
684+ CrateOrigin :: Local { repo, name : Some ( name) }
685+ }
656686 }
687+ origin => CrateOrigin :: Lang ( origin) ,
657688 }
658- origin => CrateOrigin :: Lang ( origin) ,
659689 } ;
660690
661691 ( name, origin, version)
0 commit comments