1111use ast;
1212use attr;
1313use std:: cell:: Cell ;
14+ use std:: iter;
15+ use edition:: Edition ;
1416use ext:: hygiene:: { Mark , SyntaxContext } ;
1517use symbol:: { Symbol , keywords} ;
1618use syntax_pos:: { DUMMY_SP , Span } ;
@@ -43,7 +45,13 @@ thread_local! {
4345 static INJECTED_CRATE_NAME : Cell <Option <& ' static str >> = Cell :: new( None ) ;
4446}
4547
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+
4755 // the first name in this list is the crate name of the crate with the prelude
4856 let names: & [ & str ] = if attr:: contains_name ( & krate. attrs , "no_core" ) {
4957 return krate;
@@ -58,14 +66,27 @@ pub fn maybe_inject_crates_ref(mut krate: ast::Crate, alt_std_name: Option<&str>
5866 } ;
5967
6068 // .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+ } ;
6283 krate. module . items . insert ( 0 , P ( ast:: Item {
6384 attrs : vec ! [ attr:: mk_attr_outer( DUMMY_SP ,
6485 attr:: mk_attr_id( ) ,
6586 attr:: mk_word_item( ast:: Ident :: from_str( "macro_use" ) ) ) ] ,
6687 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 ) ,
6990 id : ast:: DUMMY_NODE_ID ,
7091 span : DUMMY_SP ,
7192 tokens : None ,
@@ -91,9 +112,11 @@ pub fn maybe_inject_crates_ref(mut krate: ast::Crate, alt_std_name: Option<&str>
91112 vis : respan ( span. shrink_to_lo ( ) , ast:: VisibilityKind :: Inherited ) ,
92113 node : ast:: ItemKind :: Use ( P ( ast:: UseTree {
93114 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 ( ) ,
97120 span,
98121 } ,
99122 kind : ast:: UseTreeKind :: Glob ,
0 commit comments