11use syntax:: { ast, attr} ;
22use syntax:: edition:: Edition ;
3+ use syntax:: ext:: expand:: ExpansionConfig ;
34use syntax:: ext:: hygiene:: AstPass ;
4- use syntax:: ext:: base:: Resolver ;
5+ use syntax:: ext:: base:: { ExtCtxt , Resolver } ;
6+ use syntax:: parse:: ParseSess ;
57use syntax:: ptr:: P ;
6- use syntax:: source_map:: respan;
78use syntax:: symbol:: { Ident , Symbol , kw, sym} ;
89use syntax_pos:: DUMMY_SP ;
910
1011pub fn inject (
1112 mut krate : ast:: Crate ,
1213 resolver : & mut dyn Resolver ,
14+ sess : & ParseSess ,
1315 alt_std_name : Option < Symbol > ,
14- edition : Edition ,
1516) -> ( ast:: Crate , Option < Symbol > ) {
16- let rust_2018 = edition >= Edition :: Edition2018 ;
17+ let rust_2018 = sess . edition >= Edition :: Edition2018 ;
1718
1819 // the first name in this list is the crate name of the crate with the prelude
1920 let names: & [ Symbol ] = if attr:: contains_name ( & krate. attrs , sym:: no_core) {
@@ -37,112 +38,49 @@ pub fn inject(
3738 let span = DUMMY_SP . with_def_site_ctxt ( expn_id) ;
3839 let call_site = DUMMY_SP . with_call_site_ctxt ( expn_id) ;
3940
41+ let ecfg = ExpansionConfig :: default ( "std_lib_injection" . to_string ( ) ) ;
42+ let cx = ExtCtxt :: new ( sess, ecfg, resolver) ;
43+
44+
4045 // .rev() to preserve ordering above in combination with insert(0, ...)
41- for & orig_name_sym in names. iter ( ) . rev ( ) {
42- let ( rename , orig_name ) = if rust_2018 {
43- ( Ident :: new ( kw :: Underscore , span) , Some ( orig_name_sym ) )
46+ for & name in names. iter ( ) . rev ( ) {
47+ let ident = if rust_2018 {
48+ Ident :: new ( name , span)
4449 } else {
45- ( Ident :: new ( orig_name_sym , call_site) , None )
50+ Ident :: new ( name , call_site)
4651 } ;
47- krate. module . items . insert ( 0 , P ( ast:: Item {
48- attrs : vec ! [ attr:: mk_attr_outer(
49- attr:: mk_word_item( ast:: Ident :: new( sym:: macro_use, span) )
50- ) ] ,
51- vis : respan ( span, ast:: VisibilityKind :: Inherited ) ,
52- node : ast:: ItemKind :: ExternCrate ( alt_std_name. or ( orig_name) ) ,
53- ident : rename,
54- id : ast:: DUMMY_NODE_ID ,
52+ krate. module . items . insert ( 0 , cx. item (
5553 span,
56- tokens : None ,
57- } ) ) ;
54+ ident,
55+ vec ! [ cx. attribute( cx. meta_word( span, sym:: macro_use) ) ] ,
56+ ast:: ItemKind :: ExternCrate ( alt_std_name) ,
57+ ) ) ;
5858 }
5959
60- // the crates have been injected, the assumption is that the first one is the one with
61- // the prelude.
60+ // The crates have been injected, the assumption is that the first one is
61+ // the one with the prelude.
6262 let name = names[ 0 ] ;
6363
64- let segments = if rust_2018 {
64+ let import_path = if rust_2018 {
6565 [ name, sym:: prelude, sym:: v1] . iter ( )
66- . map ( |symbol| ast:: PathSegment :: from_ident ( ast:: Ident :: new ( * symbol, span) ) )
67- . collect ( )
66+ . map ( |symbol| ast:: Ident :: new ( * symbol, span) ) . collect ( )
6867 } else {
6968 [ kw:: PathRoot , name, sym:: prelude, sym:: v1] . iter ( )
70- . map ( |symbol| ast:: PathSegment :: from_ident ( ast:: Ident :: new ( * symbol, call_site) ) )
71- . collect ( )
69+ . map ( |symbol| ast:: Ident :: new ( * symbol, span) ) . collect ( )
7270 } ;
7371
74- let use_item = P ( ast :: Item {
75- attrs : vec ! [ attr :: mk_attr_outer (
76- attr :: mk_word_item ( ast:: Ident :: new ( sym :: prelude_import , span ) ) ) ] ,
77- vis : respan ( span . shrink_to_lo ( ) , ast :: VisibilityKind :: Inherited ) ,
78- node : ast:: ItemKind :: Use ( P ( ast:: UseTree {
79- prefix : ast :: Path { segments , span } ,
72+ let use_item = cx . item (
73+ span ,
74+ ast:: Ident :: invalid ( ) ,
75+ vec ! [ cx . attribute ( cx . meta_word ( span , sym :: prelude_import ) ) ] ,
76+ ast:: ItemKind :: Use ( P ( ast:: UseTree {
77+ prefix : cx . path ( span , import_path ) ,
8078 kind : ast:: UseTreeKind :: Glob ,
8179 span,
8280 } ) ) ,
83- id : ast:: DUMMY_NODE_ID ,
84- ident : ast:: Ident :: invalid ( ) ,
85- span,
86- tokens : None ,
87- } ) ;
88-
89- let prelude_import_item = if rust_2018 {
90- let hygienic_extern_crate = P ( ast:: Item {
91- attrs : vec ! [ ] ,
92- vis : respan ( span, ast:: VisibilityKind :: Inherited ) ,
93- node : ast:: ItemKind :: ExternCrate ( alt_std_name) ,
94- ident : ast:: Ident :: new ( name, span) ,
95- id : ast:: DUMMY_NODE_ID ,
96- span,
97- tokens : None ,
98- } ) ;
99-
100- // Use an anonymous const to hide `extern crate std as hygienic_std`
101- // FIXME: Once inter-crate hygiene exists, this can just be `use_item`.
102- P ( ast:: Item {
103- attrs : Vec :: new ( ) ,
104- vis : respan ( span. shrink_to_lo ( ) , ast:: VisibilityKind :: Inherited ) ,
105- node : ast:: ItemKind :: Const (
106- P ( ast:: Ty {
107- id : ast:: DUMMY_NODE_ID ,
108- node : ast:: TyKind :: Tup ( Vec :: new ( ) ) ,
109- span,
110- } ) ,
111- P ( ast:: Expr {
112- id : ast:: DUMMY_NODE_ID ,
113- attrs : syntax:: ThinVec :: new ( ) ,
114- node : ast:: ExprKind :: Block ( P ( ast:: Block {
115- id : ast:: DUMMY_NODE_ID ,
116- rules : ast:: BlockCheckMode :: Default ,
117- stmts : vec ! [
118- ast:: Stmt {
119- id: ast:: DUMMY_NODE_ID ,
120- node: ast:: StmtKind :: Item ( use_item) ,
121- span,
122- } ,
123- ast:: Stmt {
124- id: ast:: DUMMY_NODE_ID ,
125- node: ast:: StmtKind :: Item ( hygienic_extern_crate) ,
126- span,
127- }
128- ] ,
129- span,
130- } ) , None ) ,
131- span,
132- } )
133- ) ,
134- id : ast:: DUMMY_NODE_ID ,
135- ident : ast:: Ident :: new ( kw:: Underscore , span) ,
136- span,
137- tokens : None ,
138- } )
139- } else {
140- // Have `extern crate std` at the root, so don't need to create a named
141- // extern crate item.
142- use_item
143- } ;
81+ ) ;
14482
145- krate. module . items . insert ( 0 , prelude_import_item ) ;
83+ krate. module . items . insert ( 0 , use_item ) ;
14684
14785 ( krate, Some ( name) )
14886}
0 commit comments