@@ -13,9 +13,11 @@ use rustc_expand::base::{
13
13
} ;
14
14
use rustc_expand:: module:: DirOwnership ;
15
15
use rustc_lint_defs:: BuiltinLintDiag ;
16
- use rustc_parse:: parser:: { ForceCollect , Parser } ;
16
+ use rustc_parse:: lexer:: StripTokens ;
17
+ use rustc_parse:: parser:: ForceCollect ;
17
18
use rustc_parse:: { new_parser_from_file, unwrap_or_emit_fatal, utf8_error} ;
18
19
use rustc_session:: lint:: builtin:: INCOMPLETE_INCLUDE ;
20
+ use rustc_session:: parse:: ParseSess ;
19
21
use rustc_span:: source_map:: SourceMap ;
20
22
use rustc_span:: { ByteSymbol , Pos , Span , Symbol } ;
21
23
use smallvec:: SmallVec ;
@@ -114,64 +116,76 @@ pub(crate) fn expand_include<'cx>(
114
116
let ExpandResult :: Ready ( mac) = get_single_str_from_tts ( cx, sp, tts, "include!" ) else {
115
117
return ExpandResult :: Retry ( ( ) ) ;
116
118
} ;
117
- let file = match mac {
118
- Ok ( file ) => file ,
119
+ let path = match mac {
120
+ Ok ( path ) => path ,
119
121
Err ( guar) => return ExpandResult :: Ready ( DummyResult :: any ( sp, guar) ) ,
120
122
} ;
121
123
// The file will be added to the code map by the parser
122
- let file = match resolve_path ( & cx. sess , file . as_str ( ) , sp) {
123
- Ok ( f ) => f ,
124
+ let path = match resolve_path ( & cx. sess , path . as_str ( ) , sp) {
125
+ Ok ( path ) => path ,
124
126
Err ( err) => {
125
127
let guar = err. emit ( ) ;
126
128
return ExpandResult :: Ready ( DummyResult :: any ( sp, guar) ) ;
127
129
}
128
130
} ;
129
- let p = unwrap_or_emit_fatal ( new_parser_from_file ( cx. psess ( ) , & file, Some ( sp) ) ) ;
130
131
131
132
// If in the included file we have e.g., `mod bar;`,
132
- // then the path of `bar.rs` should be relative to the directory of `file `.
133
+ // then the path of `bar.rs` should be relative to the directory of `path `.
133
134
// See https://github.com/rust-lang/rust/pull/69838/files#r395217057 for a discussion.
134
135
// `MacroExpander::fully_expand_fragment` later restores, so "stack discipline" is maintained.
135
- let dir_path = file . parent ( ) . unwrap_or ( & file ) . to_owned ( ) ;
136
+ let dir_path = path . parent ( ) . unwrap_or ( & path ) . to_owned ( ) ;
136
137
cx. current_expansion . module = Rc :: new ( cx. current_expansion . module . with_dir_path ( dir_path) ) ;
137
138
cx. current_expansion . dir_ownership = DirOwnership :: Owned { relative : None } ;
138
139
139
140
struct ExpandInclude < ' a > {
140
- p : Parser < ' a > ,
141
+ psess : & ' a ParseSess ,
142
+ path : PathBuf ,
141
143
node_id : ast:: NodeId ,
144
+ span : Span ,
142
145
}
143
146
impl < ' a > MacResult for ExpandInclude < ' a > {
144
- fn make_expr ( mut self : Box < ExpandInclude < ' a > > ) -> Option < Box < ast:: Expr > > {
145
- let expr = parse_expr ( & mut self . p ) . ok ( ) ?;
146
- if self . p . token != token:: Eof {
147
- self . p . psess . buffer_lint (
147
+ fn make_expr ( self : Box < ExpandInclude < ' a > > ) -> Option < Box < ast:: Expr > > {
148
+ let mut p = unwrap_or_emit_fatal ( new_parser_from_file (
149
+ self . psess ,
150
+ & self . path ,
151
+ // Don't strip frontmatter for backward compatibility, `---` may be the start of a
152
+ // manifold negation. FIXME: Ideally, we wouldn't strip shebangs here either.
153
+ StripTokens :: Shebang ,
154
+ Some ( self . span ) ,
155
+ ) ) ;
156
+ let expr = parse_expr ( & mut p) . ok ( ) ?;
157
+ if p. token != token:: Eof {
158
+ p. psess . buffer_lint (
148
159
INCOMPLETE_INCLUDE ,
149
- self . p . token . span ,
160
+ p. token . span ,
150
161
self . node_id ,
151
162
BuiltinLintDiag :: IncompleteInclude ,
152
163
) ;
153
164
}
154
165
Some ( expr)
155
166
}
156
167
157
- fn make_items ( mut self : Box < ExpandInclude < ' a > > ) -> Option < SmallVec < [ Box < ast:: Item > ; 1 ] > > {
168
+ fn make_items ( self : Box < ExpandInclude < ' a > > ) -> Option < SmallVec < [ Box < ast:: Item > ; 1 ] > > {
169
+ let mut p = unwrap_or_emit_fatal ( new_parser_from_file (
170
+ self . psess ,
171
+ & self . path ,
172
+ StripTokens :: ShebangAndFrontmatter ,
173
+ Some ( self . span ) ,
174
+ ) ) ;
158
175
let mut ret = SmallVec :: new ( ) ;
159
176
loop {
160
- match self . p . parse_item ( ForceCollect :: No ) {
177
+ match p. parse_item ( ForceCollect :: No ) {
161
178
Err ( err) => {
162
179
err. emit ( ) ;
163
180
break ;
164
181
}
165
182
Ok ( Some ( item) ) => ret. push ( item) ,
166
183
Ok ( None ) => {
167
- if self . p . token != token:: Eof {
168
- self . p
169
- . dcx ( )
170
- . create_err ( errors:: ExpectedItem {
171
- span : self . p . token . span ,
172
- token : & pprust:: token_to_string ( & self . p . token ) ,
173
- } )
174
- . emit ( ) ;
184
+ if p. token != token:: Eof {
185
+ p. dcx ( ) . emit_err ( errors:: ExpectedItem {
186
+ span : p. token . span ,
187
+ token : & pprust:: token_to_string ( & p. token ) ,
188
+ } ) ;
175
189
}
176
190
177
191
break ;
@@ -182,7 +196,12 @@ pub(crate) fn expand_include<'cx>(
182
196
}
183
197
}
184
198
185
- ExpandResult :: Ready ( Box :: new ( ExpandInclude { p, node_id : cx. current_expansion . lint_node_id } ) )
199
+ ExpandResult :: Ready ( Box :: new ( ExpandInclude {
200
+ psess : cx. psess ( ) ,
201
+ path,
202
+ node_id : cx. current_expansion . lint_node_id ,
203
+ span : sp,
204
+ } ) )
186
205
}
187
206
188
207
/// Expand `include_str!($input)` to the content of the UTF-8-encoded file given by path `$input` as a string literal.
0 commit comments