1
1
use syntax:: { ast, attr} ;
2
2
use syntax:: edition:: Edition ;
3
+ use syntax:: ext:: expand:: ExpansionConfig ;
3
4
use syntax:: ext:: hygiene:: AstPass ;
4
- use syntax:: ext:: base:: Resolver ;
5
+ use syntax:: ext:: base:: { ExtCtxt , Resolver } ;
6
+ use syntax:: parse:: ParseSess ;
5
7
use syntax:: ptr:: P ;
6
- use syntax:: source_map:: respan;
7
8
use syntax:: symbol:: { Ident , Symbol , kw, sym} ;
8
9
use syntax_pos:: DUMMY_SP ;
9
10
10
11
pub fn inject (
11
12
mut krate : ast:: Crate ,
12
13
resolver : & mut dyn Resolver ,
14
+ sess : & ParseSess ,
13
15
alt_std_name : Option < Symbol > ,
14
- edition : Edition ,
15
16
) -> ( ast:: Crate , Option < Symbol > ) {
16
- let rust_2018 = edition >= Edition :: Edition2018 ;
17
+ let rust_2018 = sess . edition >= Edition :: Edition2018 ;
17
18
18
19
// the first name in this list is the crate name of the crate with the prelude
19
20
let names: & [ Symbol ] = if attr:: contains_name ( & krate. attrs , sym:: no_core) {
@@ -37,112 +38,49 @@ pub fn inject(
37
38
let span = DUMMY_SP . with_def_site_ctxt ( expn_id) ;
38
39
let call_site = DUMMY_SP . with_call_site_ctxt ( expn_id) ;
39
40
41
+ let ecfg = ExpansionConfig :: default ( "std_lib_injection" . to_string ( ) ) ;
42
+ let cx = ExtCtxt :: new ( sess, ecfg, resolver) ;
43
+
44
+
40
45
// .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)
44
49
} else {
45
- ( Ident :: new ( orig_name_sym , call_site) , None )
50
+ Ident :: new ( name , call_site)
46
51
} ;
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 (
55
53
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
+ ) ) ;
58
58
}
59
59
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.
62
62
let name = names[ 0 ] ;
63
63
64
- let segments = if rust_2018 {
64
+ let import_path = if rust_2018 {
65
65
[ 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 ( )
68
67
} else {
69
68
[ 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 ( )
72
70
} ;
73
71
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 ) ,
80
78
kind : ast:: UseTreeKind :: Glob ,
81
79
span,
82
80
} ) ) ,
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
+ ) ;
144
82
145
- krate. module . items . insert ( 0 , prelude_import_item ) ;
83
+ krate. module . items . insert ( 0 , use_item ) ;
146
84
147
85
( krate, Some ( name) )
148
86
}
0 commit comments