@@ -13,9 +13,11 @@ use rustc_expand::base::{
1313} ;
1414use rustc_expand:: module:: DirOwnership ;
1515use rustc_lint_defs:: BuiltinLintDiag ;
16- use rustc_parse:: parser:: { ForceCollect , Parser } ;
16+ use rustc_parse:: lexer:: StripTokens ;
17+ use rustc_parse:: parser:: ForceCollect ;
1718use rustc_parse:: { new_parser_from_file, unwrap_or_emit_fatal, utf8_error} ;
1819use rustc_session:: lint:: builtin:: INCOMPLETE_INCLUDE ;
20+ use rustc_session:: parse:: ParseSess ;
1921use rustc_span:: source_map:: SourceMap ;
2022use rustc_span:: { ByteSymbol , Pos , Span , Symbol } ;
2123use smallvec:: SmallVec ;
@@ -114,64 +116,76 @@ pub(crate) fn expand_include<'cx>(
114116 let ExpandResult :: Ready ( mac) = get_single_str_from_tts ( cx, sp, tts, "include!" ) else {
115117 return ExpandResult :: Retry ( ( ) ) ;
116118 } ;
117- let file = match mac {
118- Ok ( file ) => file ,
119+ let path = match mac {
120+ Ok ( path ) => path ,
119121 Err ( guar) => return ExpandResult :: Ready ( DummyResult :: any ( sp, guar) ) ,
120122 } ;
121123 // 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 ,
124126 Err ( err) => {
125127 let guar = err. emit ( ) ;
126128 return ExpandResult :: Ready ( DummyResult :: any ( sp, guar) ) ;
127129 }
128130 } ;
129- let p = unwrap_or_emit_fatal ( new_parser_from_file ( cx. psess ( ) , & file, Some ( sp) ) ) ;
130131
131132 // 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 `.
133134 // See https://github.com/rust-lang/rust/pull/69838/files#r395217057 for a discussion.
134135 // `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 ( ) ;
136137 cx. current_expansion . module = Rc :: new ( cx. current_expansion . module . with_dir_path ( dir_path) ) ;
137138 cx. current_expansion . dir_ownership = DirOwnership :: Owned { relative : None } ;
138139
139140 struct ExpandInclude < ' a > {
140- p : Parser < ' a > ,
141+ psess : & ' a ParseSess ,
142+ path : PathBuf ,
141143 node_id : ast:: NodeId ,
144+ span : Span ,
142145 }
143146 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 (
148159 INCOMPLETE_INCLUDE ,
149- self . p . token . span ,
160+ p. token . span ,
150161 self . node_id ,
151162 BuiltinLintDiag :: IncompleteInclude ,
152163 ) ;
153164 }
154165 Some ( expr)
155166 }
156167
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+ ) ) ;
158175 let mut ret = SmallVec :: new ( ) ;
159176 loop {
160- match self . p . parse_item ( ForceCollect :: No ) {
177+ match p. parse_item ( ForceCollect :: No ) {
161178 Err ( err) => {
162179 err. emit ( ) ;
163180 break ;
164181 }
165182 Ok ( Some ( item) ) => ret. push ( item) ,
166183 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+ } ) ;
175189 }
176190
177191 break ;
@@ -182,7 +196,12 @@ pub(crate) fn expand_include<'cx>(
182196 }
183197 }
184198
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+ } ) )
186205}
187206
188207/// Expand `include_str!($input)` to the content of the UTF-8-encoded file given by path `$input` as a string literal.
0 commit comments