@@ -18,7 +18,7 @@ use crate::{
18
18
generics:: GenericParams ,
19
19
import_map:: ImportMap ,
20
20
intern:: Interned ,
21
- item_tree:: ItemTree ,
21
+ item_tree:: { AttrOwner , ItemTree } ,
22
22
lang_item:: { LangItemTarget , LangItems } ,
23
23
nameres:: DefMap ,
24
24
visibility:: { self , Visibility } ,
@@ -184,6 +184,8 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
184
184
185
185
#[ salsa:: transparent]
186
186
fn crate_limits ( & self , crate_id : CrateId ) -> CrateLimits ;
187
+
188
+ fn crate_supports_no_std ( & self , crate_id : CrateId ) -> bool ;
187
189
}
188
190
189
191
fn crate_def_map_wait ( db : & dyn DefDatabase , krate : CrateId ) -> Arc < DefMap > {
@@ -204,3 +206,38 @@ fn crate_limits(db: &dyn DefDatabase, crate_id: CrateId) -> CrateLimits {
204
206
recursion_limit : def_map. recursion_limit ( ) . unwrap_or ( 128 ) ,
205
207
}
206
208
}
209
+
210
+ fn crate_supports_no_std ( db : & dyn DefDatabase , crate_id : CrateId ) -> bool {
211
+ let file = db. crate_graph ( ) [ crate_id] . root_file_id ;
212
+ let item_tree = db. file_item_tree ( file. into ( ) ) ;
213
+ let attrs = item_tree. raw_attrs ( AttrOwner :: TopLevel ) ;
214
+ for attr in & * * attrs {
215
+ match attr. path ( ) . as_ident ( ) . and_then ( |id| id. as_text ( ) ) {
216
+ Some ( ident) if ident == "no_std" => return true ,
217
+ Some ( ident) if ident == "cfg_attr" => { }
218
+ _ => continue ,
219
+ }
220
+
221
+ // This is a `cfg_attr`; check if it could possibly expand to `no_std`.
222
+ // Syntax is: `#[cfg_attr(condition(cfg, style), attr0, attr1, <...>)]`
223
+ let tt = match attr. token_tree_value ( ) {
224
+ Some ( tt) => & tt. token_trees ,
225
+ None => continue ,
226
+ } ;
227
+
228
+ let segments = tt. split ( |tt| match tt {
229
+ tt:: TokenTree :: Leaf ( tt:: Leaf :: Punct ( p) ) if p. char == ',' => true ,
230
+ _ => false ,
231
+ } ) ;
232
+ for output in segments. skip ( 1 ) {
233
+ match output {
234
+ [ tt:: TokenTree :: Leaf ( tt:: Leaf :: Ident ( ident) ) ] if ident. text == "no_std" => {
235
+ return true
236
+ }
237
+ _ => { }
238
+ }
239
+ }
240
+ }
241
+
242
+ false
243
+ }
0 commit comments