Skip to content

Commit 2445d53

Browse files
committed
Auto merge of rust-lang#17489 - Veykril:tt-iter, r=Veykril
minro: move tt-iter into tt crate
2 parents a16d63c + 3db2881 commit 2445d53

File tree

10 files changed

+332
-319
lines changed

10 files changed

+332
-319
lines changed

src/tools/rust-analyzer/Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2252,6 +2252,7 @@ dependencies = [
22522252
name = "tt"
22532253
version = "0.0.0"
22542254
dependencies = [
2255+
"arrayvec",
22552256
"smol_str",
22562257
"stdx",
22572258
"text-size",

src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incoherent_impl.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
use hir::InFile;
2+
use syntax::{AstNode, TextRange};
23

3-
use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext};
4+
use crate::{adjusted_display_range, Diagnostic, DiagnosticCode, DiagnosticsContext};
45

56
// Diagnostic: incoherent-impl
67
//
78
// This diagnostic is triggered if the targe type of an impl is from a foreign crate.
89
pub(crate) fn incoherent_impl(ctx: &DiagnosticsContext<'_>, d: &hir::IncoherentImpl) -> Diagnostic {
9-
Diagnostic::new_with_syntax_node_ptr(
10-
ctx,
10+
let display_range = adjusted_display_range(ctx, InFile::new(d.file_id, d.impl_), &|node| {
11+
Some(TextRange::new(
12+
node.syntax().text_range().start(),
13+
node.self_ty()?.syntax().text_range().end(),
14+
))
15+
});
16+
17+
Diagnostic::new(
1118
DiagnosticCode::RustcHardError("E0210"),
1219
"cannot define inherent `impl` for foreign type".to_owned(),
13-
InFile::new(d.file_id, d.impl_.into()),
20+
display_range,
1421
)
1522
}
1623

@@ -23,7 +30,7 @@ mod change_case {
2330
check_diagnostics(
2431
r#"
2532
impl bool {}
26-
//^^^^^^^^^^^^ error: cannot define inherent `impl` for foreign type
33+
//^^^^^^^^^ error: cannot define inherent `impl` for foreign type
2734
"#,
2835
);
2936
}
@@ -60,7 +67,7 @@ impl foo::S {
6067
pub struct S;
6168
//- /main.rs crate:main deps:foo
6269
impl foo::S { #[rustc_allow_incoherent_impl] fn func(self) {} }
63-
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: cannot define inherent `impl` for foreign type
70+
//^^^^^^^^^^^ error: cannot define inherent `impl` for foreign type
6471
"#,
6572
);
6673
check_diagnostics(
@@ -70,7 +77,7 @@ pub struct S;
7077
pub struct S;
7178
//- /main.rs crate:main deps:foo
7279
impl foo::S { fn func(self) {} }
73-
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: cannot define inherent `impl` for foreign type
80+
//^^^^^^^^^^^ error: cannot define inherent `impl` for foreign type
7481
"#,
7582
);
7683
}

src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs

Lines changed: 81 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,12 @@ use std::{rc::Rc, sync::Arc};
6464
use smallvec::{smallvec, SmallVec};
6565
use span::{Edition, Span};
6666
use syntax::SmolStr;
67-
use tt::DelimSpan;
67+
use tt::{iter::TtIter, DelimSpan};
6868

6969
use crate::{
7070
expander::{Binding, Bindings, ExpandResult, Fragment},
71+
expect_fragment,
7172
parser::{MetaVarKind, Op, RepeatKind, Separator},
72-
tt_iter::TtIter,
7373
ExpandError, MetaTemplate, ValueResult,
7474
};
7575

@@ -406,7 +406,7 @@ fn match_loop_inner<'t>(
406406
if item.sep.is_some() && !item.sep_matched {
407407
let sep = item.sep.as_ref().unwrap();
408408
let mut fork = src.clone();
409-
if fork.expect_separator(sep) {
409+
if expect_separator(&mut fork, sep) {
410410
// HACK: here we use `meta_result` to pass `TtIter` back to caller because
411411
// it might have been advanced multiple times. `ValueResult` is
412412
// insignificant.
@@ -746,7 +746,7 @@ fn match_meta_var(
746746
) -> ExpandResult<Option<Fragment>> {
747747
let fragment = match kind {
748748
MetaVarKind::Path => {
749-
return input.expect_fragment(parser::PrefixEntryPoint::Path, edition).map(|it| {
749+
return expect_fragment(input, parser::PrefixEntryPoint::Path, edition).map(|it| {
750750
it.map(|it| tt::TokenTree::subtree_or_wrap(it, delim_span)).map(Fragment::Path)
751751
});
752752
}
@@ -765,7 +765,7 @@ fn match_meta_var(
765765
}
766766
_ => {}
767767
};
768-
return input.expect_fragment(parser::PrefixEntryPoint::Expr, edition).map(|tt| {
768+
return expect_fragment(input, parser::PrefixEntryPoint::Expr, edition).map(|tt| {
769769
tt.map(|tt| match tt {
770770
tt::TokenTree::Leaf(leaf) => tt::Subtree {
771771
delimiter: tt::Delimiter::invisible_spanned(*leaf.span()),
@@ -787,14 +787,13 @@ fn match_meta_var(
787787
.expect_ident()
788788
.map(|ident| tt::Leaf::from(ident.clone()).into())
789789
.map_err(|()| ExpandError::binding_error("expected ident")),
790-
MetaVarKind::Tt => input
791-
.expect_tt()
792-
.map_err(|()| ExpandError::binding_error("expected token tree")),
793-
MetaVarKind::Lifetime => input
794-
.expect_lifetime()
790+
MetaVarKind::Tt => {
791+
expect_tt(input).map_err(|()| ExpandError::binding_error("expected token tree"))
792+
}
793+
MetaVarKind::Lifetime => expect_lifetime(input)
795794
.map_err(|()| ExpandError::binding_error("expected lifetime")),
796795
MetaVarKind::Literal => {
797-
let neg = input.eat_char('-');
796+
let neg = eat_char(input, '-');
798797
input
799798
.expect_literal()
800799
.map(|literal| {
@@ -822,7 +821,7 @@ fn match_meta_var(
822821
MetaVarKind::Item => parser::PrefixEntryPoint::Item,
823822
MetaVarKind::Vis => parser::PrefixEntryPoint::Vis,
824823
};
825-
input.expect_fragment(fragment, edition).map(|it| it.map(Fragment::Tokens))
824+
expect_fragment(input, fragment, edition).map(|it| it.map(Fragment::Tokens))
826825
}
827826

828827
fn collect_vars(collector_fun: &mut impl FnMut(SmolStr), pattern: &MetaTemplate) {
@@ -905,86 +904,84 @@ impl<'a> Iterator for OpDelimitedIter<'a> {
905904
}
906905
}
907906

908-
impl TtIter<'_, Span> {
909-
fn expect_separator(&mut self, separator: &Separator) -> bool {
910-
let mut fork = self.clone();
911-
let ok = match separator {
912-
Separator::Ident(lhs) => match fork.expect_ident_or_underscore() {
913-
Ok(rhs) => rhs.text == lhs.text,
914-
Err(_) => false,
915-
},
916-
Separator::Literal(lhs) => match fork.expect_literal() {
917-
Ok(rhs) => match rhs {
918-
tt::Leaf::Literal(rhs) => rhs.text == lhs.text,
919-
tt::Leaf::Ident(rhs) => rhs.text == lhs.text,
920-
tt::Leaf::Punct(_) => false,
921-
},
922-
Err(_) => false,
907+
fn expect_separator<S: Copy>(iter: &mut TtIter<'_, S>, separator: &Separator) -> bool {
908+
let mut fork = iter.clone();
909+
let ok = match separator {
910+
Separator::Ident(lhs) => match fork.expect_ident_or_underscore() {
911+
Ok(rhs) => rhs.text == lhs.text,
912+
Err(_) => false,
913+
},
914+
Separator::Literal(lhs) => match fork.expect_literal() {
915+
Ok(rhs) => match rhs {
916+
tt::Leaf::Literal(rhs) => rhs.text == lhs.text,
917+
tt::Leaf::Ident(rhs) => rhs.text == lhs.text,
918+
tt::Leaf::Punct(_) => false,
923919
},
924-
Separator::Puncts(lhs) => match fork.expect_glued_punct() {
925-
Ok(rhs) => {
926-
let lhs = lhs.iter().map(|it| it.char);
927-
let rhs = rhs.iter().map(|it| it.char);
928-
lhs.eq(rhs)
929-
}
930-
Err(_) => false,
931-
},
932-
};
933-
if ok {
934-
*self = fork;
935-
}
936-
ok
937-
}
938-
939-
fn expect_tt(&mut self) -> Result<tt::TokenTree<Span>, ()> {
940-
if let Some(tt::TokenTree::Leaf(tt::Leaf::Punct(punct))) = self.peek_n(0) {
941-
if punct.char == '\'' {
942-
self.expect_lifetime()
943-
} else {
944-
let puncts = self.expect_glued_punct()?;
945-
let delimiter = tt::Delimiter {
946-
open: puncts.first().unwrap().span,
947-
close: puncts.last().unwrap().span,
948-
kind: tt::DelimiterKind::Invisible,
949-
};
950-
let token_trees = puncts.into_iter().map(|p| tt::Leaf::Punct(p).into()).collect();
951-
Ok(tt::TokenTree::Subtree(tt::Subtree { delimiter, token_trees }))
920+
Err(_) => false,
921+
},
922+
Separator::Puncts(lhs) => match fork.expect_glued_punct() {
923+
Ok(rhs) => {
924+
let lhs = lhs.iter().map(|it| it.char);
925+
let rhs = rhs.iter().map(|it| it.char);
926+
lhs.eq(rhs)
952927
}
953-
} else {
954-
self.next().ok_or(()).cloned()
955-
}
928+
Err(_) => false,
929+
},
930+
};
931+
if ok {
932+
*iter = fork;
956933
}
934+
ok
935+
}
957936

958-
fn expect_lifetime(&mut self) -> Result<tt::TokenTree<Span>, ()> {
959-
let punct = self.expect_single_punct()?;
960-
if punct.char != '\'' {
961-
return Err(());
962-
}
963-
let ident = self.expect_ident_or_underscore()?;
964-
965-
Ok(tt::Subtree {
966-
delimiter: tt::Delimiter {
967-
open: punct.span,
968-
close: ident.span,
937+
fn expect_tt<S: Copy>(iter: &mut TtIter<'_, S>) -> Result<tt::TokenTree<S>, ()> {
938+
if let Some(tt::TokenTree::Leaf(tt::Leaf::Punct(punct))) = iter.peek_n(0) {
939+
if punct.char == '\'' {
940+
expect_lifetime(iter)
941+
} else {
942+
let puncts = iter.expect_glued_punct()?;
943+
let delimiter = tt::Delimiter {
944+
open: puncts.first().unwrap().span,
945+
close: puncts.last().unwrap().span,
969946
kind: tt::DelimiterKind::Invisible,
970-
},
971-
token_trees: Box::new([
972-
tt::Leaf::Punct(*punct).into(),
973-
tt::Leaf::Ident(ident.clone()).into(),
974-
]),
947+
};
948+
let token_trees = puncts.into_iter().map(|p| tt::Leaf::Punct(p).into()).collect();
949+
Ok(tt::TokenTree::Subtree(tt::Subtree { delimiter, token_trees }))
975950
}
976-
.into())
951+
} else {
952+
iter.next().ok_or(()).cloned()
977953
}
954+
}
978955

979-
fn eat_char(&mut self, c: char) -> Option<tt::TokenTree<Span>> {
980-
let mut fork = self.clone();
981-
match fork.expect_char(c) {
982-
Ok(_) => {
983-
let tt = self.next().cloned();
984-
*self = fork;
985-
tt
986-
}
987-
Err(_) => None,
956+
fn expect_lifetime<S: Copy>(iter: &mut TtIter<'_, S>) -> Result<tt::TokenTree<S>, ()> {
957+
let punct = iter.expect_single_punct()?;
958+
if punct.char != '\'' {
959+
return Err(());
960+
}
961+
let ident = iter.expect_ident_or_underscore()?;
962+
963+
Ok(tt::Subtree {
964+
delimiter: tt::Delimiter {
965+
open: punct.span,
966+
close: ident.span,
967+
kind: tt::DelimiterKind::Invisible,
968+
},
969+
token_trees: Box::new([
970+
tt::Leaf::Punct(*punct).into(),
971+
tt::Leaf::Ident(ident.clone()).into(),
972+
]),
973+
}
974+
.into())
975+
}
976+
977+
fn eat_char<S: Copy>(iter: &mut TtIter<'_, S>, c: char) -> Option<tt::TokenTree<S>> {
978+
let mut fork = iter.clone();
979+
match fork.expect_char(c) {
980+
Ok(_) => {
981+
let tt = iter.next().cloned();
982+
*iter = fork;
983+
tt
988984
}
985+
Err(_) => None,
989986
}
990987
}

src/tools/rust-analyzer/crates/mbe/src/lib.rs

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,17 @@ mod expander;
1212
mod parser;
1313
mod syntax_bridge;
1414
mod to_parser_input;
15-
mod tt_iter;
1615

1716
#[cfg(test)]
1817
mod benchmark;
1918

2019
use span::{Edition, Span, SyntaxContextId};
2120
use stdx::impl_from;
21+
use tt::iter::TtIter;
2222

2323
use std::fmt;
2424

25-
use crate::{
26-
parser::{MetaTemplate, MetaVarKind, Op},
27-
tt_iter::TtIter,
28-
};
25+
use crate::parser::{MetaTemplate, MetaVarKind, Op};
2926

3027
// FIXME: we probably should re-think `token_tree_to_syntax_node` interfaces
3128
pub use ::parser::TopEntryPoint;
@@ -247,6 +244,10 @@ impl DeclarativeMacro {
247244
self.err.as_deref()
248245
}
249246

247+
pub fn num_rules(&self) -> usize {
248+
self.rules.len()
249+
}
250+
250251
pub fn expand(
251252
&self,
252253
tt: &tt::Subtree<Span>,
@@ -361,3 +362,60 @@ impl<T: Default, E> From<Result<T, E>> for ValueResult<T, E> {
361362
result.map_or_else(Self::only_err, Self::ok)
362363
}
363364
}
365+
366+
fn expect_fragment<S: Copy + fmt::Debug>(
367+
tt_iter: &mut TtIter<'_, S>,
368+
entry_point: ::parser::PrefixEntryPoint,
369+
edition: ::parser::Edition,
370+
) -> ExpandResult<Option<tt::TokenTree<S>>> {
371+
use ::parser;
372+
let buffer = tt::buffer::TokenBuffer::from_tokens(tt_iter.as_slice());
373+
let parser_input = to_parser_input::to_parser_input(&buffer);
374+
let tree_traversal = entry_point.parse(&parser_input, edition);
375+
let mut cursor = buffer.begin();
376+
let mut error = false;
377+
for step in tree_traversal.iter() {
378+
match step {
379+
parser::Step::Token { kind, mut n_input_tokens } => {
380+
if kind == ::parser::SyntaxKind::LIFETIME_IDENT {
381+
n_input_tokens = 2;
382+
}
383+
for _ in 0..n_input_tokens {
384+
cursor = cursor.bump_subtree();
385+
}
386+
}
387+
parser::Step::FloatSplit { .. } => {
388+
// FIXME: We need to split the tree properly here, but mutating the token trees
389+
// in the buffer is somewhat tricky to pull off.
390+
cursor = cursor.bump_subtree();
391+
}
392+
parser::Step::Enter { .. } | parser::Step::Exit => (),
393+
parser::Step::Error { .. } => error = true,
394+
}
395+
}
396+
397+
let err = if error || !cursor.is_root() {
398+
Some(ExpandError::binding_error(format!("expected {entry_point:?}")))
399+
} else {
400+
None
401+
};
402+
403+
let mut curr = buffer.begin();
404+
let mut res = vec![];
405+
406+
while curr != cursor {
407+
let Some(token) = curr.token_tree() else { break };
408+
res.push(token.cloned());
409+
curr = curr.bump();
410+
}
411+
412+
*tt_iter = TtIter::new_iter(tt_iter.as_slice()[res.len()..].iter());
413+
let res = match &*res {
414+
[] | [_] => res.pop(),
415+
[first, ..] => Some(tt::TokenTree::Subtree(tt::Subtree {
416+
delimiter: Delimiter::invisible_spanned(first.first_span()),
417+
token_trees: res.into_boxed_slice(),
418+
})),
419+
};
420+
ExpandResult { value: res, err }
421+
}

src/tools/rust-analyzer/crates/mbe/src/parser.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ use std::sync::Arc;
66
use arrayvec::ArrayVec;
77
use span::{Edition, Span, SyntaxContextId};
88
use syntax::SmolStr;
9+
use tt::iter::TtIter;
910

10-
use crate::{tt_iter::TtIter, ParseError};
11+
use crate::ParseError;
1112

1213
/// Consider
1314
///

0 commit comments

Comments
 (0)