Skip to content

Commit 7468581

Browse files
committed
Take header by mutable value, and merge into the value passed in.
1 parent d4e9c20 commit 7468581

3 files changed

Lines changed: 49 additions & 7 deletions

File tree

cfgrammar/src/lib/markmap.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,48 @@ impl<K: Ord + Clone, V> MarkMap<K, V> {
409409
Ok(())
410410
}
411411

412+
/// Similar to `merge_from` except the `MergeBehavior` of self is used when merging into `*other*`.
413+
#[doc(hidden)]
414+
pub fn merge_into(mut self, other: &'_ mut Self) -> Result<(), MergeError<K, Box<V>>> {
415+
for (src_key, src_mark, src_val) in self.contents.drain(..) {
416+
let pos = other.contents.binary_search_by(|x| x.0.cmp(&src_key));
417+
match pos {
418+
Ok(pos) => {
419+
let (_, dest_mark, dest_val) = &mut other.contents[pos];
420+
let theirs_mark = Mark::MergeBehavior(MergeBehavior::Theirs).repr();
421+
let ours_mark = Mark::MergeBehavior(MergeBehavior::Ours).repr();
422+
let exclusive_mark =
423+
Mark::MergeBehavior(MergeBehavior::MutuallyExclusive).repr();
424+
let merge_behavior = (src_mark & exclusive_mark)
425+
| (src_mark & ours_mark)
426+
| (src_mark & theirs_mark);
427+
if merge_behavior == exclusive_mark || merge_behavior == 0 {
428+
// If only clippy could convince me and the borrow checker this is actually unnecessary.
429+
#[allow(clippy::unnecessary_unwrap)]
430+
if src_val.is_some() && dest_val.is_some() {
431+
return Err(MergeError::Exclusivity(
432+
src_key,
433+
Box::new(src_val.unwrap()),
434+
));
435+
} else if dest_val.is_none() {
436+
*dest_val = src_val;
437+
}
438+
} else if merge_behavior == ours_mark && src_val.is_some()
439+
|| merge_behavior == theirs_mark && dest_val.is_none()
440+
{
441+
*dest_mark = src_mark;
442+
*dest_val = src_val;
443+
}
444+
}
445+
Err(pos) => {
446+
other.contents
447+
.insert(pos, (src_key, src_mark, src_val));
448+
}
449+
}
450+
}
451+
Ok(())
452+
}
453+
412454
/// Returns whether `key` has been marked as used.
413455
#[doc(hidden)]
414456
pub fn is_used<Q>(&self, key: &Q) -> bool

lrlex/src/lib/ctbuilder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -465,12 +465,12 @@ where
465465
if let Some(inspect_lexerkind_cb) = self.inspect_lexerkind_cb {
466466
inspect_lexerkind_cb(lexerkind)?
467467
}
468-
let header = Header::new();
468+
let mut header = Header::new();
469469
let (mut lexerdef, lex_flags): (Box<dyn LexerDef<LexerTypesT>>, LexFlags) = match lexerkind
470470
{
471471
LexerKind::LRNonStreamingLexer => {
472472
let lexerdef =
473-
LRNonStreamingLexerDef::<LexerTypesT>::new_with_header(&lex_src, header)
473+
LRNonStreamingLexerDef::<LexerTypesT>::new_with_header(&lex_src, &mut header)
474474
.map_err(|errs| {
475475
errs.iter()
476476
.map(|e| match e {

lrlex/src/lib/lexer.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -597,11 +597,11 @@ where
597597

598598
pub fn new_with_header(
599599
s: &str,
600-
args_header: Header,
600+
args_header: &mut Header,
601601
) -> Result<LRNonStreamingLexerDef<LexerTypesT>, Vec<LexBuildHeaderError>> {
602-
let mut defaults = default_lex_flags_header();
602+
let defaults = default_lex_flags_header();
603603
defaults
604-
.merge_from(args_header)
604+
.merge_into(args_header)
605605
.expect("merging into defaults cannot fail");
606606
let (header, pos) = GrmtoolsSectionParser::new(s, false)
607607
.parse()
@@ -610,8 +610,8 @@ where
610610
.map(LexBuildHeaderError::Header)
611611
.collect::<Vec<_>>()
612612
})?;
613-
defaults.merge_from(header).unwrap();
614-
let lex_flags = LexFlags::try_from(&defaults).map_err(|e| vec![e.into()])?;
613+
args_header.merge_from(header).unwrap();
614+
let lex_flags = LexFlags::try_from(&*args_header).map_err(|e| vec![e.into()])?;
615615
let p =
616616
LexParser::<LexerTypesT>::new_with_lex_flags(s[pos..].to_string(), lex_flags.clone());
617617
match p {

0 commit comments

Comments
 (0)