Skip to content

Commit

Permalink
Make edition per-token, not per-file
Browse files Browse the repository at this point in the history
More correctly, *also* per-token. Because as it turns out, while the top-level edition affects parsing (I think), the per-token edition affects escaping of identifiers/keywords.
  • Loading branch information
ChayimFriedman2 committed Jan 7, 2025
1 parent 3f2bbe9 commit 5103b4c
Show file tree
Hide file tree
Showing 31 changed files with 435 additions and 245 deletions.
1 change: 1 addition & 0 deletions crates/edition/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// This should live in a separate crate because we use it in both actual code and codegen.
use std::fmt;

// The syntax context stuff needs the discriminants to start from 0 and be consecutive.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(u8)]
pub enum Edition {
Expand Down
3 changes: 2 additions & 1 deletion crates/hir-def/src/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ use crate::{
pub struct HygieneId(pub(crate) span::SyntaxContextId);

impl HygieneId {
pub const ROOT: Self = Self(span::SyntaxContextId::ROOT);
// The edition doesn't matter here, we only use this for comparisons and to lookup the macro.
pub const ROOT: Self = Self(span::SyntaxContextId::root(Edition::Edition2015));

pub fn new(ctx: span::SyntaxContextId) -> Self {
Self(ctx)
Expand Down
4 changes: 2 additions & 2 deletions crates/hir-def/src/expander.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use hir_expand::{
ExpandResult, HirFileId, InFile, Lookup, MacroCallId,
};
use limit::Limit;
use span::SyntaxContextId;
use span::{Edition, SyntaxContextId};
use syntax::{ast, Parse};
use triomphe::Arc;

Expand Down Expand Up @@ -60,7 +60,7 @@ impl Expander {

pub fn syntax_context(&self) -> SyntaxContextId {
// FIXME:
SyntaxContextId::ROOT
SyntaxContextId::root(Edition::CURRENT)
}

pub fn enter_expand<T: ast::AstNode>(
Expand Down
2 changes: 1 addition & 1 deletion crates/hir-def/src/item_tree/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ m!();
// AstId: 2
pub macro m2 { ... }
// AstId: 3, SyntaxContext: 0, ExpandTo: Items
// AstId: 3, SyntaxContext: 2, ExpandTo: Items
m!(...);
"#]],
);
Expand Down
30 changes: 15 additions & 15 deletions crates/hir-def/src/macro_expansion_tests/mbe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ macro_rules! f {
};
}
struct#0:1@58..64#1# MyTraitMap2#0:2@31..42#0# {#0:1@72..73#1#
map#0:1@86..89#1#:#0:1@89..90#1# #0:1@89..90#1#::#0:1@91..93#1#std#0:1@93..96#1#::#0:1@96..98#1#collections#0:1@98..109#1#::#0:1@109..111#1#HashSet#0:1@111..118#1#<#0:1@118..119#1#(#0:1@119..120#1#)#0:1@120..121#1#>#0:1@121..122#1#,#0:1@122..123#1#
}#0:1@132..133#1#
struct#0:1@58..64#4# MyTraitMap2#0:2@31..42#2# {#0:1@72..73#4#
map#0:1@86..89#4#:#0:1@89..90#4# #0:1@89..90#4#::#0:1@91..93#4#std#0:1@93..96#4#::#0:1@96..98#4#collections#0:1@98..109#4#::#0:1@109..111#4#HashSet#0:1@111..118#4#<#0:1@118..119#4#(#0:1@119..120#4#)#0:1@120..121#4#>#0:1@121..122#4#,#0:1@122..123#4#
}#0:1@132..133#4#
"#]],
);
}
Expand Down Expand Up @@ -75,12 +75,12 @@ macro_rules! f {
};
}
fn#0:2@30..32#0# main#0:2@33..37#0#(#0:2@37..38#0#)#0:2@38..39#0# {#0:2@40..41#0#
1#0:2@50..51#0#;#0:2@51..52#0#
1.0#0:2@61..64#0#;#0:2@64..65#0#
(#0:2@74..75#0#(#0:2@75..76#0#1#0:2@76..77#0#,#0:2@77..78#0# )#0:2@78..79#0#,#0:2@79..80#0# )#0:2@80..81#0#.#0:2@81..82#0#0#0:2@82..85#0#.#0:2@82..85#0#0#0:2@82..85#0#;#0:2@85..86#0#
let#0:2@95..98#0# x#0:2@99..100#0# =#0:2@101..102#0# 1#0:2@103..104#0#;#0:2@104..105#0#
}#0:2@110..111#0#
fn#0:2@30..32#2# main#0:2@33..37#2#(#0:2@37..38#2#)#0:2@38..39#2# {#0:2@40..41#2#
1#0:2@50..51#2#;#0:2@51..52#2#
1.0#0:2@61..64#2#;#0:2@64..65#2#
(#0:2@74..75#2#(#0:2@75..76#2#1#0:2@76..77#2#,#0:2@77..78#2# )#0:2@78..79#2#,#0:2@79..80#2# )#0:2@80..81#2#.#0:2@81..82#2#0#0:2@82..85#2#.#0:2@82..85#2#0#0:2@82..85#2#;#0:2@85..86#2#
let#0:2@95..98#2# x#0:2@99..100#2# =#0:2@101..102#2# 1#0:2@103..104#2#;#0:2@104..105#2#
}#0:2@110..111#2#
"#]],
Expand Down Expand Up @@ -171,7 +171,7 @@ fn main(foo: ()) {
}
fn main(foo: ()) {
/* error: unresolved macro unresolved */"helloworld!"#0:3@236..321#0#;
/* error: unresolved macro unresolved */"helloworld!"#0:3@236..321#2#;
}
}
Expand All @@ -197,7 +197,7 @@ macro_rules! mk_struct {
#[macro_use]
mod foo;
struct#1:1@59..65#1# Foo#0:2@32..35#0#(#1:1@70..71#1#u32#0:2@41..44#0#)#1:1@74..75#1#;#1:1@75..76#1#
struct#1:1@59..65#4# Foo#0:2@32..35#2#(#1:1@70..71#4#u32#0:2@41..44#2#)#1:1@74..75#4#;#1:1@75..76#4#
"#]],
);
}
Expand Down Expand Up @@ -423,10 +423,10 @@ m! { foo, bar }
macro_rules! m {
($($i:ident),*) => ( impl Bar { $(fn $i() {})* } );
}
impl#\1# Bar#\1# {#\1#
fn#\1# foo#\0#(#\1#)#\1# {#\1#}#\1#
fn#\1# bar#\0#(#\1#)#\1# {#\1#}#\1#
}#\1#
impl#\4# Bar#\4# {#\4#
fn#\4# foo#\2#(#\4#)#\4# {#\4#}#\4#
fn#\4# bar#\2#(#\4#)#\4# {#\4#}#\4#
}#\4#
"#]],
);
}
Expand Down
1 change: 1 addition & 0 deletions crates/hir-def/src/macro_expansion_tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ impl ProcMacroExpander for IdentityWhenValidProcMacroExpander {
let (parse, _) = syntax_bridge::token_tree_to_syntax_node(
subtree,
syntax_bridge::TopEntryPoint::MacroItems,
&mut |_| span::Edition::CURRENT,
span::Edition::CURRENT,
);
if parse.errors().is_empty() {
Expand Down
6 changes: 3 additions & 3 deletions crates/hir-def/src/macro_expansion_tests/proc_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,9 @@ fn foo(&self) {
self.0. 1;
}
fn#0:1@45..47#0# foo#0:1@48..51#0#(#0:1@51..52#0#&#0:1@52..53#0#self#0:1@53..57#0# )#0:1@57..58#0# {#0:1@59..60#0#
self#0:1@65..69#0# .#0:1@69..70#0#0#0:1@70..71#0#.#0:1@71..72#0#1#0:1@73..74#0#;#0:1@74..75#0#
}#0:1@76..77#0#"#]],
fn#0:1@45..47#2# foo#0:1@48..51#2#(#0:1@51..52#2#&#0:1@52..53#2#self#0:1@53..57#2# )#0:1@57..58#2# {#0:1@59..60#2#
self#0:1@65..69#2# .#0:1@69..70#2#0#0:1@70..71#2#.#0:1@71..72#2#1#0:1@73..74#2#;#0:1@74..75#2#
}#0:1@76..77#2#"#]],
);
}

