Skip to content

Commit da1f316

Browse files
Merge #4173
4173: Use core instead of std for builtin derive macros r=edwin0cheng a=edwin0cheng Fixed #4087. We can't use `$crate` here right now because : 1. We have to able to detect `macro` 2.0 in collecting phase for finding `rustc_builtin_macro` attrs. 2. And we have to make hygiene works for builtin derive macro. r= @flodiebold Co-authored-by: Edwin Cheng <[email protected]>
2 parents 7a9ba16 + c69f9c1 commit da1f316

File tree

2 files changed

+109
-37
lines changed

2 files changed

+109
-37
lines changed

crates/ra_hir_expand/src/builtin_derive.rs

Lines changed: 80 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use ra_syntax::{
99
};
1010

1111
use crate::db::AstDatabase;
12-
use crate::{name, quote, LazyMacroId, MacroDefId, MacroDefKind};
12+
use crate::{name, quote, LazyMacroId, MacroCallId, MacroDefId, MacroDefKind};
1313

1414
macro_rules! register_builtin {
1515
( $($trait:ident => $expand:ident),* ) => {
@@ -153,76 +153,113 @@ fn expand_simple_derive(
153153
Ok(expanded)
154154
}
155155

156+
fn find_builtin_crate(db: &dyn AstDatabase, id: LazyMacroId) -> tt::TokenTree {
157+
// FIXME: make hygiene works for builtin derive macro
158+
// such that $crate can be used here.
159+
160+
let m: MacroCallId = id.into();
161+
let file_id = m.as_file().original_file(db);
162+
let cg = db.crate_graph();
163+
let krates = db.relevant_crates(file_id);
164+
let krate = match krates.get(0) {
165+
Some(krate) => krate,
166+
None => {
167+
let tt = quote! { core };
168+
return tt.token_trees[0].clone();
169+
}
170+
};
171+
172+
// XXX
173+
// All crates except core itself should have a dependency on core,
174+
// We detect `core` by seeing whether it doesn't have such a dependency.
175+
let tt = if cg[*krate].dependencies.iter().any(|dep| dep.name == "core") {
176+
quote! { core }
177+
} else {
178+
quote! { crate }
179+
};
180+
181+
tt.token_trees[0].clone()
182+
}
183+
156184
fn copy_expand(
157-
_db: &dyn AstDatabase,
158-
_id: LazyMacroId,
185+
db: &dyn AstDatabase,
186+
id: LazyMacroId,
159187
tt: &tt::Subtree,
160188
) -> Result<tt::Subtree, mbe::ExpandError> {
161-
expand_simple_derive(tt, quote! { std::marker::Copy })
189+
let krate = find_builtin_crate(db, id);
190+
expand_simple_derive(tt, quote! { #krate::marker::Copy })
162191
}
163192

164193
fn clone_expand(
165-
_db: &dyn AstDatabase,
166-
_id: LazyMacroId,
194+
db: &dyn AstDatabase,
195+
id: LazyMacroId,
167196
tt: &tt::Subtree,
168197
) -> Result<tt::Subtree, mbe::ExpandError> {
169-
expand_simple_derive(tt, quote! { std::clone::Clone })
198+
let krate = find_builtin_crate(db, id);
199+
expand_simple_derive(tt, quote! { #krate::clone::Clone })
170200
}
171201

172202
fn default_expand(
173-
_db: &dyn AstDatabase,
174-
_id: LazyMacroId,
203+
db: &dyn AstDatabase,
204+
id: LazyMacroId,
175205
tt: &tt::Subtree,
176206
) -> Result<tt::Subtree, mbe::ExpandError> {
177-
expand_simple_derive(tt, quote! { std::default::Default })
207+
let krate = find_builtin_crate(db, id);
208+
expand_simple_derive(tt, quote! { #krate::default::Default })
178209
}
179210

180211
fn debug_expand(
181-
_db: &dyn AstDatabase,
182-
_id: LazyMacroId,
212+
db: &dyn AstDatabase,
213+
id: LazyMacroId,
183214
tt: &tt::Subtree,
184215
) -> Result<tt::Subtree, mbe::ExpandError> {
185-
expand_simple_derive(tt, quote! { std::fmt::Debug })
216+
let krate = find_builtin_crate(db, id);
217+
expand_simple_derive(tt, quote! { #krate::fmt::Debug })
186218
}
187219

188220
fn hash_expand(
189-
_db: &dyn AstDatabase,
190-
_id: LazyMacroId,
221+
db: &dyn AstDatabase,
222+
id: LazyMacroId,
191223
tt: &tt::Subtree,
192224
) -> Result<tt::Subtree, mbe::ExpandError> {
193-
expand_simple_derive(tt, quote! { std::hash::Hash })
225+
let krate = find_builtin_crate(db, id);
226+
expand_simple_derive(tt, quote! { #krate::hash::Hash })
194227
}
195228

196229
fn eq_expand(
197-
_db: &dyn AstDatabase,
198-
_id: LazyMacroId,
230+
db: &dyn AstDatabase,
231+
id: LazyMacroId,
199232
tt: &tt::Subtree,
200233
) -> Result<tt::Subtree, mbe::ExpandError> {
201-
expand_simple_derive(tt, quote! { std::cmp::Eq })
234+
let krate = find_builtin_crate(db, id);
235+
expand_simple_derive(tt, quote! { #krate::cmp::Eq })
202236
}
203237

204238
fn partial_eq_expand(
205-
_db: &dyn AstDatabase,
206-
_id: LazyMacroId,
239+
db: &dyn AstDatabase,
240+
id: LazyMacroId,
207241
tt: &tt::Subtree,
208242
) -> Result<tt::Subtree, mbe::ExpandError> {
209-
expand_simple_derive(tt, quote! { std::cmp::PartialEq })
243+
let krate = find_builtin_crate(db, id);
244+
expand_simple_derive(tt, quote! { #krate::cmp::PartialEq })
210245
}
211246

212247
fn ord_expand(
213-
_db: &dyn AstDatabase,
214-
_id: LazyMacroId,
248+
db: &dyn AstDatabase,
249+
id: LazyMacroId,
215250
tt: &tt::Subtree,
216251
) -> Result<tt::Subtree, mbe::ExpandError> {
217-
expand_simple_derive(tt, quote! { std::cmp::Ord })
252+
let krate = find_builtin_crate(db, id);
253+
expand_simple_derive(tt, quote! { #krate::cmp::Ord })
218254
}
219255

220256
fn partial_ord_expand(
221-
_db: &dyn AstDatabase,
222-
_id: LazyMacroId,
257+
db: &dyn AstDatabase,
258+
id: LazyMacroId,
223259
tt: &tt::Subtree,
224260
) -> Result<tt::Subtree, mbe::ExpandError> {
225-
expand_simple_derive(tt, quote! { std::cmp::PartialOrd })
261+
let krate = find_builtin_crate(db, id);
262+
expand_simple_derive(tt, quote! { #krate::cmp::PartialOrd })
226263
}
227264

228265
#[cfg(test)]
@@ -234,8 +271,18 @@ mod tests {
234271

235272
fn expand_builtin_derive(s: &str, name: Name) -> String {
236273
let def = find_builtin_derive(&name).unwrap();
274+
let fixture = format!(
275+
r#"//- /main.rs crate:main deps:core
276+
<|>
277+
{}
278+
//- /lib.rs crate:core
279+
// empty
280+
"#,
281+
s
282+
);
237283

238-
let (db, file_id) = TestDB::with_single_file(&s);
284+
let (db, file_pos) = TestDB::with_position(&fixture);
285+
let file_id = file_pos.file_id;
239286
let parsed = db.parse(file_id);
240287
let items: Vec<_> =
241288
parsed.syntax_node().descendants().filter_map(ast::ModuleItem::cast).collect();
@@ -264,7 +311,7 @@ mod tests {
264311
known::Copy,
265312
);
266313

267-
assert_eq!(expanded, "impl< >std::marker::CopyforFoo< >{}");
314+
assert_eq!(expanded, "impl< >core::marker::CopyforFoo< >{}");
268315
}
269316

270317
#[test]
@@ -279,7 +326,7 @@ mod tests {
279326

280327
assert_eq!(
281328
expanded,
282-
"impl<T0:std::marker::Copy,T1:std::marker::Copy>std::marker::CopyforFoo<T0,T1>{}"
329+
"impl<T0:core::marker::Copy,T1:core::marker::Copy>core::marker::CopyforFoo<T0,T1>{}"
283330
);
284331
}
285332

@@ -297,7 +344,7 @@ mod tests {
297344

298345
assert_eq!(
299346
expanded,
300-
"impl<T0:std::marker::Copy,T1:std::marker::Copy>std::marker::CopyforFoo<T0,T1>{}"
347+
"impl<T0:core::marker::Copy,T1:core::marker::Copy>core::marker::CopyforFoo<T0,T1>{}"
301348
);
302349
}
303350

@@ -313,7 +360,7 @@ mod tests {
313360

314361
assert_eq!(
315362
expanded,
316-
"impl<T0:std::clone::Clone,T1:std::clone::Clone>std::clone::CloneforFoo<T0,T1>{}"
363+
"impl<T0:core::clone::Clone,T1:core::clone::Clone>core::clone::CloneforFoo<T0,T1>{}"
317364
);
318365
}
319366
}

crates/ra_hir_ty/src/tests/macros.rs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -622,14 +622,14 @@ fn main() {
622622
fn infer_derive_clone_simple() {
623623
let (db, pos) = TestDB::with_position(
624624
r#"
625-
//- /main.rs crate:main deps:std
625+
//- /main.rs crate:main deps:core
626626
#[derive(Clone)]
627627
struct S;
628628
fn test() {
629629
S.clone()<|>;
630630
}
631631
632-
//- /lib.rs crate:std
632+
//- /lib.rs crate:core
633633
#[prelude_import]
634634
use clone::*;
635635
mod clone {
@@ -642,11 +642,36 @@ mod clone {
642642
assert_eq!("S", type_at_pos(&db, pos));
643643
}
644644

645+
#[test]
646+
fn infer_derive_clone_in_core() {
647+
let (db, pos) = TestDB::with_position(
648+
r#"
649+
//- /lib.rs crate:core
650+
#[prelude_import]
651+
use clone::*;
652+
mod clone {
653+
trait Clone {
654+
fn clone(&self) -> Self;
655+
}
656+
}
657+
#[derive(Clone)]
658+
pub struct S;
659+
660+
//- /main.rs crate:main deps:core
661+
use core::S;
662+
fn test() {
663+
S.clone()<|>;
664+
}
665+
"#,
666+
);
667+
assert_eq!("S", type_at_pos(&db, pos));
668+
}
669+
645670
#[test]
646671
fn infer_derive_clone_with_params() {
647672
let (db, pos) = TestDB::with_position(
648673
r#"
649-
//- /main.rs crate:main deps:std
674+
//- /main.rs crate:main deps:core
650675
#[derive(Clone)]
651676
struct S;
652677
#[derive(Clone)]
@@ -656,7 +681,7 @@ fn test() {
656681
(Wrapper(S).clone(), Wrapper(NonClone).clone())<|>;
657682
}
658683
659-
//- /lib.rs crate:std
684+
//- /lib.rs crate:core
660685
#[prelude_import]
661686
use clone::*;
662687
mod clone {

0 commit comments

Comments
 (0)