11
11
use ast;
12
12
use attr;
13
13
use std:: cell:: Cell ;
14
+ use std:: iter;
15
+ use edition:: Edition ;
14
16
use ext:: hygiene:: { Mark , SyntaxContext } ;
15
17
use symbol:: { Symbol , keywords} ;
16
18
use syntax_pos:: { DUMMY_SP , Span } ;
@@ -43,7 +45,13 @@ thread_local! {
43
45
static INJECTED_CRATE_NAME : Cell <Option <& ' static str >> = Cell :: new( None ) ;
44
46
}
45
47
46
- pub fn maybe_inject_crates_ref ( mut krate : ast:: Crate , alt_std_name : Option < & str > ) -> ast:: Crate {
48
+ pub fn maybe_inject_crates_ref (
49
+ mut krate : ast:: Crate ,
50
+ alt_std_name : Option < & str > ,
51
+ edition : Edition ,
52
+ ) -> ast:: Crate {
53
+ let rust_2018 = edition >= Edition :: Edition2018 ;
54
+
47
55
// the first name in this list is the crate name of the crate with the prelude
48
56
let names: & [ & str ] = if attr:: contains_name ( & krate. attrs , "no_core" ) {
49
57
return krate;
@@ -58,14 +66,27 @@ pub fn maybe_inject_crates_ref(mut krate: ast::Crate, alt_std_name: Option<&str>
58
66
} ;
59
67
60
68
// .rev() to preserve ordering above in combination with insert(0, ...)
61
- for name in names. iter ( ) . rev ( ) {
69
+ let alt_std_name = alt_std_name. map ( Symbol :: intern) ;
70
+ for orig_name in names. iter ( ) . rev ( ) {
71
+ let orig_name = Symbol :: intern ( orig_name) ;
72
+ let mut rename = orig_name;
73
+ // HACK(eddyb) gensym the injected crates on the Rust 2018 edition,
74
+ // so they don't accidentally interfere with the new import paths.
75
+ if rust_2018 {
76
+ rename = orig_name. gensymed ( ) ;
77
+ }
78
+ let orig_name = if rename != orig_name {
79
+ Some ( orig_name)
80
+ } else {
81
+ None
82
+ } ;
62
83
krate. module . items . insert ( 0 , P ( ast:: Item {
63
84
attrs : vec ! [ attr:: mk_attr_outer( DUMMY_SP ,
64
85
attr:: mk_attr_id( ) ,
65
86
attr:: mk_word_item( ast:: Ident :: from_str( "macro_use" ) ) ) ] ,
66
87
vis : dummy_spanned ( ast:: VisibilityKind :: Inherited ) ,
67
- node : ast:: ItemKind :: ExternCrate ( alt_std_name. map ( Symbol :: intern ) ) ,
68
- ident : ast:: Ident :: from_str ( name ) ,
88
+ node : ast:: ItemKind :: ExternCrate ( alt_std_name. or ( orig_name ) ) ,
89
+ ident : ast:: Ident :: with_empty_ctxt ( rename ) ,
69
90
id : ast:: DUMMY_NODE_ID ,
70
91
span : DUMMY_SP ,
71
92
tokens : None ,
@@ -91,9 +112,11 @@ pub fn maybe_inject_crates_ref(mut krate: ast::Crate, alt_std_name: Option<&str>
91
112
vis : respan ( span. shrink_to_lo ( ) , ast:: VisibilityKind :: Inherited ) ,
92
113
node : ast:: ItemKind :: Use ( P ( ast:: UseTree {
93
114
prefix : ast:: Path {
94
- segments : [ name, "prelude" , "v1" ] . into_iter ( ) . map ( |name| {
95
- ast:: PathSegment :: from_ident ( ast:: Ident :: from_str ( name) )
96
- } ) . collect ( ) ,
115
+ segments : iter:: once ( keywords:: CrateRoot . ident ( ) )
116
+ . chain (
117
+ [ name, "prelude" , "v1" ] . iter ( ) . cloned ( )
118
+ . map ( ast:: Ident :: from_str)
119
+ ) . map ( ast:: PathSegment :: from_ident) . collect ( ) ,
97
120
span,
98
121
} ,
99
122
kind : ast:: UseTreeKind :: Glob ,
0 commit comments