Expand Down
2 changes: 1 addition & 1 deletion crates/hir-def/src/nameres/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI

let proc_macros = if krate.is_proc_macro {
db.proc_macros()
.for_crate(def_map.krate, db.syntax_context(tree_id.file_id()))
.for_crate(def_map.krate, db.syntax_context(tree_id.file_id(), krate.edition))
.unwrap_or_default()
} else {
Default::default()
Expand Down
105 changes: 76 additions & 29 deletions crates/hir-expand/src/builtin/derive_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use intern::sym;
use itertools::{izip, Itertools};
use parser::SyntaxKind;
use rustc_hash::FxHashSet;
use span::{MacroCallId, Span, SyntaxContextId};
use span::{Edition, MacroCallId, Span, SyntaxContextId};
use stdx::never;
use syntax_bridge::DocCommentDesugarMode;
use tracing::debug;
Expand Down Expand Up @@ -33,7 +33,7 @@ macro_rules! register_builtin {
}

impl BuiltinDeriveExpander {
pub fn expander(&self) -> fn(Span, &tt::TopSubtree) -> ExpandResult<tt::TopSubtree> {
pub fn expander(&self) -> fn(&dyn ExpandDatabase, Span, &tt::TopSubtree) -> ExpandResult<tt::TopSubtree> {
match *self {
$( BuiltinDeriveExpander::$trait => $expand, )*
}
Expand All @@ -58,8 +58,8 @@ impl BuiltinDeriveExpander {
tt: &tt::TopSubtree,
span: Span,
) -> ExpandResult<tt::TopSubtree> {
let span = span_with_def_site_ctxt(db, span, id);
self.expander()(span, tt)
let span = span_with_def_site_ctxt(db, span, id, Edition::CURRENT);
self.expander()(db, span, tt)
}
}

Expand Down Expand Up @@ -226,8 +226,12 @@ struct AdtParam {
}

// FIXME: This whole thing needs a refactor. Each derive requires its special values, and the result is a mess.
fn parse_adt(tt: &tt::TopSubtree, call_site: Span) -> Result<BasicAdtInfo, ExpandError> {
let (adt, tm) = to_adt_syntax(tt, call_site)?;
fn parse_adt(
db: &dyn ExpandDatabase,
tt: &tt::TopSubtree,
call_site: Span,
) -> Result<BasicAdtInfo, ExpandError> {
let (adt, tm) = to_adt_syntax(db, tt, call_site)?;
parse_adt_from_syntax(&adt, &tm, call_site)
}

Expand Down Expand Up @@ -382,12 +386,14 @@ fn parse_adt_from_syntax(
}

fn to_adt_syntax(
db: &dyn ExpandDatabase,
tt: &tt::TopSubtree,
call_site: Span,
) -> Result<(ast::Adt, span::SpanMap<SyntaxContextId>), ExpandError> {
let (parsed, tm) = syntax_bridge::token_tree_to_syntax_node(
let (parsed, tm) = crate::db::token_tree_to_syntax_node(
db,
tt,
syntax_bridge::TopEntryPoint::MacroItems,
crate::ExpandTo::Items,
parser::Edition::CURRENT_FIXME,
);
let macro_items = ast::MacroItems::cast(parsed.syntax_node())
Expand Down Expand Up @@ -446,12 +452,13 @@ fn name_to_token(
/// where B1, ..., BN are the bounds given by `bounds_paths`. Z is a phantom type, and
/// therefore does not get bound by the derived trait.
fn expand_simple_derive(
db: &dyn ExpandDatabase,
invoc_span: Span,
tt: &tt::TopSubtree,
trait_path: tt::TopSubtree,
make_trait_body: impl FnOnce(&BasicAdtInfo) -> tt::TopSubtree,
) -> ExpandResult<tt::TopSubtree> {
let info = match parse_adt(tt, invoc_span) {
let info = match parse_adt(db, tt, invoc_span) {
Ok(info) => info,
Err(e) => {
return ExpandResult::new(
Expand Down Expand Up @@ -520,14 +527,22 @@ fn expand_simple_derive_with_parsed(
}
}

fn copy_expand(span: Span, tt: &tt::TopSubtree) -> ExpandResult<tt::TopSubtree> {
fn copy_expand(
db: &dyn ExpandDatabase,
span: Span,
tt: &tt::TopSubtree,
) -> ExpandResult<tt::TopSubtree> {
let krate = dollar_crate(span);
expand_simple_derive(span, tt, quote! {span => #krate::marker::Copy }, |_| quote! {span =>})
expand_simple_derive(db, span, tt, quote! {span => #krate::marker::Copy }, |_| quote! {span =>})
}

fn clone_expand(span: Span, tt: &tt::TopSubtree) -> ExpandResult<tt::TopSubtree> {
fn clone_expand(
db: &dyn ExpandDatabase,
span: Span,
tt: &tt::TopSubtree,
) -> ExpandResult<tt::TopSubtree> {
let krate = dollar_crate(span);
expand_simple_derive(span, tt, quote! {span => #krate::clone::Clone }, |adt| {
expand_simple_derive(db, span, tt, quote! {span => #krate::clone::Clone }, |adt| {
if matches!(adt.shape, AdtShape::Union) {
let star = tt::Punct { char: '*', spacing: ::tt::Spacing::Alone, span };
return quote! {span =>
Expand Down Expand Up @@ -576,9 +591,13 @@ fn and_and(span: Span) -> tt::TopSubtree {
quote! {span => #and& }
}

fn default_expand(span: Span, tt: &tt::TopSubtree) -> ExpandResult<tt::TopSubtree> {
fn default_expand(
db: &dyn ExpandDatabase,
span: Span,
tt: &tt::TopSubtree,
) -> ExpandResult<tt::TopSubtree> {
let krate = &dollar_crate(span);
expand_simple_derive(span, tt, quote! {span => #krate::default::Default }, |adt| {
expand_simple_derive(db, span, tt, quote! {span => #krate::default::Default }, |adt| {
let body = match &adt.shape {
AdtShape::Struct(fields) => {
let name = &adt.name;
Expand Down Expand Up @@ -615,9 +634,13 @@ fn default_expand(span: Span, tt: &tt::TopSubtree) -> ExpandResult<tt::TopSubtre
})
}

fn debug_expand(span: Span, tt: &tt::TopSubtree) -> ExpandResult<tt::TopSubtree> {
fn debug_expand(
db: &dyn ExpandDatabase,
span: Span,
tt: &tt::TopSubtree,
) -> ExpandResult<tt::TopSubtree> {
let krate = &dollar_crate(span);
expand_simple_derive(span, tt, quote! {span => #krate::fmt::Debug }, |adt| {
expand_simple_derive(db, span, tt, quote! {span => #krate::fmt::Debug }, |adt| {
let for_variant = |name: String, v: &VariantShape| match v {
VariantShape::Struct(fields) => {
let for_fields = fields.iter().map(|it| {
Expand Down Expand Up @@ -687,9 +710,13 @@ fn debug_expand(span: Span, tt: &tt::TopSubtree) -> ExpandResult<tt::TopSubtree>
})
}

fn hash_expand(span: Span, tt: &tt::TopSubtree) -> ExpandResult<tt::TopSubtree> {
fn hash_expand(
db: &dyn ExpandDatabase,
span: Span,
tt: &tt::TopSubtree,
) -> ExpandResult<tt::TopSubtree> {
let krate = &dollar_crate(span);
expand_simple_derive(span, tt, quote! {span => #krate::hash::Hash }, |adt| {
expand_simple_derive(db, span, tt, quote! {span => #krate::hash::Hash }, |adt| {
if matches!(adt.shape, AdtShape::Union) {
// FIXME: Return expand error here
return quote! {span =>};
Expand Down Expand Up @@ -734,14 +761,22 @@ fn hash_expand(span: Span, tt: &tt::TopSubtree) -> ExpandResult<tt::TopSubtree>
})
}

fn eq_expand(span: Span, tt: &tt::TopSubtree) -> ExpandResult<tt::TopSubtree> {
fn eq_expand(
db: &dyn ExpandDatabase,
span: Span,
tt: &tt::TopSubtree,
) -> ExpandResult<tt::TopSubtree> {
let krate = dollar_crate(span);
expand_simple_derive(span, tt, quote! {span => #krate::cmp::Eq }, |_| quote! {span =>})
expand_simple_derive(db, span, tt, quote! {span => #krate::cmp::Eq }, |_| quote! {span =>})
}

fn partial_eq_expand(span: Span, tt: &tt::TopSubtree) -> ExpandResult<tt::TopSubtree> {
fn partial_eq_expand(
db: &dyn ExpandDatabase,
span: Span,
tt: &tt::TopSubtree,
) -> ExpandResult<tt::TopSubtree> {
let krate = dollar_crate(span);
expand_simple_derive(span, tt, quote! {span => #krate::cmp::PartialEq }, |adt| {
expand_simple_derive(db, span, tt, quote! {span => #krate::cmp::PartialEq }, |adt| {
if matches!(adt.shape, AdtShape::Union) {
// FIXME: Return expand error here
return quote! {span =>};
Expand Down Expand Up @@ -811,9 +846,13 @@ fn self_and_other_patterns(
(self_patterns, other_patterns)
}

fn ord_expand(span: Span, tt: &tt::TopSubtree) -> ExpandResult<tt::TopSubtree> {
fn ord_expand(
db: &dyn ExpandDatabase,
span: Span,
tt: &tt::TopSubtree,
) -> ExpandResult<tt::TopSubtree> {
let krate = &dollar_crate(span);
expand_simple_derive(span, tt, quote! {span => #krate::cmp::Ord }, |adt| {
expand_simple_derive(db, span, tt, quote! {span => #krate::cmp::Ord }, |adt| {
fn compare(
krate: &tt::Ident,
left: tt::TopSubtree,
Expand Down Expand Up @@ -869,9 +908,13 @@ fn ord_expand(span: Span, tt: &tt::TopSubtree) -> ExpandResult<tt::TopSubtree> {
})
}

fn partial_ord_expand(span: Span, tt: &tt::TopSubtree) -> ExpandResult<tt::TopSubtree> {
fn partial_ord_expand(
db: &dyn ExpandDatabase,
span: Span,
tt: &tt::TopSubtree,
) -> ExpandResult<tt::TopSubtree> {
let krate = &dollar_crate(span);
expand_simple_derive(span, tt, quote! {span => #krate::cmp::PartialOrd }, |adt| {
expand_simple_derive(db, span, tt, quote! {span => #krate::cmp::PartialOrd }, |adt| {
fn compare(
krate: &tt::Ident,
left: tt::TopSubtree,
Expand Down Expand Up @@ -932,8 +975,12 @@ fn partial_ord_expand(span: Span, tt: &tt::TopSubtree) -> ExpandResult<tt::TopSu
})
}

fn coerce_pointee_expand(span: Span, tt: &tt::TopSubtree) -> ExpandResult<tt::TopSubtree> {
let (adt, _span_map) = match to_adt_syntax(tt, span) {
fn coerce_pointee_expand(
db: &dyn ExpandDatabase,
span: Span,
tt: &tt::TopSubtree,
) -> ExpandResult<tt::TopSubtree> {
let (adt, _span_map) = match to_adt_syntax(db, tt, span) {
Ok(it) => it,
Err(err) => {
return ExpandResult::new(tt::TopSubtree::empty(tt::DelimSpan::from_single(span)), err);
Expand Down
Loading

0 comments on commit 5103b4c

Please sign in to comment.