Builtin derives are hygienic
This commit is contained in:
parent
af40101841
commit
7dd9f20ce3
@ -16,13 +16,12 @@ fn test_copy_expand_simple() {
|
||||
#[derive(Copy)]
|
||||
struct Foo;
|
||||
|
||||
impl < > core::marker::Copy for Foo< > where {}"#]],
|
||||
impl < > $crate::marker::Copy for Foo< > where {}"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_copy_expand_in_core() {
|
||||
cov_mark::check!(test_copy_expand_in_core);
|
||||
check(
|
||||
r#"
|
||||
//- /lib.rs crate:core
|
||||
@ -41,7 +40,7 @@ fn test_copy_expand_in_core() {
|
||||
#[derive(Copy)]
|
||||
struct Foo;
|
||||
|
||||
impl < > crate ::marker::Copy for Foo< > where {}"#]],
|
||||
impl < > $crate::marker::Copy for Foo< > where {}"#]],
|
||||
);
|
||||
}
|
||||
|
||||
@ -57,7 +56,7 @@ fn test_copy_expand_with_type_params() {
|
||||
#[derive(Copy)]
|
||||
struct Foo<A, B>;
|
||||
|
||||
impl <A: core::marker::Copy, B: core::marker::Copy, > core::marker::Copy for Foo<A, B, > where {}"#]],
|
||||
impl <A: $crate::marker::Copy, B: $crate::marker::Copy, > $crate::marker::Copy for Foo<A, B, > where {}"#]],
|
||||
);
|
||||
}
|
||||
|
||||
@ -74,7 +73,7 @@ fn test_copy_expand_with_lifetimes() {
|
||||
#[derive(Copy)]
|
||||
struct Foo<A, B, 'a, 'b>;
|
||||
|
||||
impl <A: core::marker::Copy, B: core::marker::Copy, > core::marker::Copy for Foo<A, B, > where {}"#]],
|
||||
impl <A: $crate::marker::Copy, B: $crate::marker::Copy, > $crate::marker::Copy for Foo<A, B, > where {}"#]],
|
||||
);
|
||||
}
|
||||
|
||||
@ -98,7 +97,7 @@ enum Command<A, B> {
|
||||
Jump,
|
||||
}
|
||||
|
||||
impl <A: core::clone::Clone, B: core::clone::Clone, > core::clone::Clone for Command<A, B, > where {
|
||||
impl <A: $crate::clone::Clone, B: $crate::clone::Clone, > $crate::clone::Clone for Command<A, B, > where {
|
||||
fn clone(&self ) -> Self {
|
||||
match self {
|
||||
Command::Move {
|
||||
@ -158,7 +157,7 @@ struct Foo<T: Trait>
|
||||
generic: Vec<T::InGenericArg>,
|
||||
}
|
||||
|
||||
impl <T: core::clone::Clone, > core::clone::Clone for Foo<T, > where T: Trait, T::InFieldShorthand: core::clone::Clone, T::InGenericArg: core::clone::Clone, {
|
||||
impl <T: $crate::clone::Clone, > $crate::clone::Clone for Foo<T, > where T: Trait, T::InFieldShorthand: $crate::clone::Clone, T::InGenericArg: $crate::clone::Clone, {
|
||||
fn clone(&self ) -> Self {
|
||||
match self {
|
||||
Foo {
|
||||
@ -186,7 +185,7 @@ fn test_clone_expand_with_const_generics() {
|
||||
#[derive(Clone)]
|
||||
struct Foo<const X: usize, T>(u32);
|
||||
|
||||
impl <const X: usize, T: core::clone::Clone, > core::clone::Clone for Foo<X, T, > where {
|
||||
impl <const X: usize, T: $crate::clone::Clone, > $crate::clone::Clone for Foo<X, T, > where {
|
||||
fn clone(&self ) -> Self {
|
||||
match self {
|
||||
Foo(f0, )=>Foo(f0.clone(), ),
|
||||
@ -226,14 +225,14 @@ enum Bar {
|
||||
Bar,
|
||||
}
|
||||
|
||||
impl < > core::default::Default for Foo< > where {
|
||||
impl < > $crate::default::Default for Foo< > where {
|
||||
fn default() -> Self {
|
||||
Foo {
|
||||
field1: core::default::Default::default(), field2: core::default::Default::default(),
|
||||
field1: $crate::default::Default::default(), field2: $crate::default::Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl < > core::default::Default for Bar< > where {
|
||||
impl < > $crate::default::Default for Bar< > where {
|
||||
fn default() -> Self {
|
||||
Bar::Bar
|
||||
}
|
||||
@ -261,7 +260,7 @@ enum Command {
|
||||
Jump,
|
||||
}
|
||||
|
||||
impl < > core::cmp::PartialEq for Command< > where {
|
||||
impl < > $crate::cmp::PartialEq for Command< > where {
|
||||
fn eq(&self , other: &Self ) -> bool {
|
||||
match (self , other) {
|
||||
(Command::Move {
|
||||
@ -274,7 +273,7 @@ fn eq(&self , other: &Self ) -> bool {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl < > core::cmp::Eq for Command< > where {}"#]],
|
||||
impl < > $crate::cmp::Eq for Command< > where {}"#]],
|
||||
);
|
||||
}
|
||||
|
||||
@ -299,7 +298,7 @@ enum Command {
|
||||
Jump,
|
||||
}
|
||||
|
||||
impl < > core::cmp::PartialEq for Command< > where {
|
||||
impl < > $crate::cmp::PartialEq for Command< > where {
|
||||
fn eq(&self , other: &Self ) -> bool {
|
||||
match (self , other) {
|
||||
(Command::Move {
|
||||
@ -312,7 +311,7 @@ fn eq(&self , other: &Self ) -> bool {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl < > core::cmp::Eq for Command< > where {}"#]],
|
||||
impl < > $crate::cmp::Eq for Command< > where {}"#]],
|
||||
);
|
||||
}
|
||||
|
||||
@ -336,10 +335,10 @@ enum Command {
|
||||
Jump,
|
||||
}
|
||||
|
||||
impl < > core::cmp::PartialOrd for Command< > where {
|
||||
fn partial_cmp(&self , other: &Self ) -> core::option::Option::Option<core::cmp::Ordering> {
|
||||
match core::intrinsics::discriminant_value(self ).partial_cmp(&core::intrinsics::discriminant_value(other)) {
|
||||
core::option::Option::Some(core::cmp::Ordering::Equal)=> {
|
||||
impl < > $crate::cmp::PartialOrd for Command< > where {
|
||||
fn partial_cmp(&self , other: &Self ) -> $crate::option::Option::Option<$crate::cmp::Ordering> {
|
||||
match $crate::intrinsics::discriminant_value(self ).partial_cmp(&$crate::intrinsics::discriminant_value(other)) {
|
||||
$crate::option::Option::Some($crate::cmp::Ordering::Equal)=> {
|
||||
match (self , other) {
|
||||
(Command::Move {
|
||||
x: x_self, y: y_self,
|
||||
@ -348,10 +347,10 @@ fn partial_cmp(&self , other: &Self ) -> core::option::Option::Option<core::cmp:
|
||||
x: x_other, y: y_other,
|
||||
}
|
||||
)=>match x_self.partial_cmp(&x_other) {
|
||||
core::option::Option::Some(core::cmp::Ordering::Equal)=> {
|
||||
$crate::option::Option::Some($crate::cmp::Ordering::Equal)=> {
|
||||
match y_self.partial_cmp(&y_other) {
|
||||
core::option::Option::Some(core::cmp::Ordering::Equal)=> {
|
||||
core::option::Option::Some(core::cmp::Ordering::Equal)
|
||||
$crate::option::Option::Some($crate::cmp::Ordering::Equal)=> {
|
||||
$crate::option::Option::Some($crate::cmp::Ordering::Equal)
|
||||
}
|
||||
c=>return c,
|
||||
}
|
||||
@ -359,22 +358,22 @@ fn partial_cmp(&self , other: &Self ) -> core::option::Option::Option<core::cmp:
|
||||
c=>return c,
|
||||
}
|
||||
, (Command::Do(f0_self, ), Command::Do(f0_other, ))=>match f0_self.partial_cmp(&f0_other) {
|
||||
core::option::Option::Some(core::cmp::Ordering::Equal)=> {
|
||||
core::option::Option::Some(core::cmp::Ordering::Equal)
|
||||
$crate::option::Option::Some($crate::cmp::Ordering::Equal)=> {
|
||||
$crate::option::Option::Some($crate::cmp::Ordering::Equal)
|
||||
}
|
||||
c=>return c,
|
||||
}
|
||||
, (Command::Jump, Command::Jump)=>core::option::Option::Some(core::cmp::Ordering::Equal), _unused=>core::option::Option::Some(core::cmp::Ordering::Equal)
|
||||
, (Command::Jump, Command::Jump)=>$crate::option::Option::Some($crate::cmp::Ordering::Equal), _unused=>$crate::option::Option::Some($crate::cmp::Ordering::Equal)
|
||||
}
|
||||
}
|
||||
c=>return c,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl < > core::cmp::Ord for Command< > where {
|
||||
fn cmp(&self , other: &Self ) -> core::cmp::Ordering {
|
||||
match core::intrinsics::discriminant_value(self ).cmp(&core::intrinsics::discriminant_value(other)) {
|
||||
core::cmp::Ordering::Equal=> {
|
||||
impl < > $crate::cmp::Ord for Command< > where {
|
||||
fn cmp(&self , other: &Self ) -> $crate::cmp::Ordering {
|
||||
match $crate::intrinsics::discriminant_value(self ).cmp(&$crate::intrinsics::discriminant_value(other)) {
|
||||
$crate::cmp::Ordering::Equal=> {
|
||||
match (self , other) {
|
||||
(Command::Move {
|
||||
x: x_self, y: y_self,
|
||||
@ -383,10 +382,10 @@ fn cmp(&self , other: &Self ) -> core::cmp::Ordering {
|
||||
x: x_other, y: y_other,
|
||||
}
|
||||
)=>match x_self.cmp(&x_other) {
|
||||
core::cmp::Ordering::Equal=> {
|
||||
$crate::cmp::Ordering::Equal=> {
|
||||
match y_self.cmp(&y_other) {
|
||||
core::cmp::Ordering::Equal=> {
|
||||
core::cmp::Ordering::Equal
|
||||
$crate::cmp::Ordering::Equal=> {
|
||||
$crate::cmp::Ordering::Equal
|
||||
}
|
||||
c=>return c,
|
||||
}
|
||||
@ -394,12 +393,12 @@ fn cmp(&self , other: &Self ) -> core::cmp::Ordering {
|
||||
c=>return c,
|
||||
}
|
||||
, (Command::Do(f0_self, ), Command::Do(f0_other, ))=>match f0_self.cmp(&f0_other) {
|
||||
core::cmp::Ordering::Equal=> {
|
||||
core::cmp::Ordering::Equal
|
||||
$crate::cmp::Ordering::Equal=> {
|
||||
$crate::cmp::Ordering::Equal
|
||||
}
|
||||
c=>return c,
|
||||
}
|
||||
, (Command::Jump, Command::Jump)=>core::cmp::Ordering::Equal, _unused=>core::cmp::Ordering::Equal
|
||||
, (Command::Jump, Command::Jump)=>$crate::cmp::Ordering::Equal, _unused=>$crate::cmp::Ordering::Equal
|
||||
}
|
||||
}
|
||||
c=>return c,
|
||||
@ -433,8 +432,8 @@ struct Foo {
|
||||
z: (i32, u64),
|
||||
}
|
||||
|
||||
impl < > core::hash::Hash for Foo< > where {
|
||||
fn hash<H: core::hash::Hasher>(&self , ra_expand_state: &mut H) {
|
||||
impl < > $crate::hash::Hash for Foo< > where {
|
||||
fn hash<H: $crate::hash::Hasher>(&self , ra_expand_state: &mut H) {
|
||||
match self {
|
||||
Foo {
|
||||
x: x, y: y, z: z,
|
||||
@ -471,9 +470,9 @@ enum Command {
|
||||
Jump,
|
||||
}
|
||||
|
||||
impl < > core::hash::Hash for Command< > where {
|
||||
fn hash<H: core::hash::Hasher>(&self , ra_expand_state: &mut H) {
|
||||
core::mem::discriminant(self ).hash(ra_expand_state);
|
||||
impl < > $crate::hash::Hash for Command< > where {
|
||||
fn hash<H: $crate::hash::Hasher>(&self , ra_expand_state: &mut H) {
|
||||
$crate::mem::discriminant(self ).hash(ra_expand_state);
|
||||
match self {
|
||||
Command::Move {
|
||||
x: x, y: y,
|
||||
@ -517,8 +516,8 @@ enum Command {
|
||||
Jump,
|
||||
}
|
||||
|
||||
impl < > core::fmt::Debug for Command< > where {
|
||||
fn fmt(&self , f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
impl < > $crate::fmt::Debug for Command< > where {
|
||||
fn fmt(&self , f: &mut $crate::fmt::Formatter) -> $crate::fmt::Result {
|
||||
match self {
|
||||
Command::Move {
|
||||
x: x, y: y,
|
||||
|
@ -136,7 +136,7 @@ macro_rules! option_env {() => {}}
|
||||
#[rustc_builtin_macro]
|
||||
macro_rules! option_env {() => {}}
|
||||
|
||||
fn main() { ::core::option::Option::None:: < &str>; }
|
||||
fn main() { $crate::option::Option::None:: < &str>; }
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
//! Builtin derives.
|
||||
|
||||
use base_db::{CrateOrigin, LangCrateOrigin};
|
||||
use itertools::izip;
|
||||
use rustc_hash::FxHashSet;
|
||||
use span::{MacroCallId, Span};
|
||||
@ -10,6 +9,7 @@
|
||||
use crate::{
|
||||
hygiene::span_with_def_site_ctxt,
|
||||
name::{AsName, Name},
|
||||
quote::dollar_crate,
|
||||
span_map::SpanMapRef,
|
||||
tt,
|
||||
};
|
||||
@ -38,7 +38,7 @@ pub fn expand(
|
||||
|
||||
let span = db.lookup_intern_macro_call(id).call_site;
|
||||
let span = span_with_def_site_ctxt(db, span, id);
|
||||
expander(db, id, span, tt, token_map)
|
||||
expander(span, tt, token_map)
|
||||
}
|
||||
|
||||
fn find_by_name(name: &name::Name) -> Option<Self> {
|
||||
@ -398,41 +398,13 @@ impl < ##params > #trait_path for #name < ##args > where ##where_block { #trait_
|
||||
ExpandResult::ok(expanded)
|
||||
}
|
||||
|
||||
fn find_builtin_crate(db: &dyn ExpandDatabase, id: MacroCallId, span: Span) -> tt::TokenTree {
|
||||
// FIXME: make hygiene works for builtin derive macro
|
||||
// such that $crate can be used here.
|
||||
let cg = db.crate_graph();
|
||||
let krate = db.lookup_intern_macro_call(id).krate;
|
||||
|
||||
let tt = if matches!(cg[krate].origin, CrateOrigin::Lang(LangCrateOrigin::Core)) {
|
||||
cov_mark::hit!(test_copy_expand_in_core);
|
||||
quote! {span => crate }
|
||||
} else {
|
||||
quote! {span => core }
|
||||
};
|
||||
|
||||
tt.token_trees[0].clone()
|
||||
}
|
||||
|
||||
fn copy_expand(
|
||||
db: &dyn ExpandDatabase,
|
||||
id: MacroCallId,
|
||||
span: Span,
|
||||
tt: &ast::Adt,
|
||||
tm: SpanMapRef<'_>,
|
||||
) -> ExpandResult<tt::Subtree> {
|
||||
let krate = find_builtin_crate(db, id, span);
|
||||
fn copy_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult<tt::Subtree> {
|
||||
let krate = dollar_crate(span);
|
||||
expand_simple_derive(span, tt, tm, quote! {span => #krate::marker::Copy }, |_| quote! {span =>})
|
||||
}
|
||||
|
||||
fn clone_expand(
|
||||
db: &dyn ExpandDatabase,
|
||||
id: MacroCallId,
|
||||
span: Span,
|
||||
tt: &ast::Adt,
|
||||
tm: SpanMapRef<'_>,
|
||||
) -> ExpandResult<tt::Subtree> {
|
||||
let krate = find_builtin_crate(db, id, span);
|
||||
fn clone_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult<tt::Subtree> {
|
||||
let krate = dollar_crate(span);
|
||||
expand_simple_derive(span, tt, tm, quote! {span => #krate::clone::Clone }, |adt| {
|
||||
if matches!(adt.shape, AdtShape::Union) {
|
||||
let star = tt::Punct { char: '*', spacing: ::tt::Spacing::Alone, span };
|
||||
@ -482,14 +454,8 @@ fn and_and(span: Span) -> tt::Subtree {
|
||||
quote! {span => #and& }
|
||||
}
|
||||
|
||||
fn default_expand(
|
||||
db: &dyn ExpandDatabase,
|
||||
id: MacroCallId,
|
||||
span: Span,
|
||||
tt: &ast::Adt,
|
||||
tm: SpanMapRef<'_>,
|
||||
) -> ExpandResult<tt::Subtree> {
|
||||
let krate = &find_builtin_crate(db, id, span);
|
||||
fn default_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult<tt::Subtree> {
|
||||
let krate = &dollar_crate(span);
|
||||
expand_simple_derive(span, tt, tm, quote! {span => #krate::default::Default }, |adt| {
|
||||
let body = match &adt.shape {
|
||||
AdtShape::Struct(fields) => {
|
||||
@ -527,14 +493,8 @@ fn default() -> Self {
|
||||
})
|
||||
}
|
||||
|
||||
fn debug_expand(
|
||||
db: &dyn ExpandDatabase,
|
||||
id: MacroCallId,
|
||||
span: Span,
|
||||
tt: &ast::Adt,
|
||||
tm: SpanMapRef<'_>,
|
||||
) -> ExpandResult<tt::Subtree> {
|
||||
let krate = &find_builtin_crate(db, id, span);
|
||||
fn debug_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult<tt::Subtree> {
|
||||
let krate = &dollar_crate(span);
|
||||
expand_simple_derive(span, tt, tm, quote! {span => #krate::fmt::Debug }, |adt| {
|
||||
let for_variant = |name: String, v: &VariantShape| match v {
|
||||
VariantShape::Struct(fields) => {
|
||||
@ -605,14 +565,8 @@ fn fmt(&self, f: &mut #krate::fmt::Formatter) -> #krate::fmt::Result {
|
||||
})
|
||||
}
|
||||
|
||||
fn hash_expand(
|
||||
db: &dyn ExpandDatabase,
|
||||
id: MacroCallId,
|
||||
span: Span,
|
||||
tt: &ast::Adt,
|
||||
tm: SpanMapRef<'_>,
|
||||
) -> ExpandResult<tt::Subtree> {
|
||||
let krate = &find_builtin_crate(db, id, span);
|
||||
fn hash_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult<tt::Subtree> {
|
||||
let krate = &dollar_crate(span);
|
||||
expand_simple_derive(span, tt, tm, quote! {span => #krate::hash::Hash }, |adt| {
|
||||
if matches!(adt.shape, AdtShape::Union) {
|
||||
// FIXME: Return expand error here
|
||||
@ -658,25 +612,13 @@ fn hash<H: #krate::hash::Hasher>(&self, ra_expand_state: &mut H) {
|
||||
})
|
||||
}
|
||||
|
||||
fn eq_expand(
|
||||
db: &dyn ExpandDatabase,
|
||||
id: MacroCallId,
|
||||
span: Span,
|
||||
tt: &ast::Adt,
|
||||
tm: SpanMapRef<'_>,
|
||||
) -> ExpandResult<tt::Subtree> {
|
||||
let krate = find_builtin_crate(db, id, span);
|
||||
fn eq_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult<tt::Subtree> {
|
||||
let krate = dollar_crate(span);
|
||||
expand_simple_derive(span, tt, tm, quote! {span => #krate::cmp::Eq }, |_| quote! {span =>})
|
||||
}
|
||||
|
||||
fn partial_eq_expand(
|
||||
db: &dyn ExpandDatabase,
|
||||
id: MacroCallId,
|
||||
span: Span,
|
||||
tt: &ast::Adt,
|
||||
tm: SpanMapRef<'_>,
|
||||
) -> ExpandResult<tt::Subtree> {
|
||||
let krate = find_builtin_crate(db, id, span);
|
||||
fn partial_eq_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult<tt::Subtree> {
|
||||
let krate = dollar_crate(span);
|
||||
expand_simple_derive(span, tt, tm, quote! {span => #krate::cmp::PartialEq }, |adt| {
|
||||
if matches!(adt.shape, AdtShape::Union) {
|
||||
// FIXME: Return expand error here
|
||||
@ -747,17 +689,11 @@ fn self_and_other_patterns(
|
||||
(self_patterns, other_patterns)
|
||||
}
|
||||
|
||||
fn ord_expand(
|
||||
db: &dyn ExpandDatabase,
|
||||
id: MacroCallId,
|
||||
span: Span,
|
||||
tt: &ast::Adt,
|
||||
tm: SpanMapRef<'_>,
|
||||
) -> ExpandResult<tt::Subtree> {
|
||||
let krate = &find_builtin_crate(db, id, span);
|
||||
fn ord_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult<tt::Subtree> {
|
||||
let krate = &dollar_crate(span);
|
||||
expand_simple_derive(span, tt, tm, quote! {span => #krate::cmp::Ord }, |adt| {
|
||||
fn compare(
|
||||
krate: &tt::TokenTree,
|
||||
krate: &tt::Ident,
|
||||
left: tt::Subtree,
|
||||
right: tt::Subtree,
|
||||
rest: tt::Subtree,
|
||||
@ -811,17 +747,11 @@ fn cmp(&self, other: &Self) -> #krate::cmp::Ordering {
|
||||
})
|
||||
}
|
||||
|
||||
fn partial_ord_expand(
|
||||
db: &dyn ExpandDatabase,
|
||||
id: MacroCallId,
|
||||
span: Span,
|
||||
tt: &ast::Adt,
|
||||
tm: SpanMapRef<'_>,
|
||||
) -> ExpandResult<tt::Subtree> {
|
||||
let krate = &find_builtin_crate(db, id, span);
|
||||
fn partial_ord_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult<tt::Subtree> {
|
||||
let krate = &dollar_crate(span);
|
||||
expand_simple_derive(span, tt, tm, quote! {span => #krate::cmp::PartialOrd }, |adt| {
|
||||
fn compare(
|
||||
krate: &tt::TokenTree,
|
||||
krate: &tt::Ident,
|
||||
left: tt::Subtree,
|
||||
right: tt::Subtree,
|
||||
rest: tt::Subtree,
|
||||
|
@ -6,16 +6,14 @@
|
||||
use itertools::Itertools;
|
||||
use mbe::{parse_exprs_with_sep, parse_to_token_tree};
|
||||
use span::{Span, SpanAnchor, SyntaxContextId, ROOT_ERASED_FILE_AST_ID};
|
||||
use syntax::{
|
||||
ast::{self, AstToken},
|
||||
SmolStr,
|
||||
};
|
||||
use syntax::ast::{self, AstToken};
|
||||
|
||||
use crate::{
|
||||
db::ExpandDatabase,
|
||||
hygiene::{span_with_call_site_ctxt, span_with_def_site_ctxt},
|
||||
name::{self, known},
|
||||
quote,
|
||||
quote::dollar_crate,
|
||||
tt::{self, DelimSpan},
|
||||
ExpandError, ExpandResult, HirFileIdExt, MacroCallId,
|
||||
};
|
||||
@ -205,7 +203,7 @@ fn assert_expand(
|
||||
) -> ExpandResult<tt::Subtree> {
|
||||
let call_site_span = span_with_call_site_ctxt(db, span, id);
|
||||
let args = parse_exprs_with_sep(tt, ',', call_site_span);
|
||||
let dollar_crate = tt::Ident { text: SmolStr::new_inline("$crate"), span };
|
||||
let dollar_crate = dollar_crate(span);
|
||||
let expanded = match &*args {
|
||||
[cond, panic_args @ ..] => {
|
||||
let comma = tt::Subtree {
|
||||
@ -300,7 +298,7 @@ fn asm_expand(
|
||||
[tt::TokenTree::Leaf(tt::Leaf::Literal(lit))]
|
||||
| [tt::TokenTree::Leaf(tt::Leaf::Literal(lit)), tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: ',', span: _, spacing: _ }))] =>
|
||||
{
|
||||
let dollar_krate = tt::Ident { text: SmolStr::new_inline("$crate"), span };
|
||||
let dollar_krate = dollar_crate(span);
|
||||
literals.push(quote!(span=>#dollar_krate::format_args!(#lit);));
|
||||
}
|
||||
_ => break,
|
||||
@ -345,7 +343,7 @@ fn panic_expand(
|
||||
tt: &tt::Subtree,
|
||||
span: Span,
|
||||
) -> ExpandResult<tt::Subtree> {
|
||||
let dollar_crate = tt::Ident { text: SmolStr::new_inline("$crate"), span };
|
||||
let dollar_crate = dollar_crate(span);
|
||||
let call_site_span = span_with_call_site_ctxt(db, span, id);
|
||||
|
||||
let mac =
|
||||
@ -371,7 +369,7 @@ fn unreachable_expand(
|
||||
tt: &tt::Subtree,
|
||||
span: Span,
|
||||
) -> ExpandResult<tt::Subtree> {
|
||||
let dollar_crate = tt::Ident { text: SmolStr::new_inline("$crate"), span };
|
||||
let dollar_crate = dollar_crate(span);
|
||||
let call_site_span = span_with_call_site_ctxt(db, span, id);
|
||||
|
||||
let mac = if use_panic_2021(db, call_site_span) {
|
||||
@ -763,10 +761,10 @@ fn option_env_expand(
|
||||
return ExpandResult::new(tt::Subtree::empty(DelimSpan { open: span, close: span }), e)
|
||||
}
|
||||
};
|
||||
// FIXME: Use `DOLLAR_CRATE` when that works in eager macros.
|
||||
let dollar_crate = dollar_crate(span);
|
||||
let expanded = match get_env_inner(db, arg_id, &key) {
|
||||
None => quote! {span => ::core::option::Option::None::<&str> },
|
||||
Some(s) => quote! {span => ::core::option::Option::Some(#s) },
|
||||
None => quote! {span => #dollar_crate::option::Option::None::<&str> },
|
||||
Some(s) => quote! {span => #dollar_crate::option::Option::Some(#s) },
|
||||
};
|
||||
|
||||
ExpandResult::ok(expanded)
|
||||
|
@ -4,6 +4,10 @@
|
||||
|
||||
use crate::name::Name;
|
||||
|
||||
pub(crate) fn dollar_crate(span: Span) -> tt::Ident<Span> {
|
||||
tt::Ident { text: syntax::SmolStr::new_inline("$crate"), span }
|
||||
}
|
||||
|
||||
// A helper macro quote macro
|
||||
// FIXME:
|
||||
// 1. Not all puncts are handled
|
||||
|
@ -987,15 +987,12 @@ fn main() {
|
||||
fn infer_builtin_macros_option_env() {
|
||||
check_types(
|
||||
r#"
|
||||
//- minicore: option
|
||||
//- /main.rs env:foo=bar
|
||||
#[rustc_builtin_macro]
|
||||
macro_rules! option_env {() => {}}
|
||||
|
||||
fn main() {
|
||||
let x = option_env!("foo");
|
||||
//^ Option<&str>
|
||||
}
|
||||
//- minicore: env
|
||||
//- /main.rs env:foo=bar
|
||||
fn main() {
|
||||
let x = option_env!("foo");
|
||||
//^ Option<&str>
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
@ -1014,6 +1011,21 @@ fn test() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_builtin_derive_resolves_with_core_module() {
|
||||
check_types(
|
||||
r#"
|
||||
//- minicore: derive, clone
|
||||
mod core {}
|
||||
#[derive(Clone)]
|
||||
struct S;
|
||||
fn test() {
|
||||
S.clone();
|
||||
} //^^^^^^^^^ S
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_derive_clone_with_params() {
|
||||
check_types(
|
||||
|
@ -481,7 +481,7 @@ struct Foo {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
Clone
|
||||
impl < >core::clone::Clone for Foo< >where {
|
||||
impl < >$crate::clone::Clone for Foo< >where {
|
||||
fn clone(&self) -> Self {
|
||||
match self {
|
||||
Foo{}
|
||||
@ -507,7 +507,7 @@ struct Foo {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
Copy
|
||||
impl < >core::marker::Copy for Foo< >where{}"#]],
|
||||
impl < >$crate::marker::Copy for Foo< >where{}"#]],
|
||||
);
|
||||
}
|
||||
|
||||
@ -522,7 +522,7 @@ struct Foo {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
Copy
|
||||
impl < >core::marker::Copy for Foo< >where{}"#]],
|
||||
impl < >$crate::marker::Copy for Foo< >where{}"#]],
|
||||
);
|
||||
check(
|
||||
r#"
|
||||
@ -533,7 +533,7 @@ struct Foo {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
Clone
|
||||
impl < >core::clone::Clone for Foo< >where {
|
||||
impl < >$crate::clone::Clone for Foo< >where {
|
||||
fn clone(&self) -> Self {
|
||||
match self {
|
||||
Foo{}
|
||||
|
@ -25,6 +25,7 @@
|
||||
//! derive:
|
||||
//! discriminant:
|
||||
//! drop:
|
||||
//! env: option
|
||||
//! eq: sized
|
||||
//! error: fmt
|
||||
//! fmt: result, transmute, coerce_unsized
|
||||
@ -1450,6 +1451,15 @@ macro_rules! include {
|
||||
#[macro_export]
|
||||
macro_rules! concat {}
|
||||
// endregion:concat
|
||||
|
||||
// region:env
|
||||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! env {}
|
||||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! option_env {}
|
||||
// endregion:env
|
||||
}
|
||||
|
||||
// region:non_zero
|
||||
|
Loading…
Reference in New Issue
Block a user