diff --git a/core/src/parser/grammar.lalrpop b/core/src/parser/grammar.lalrpop index 8f793c7f6c..7865d33f0b 100644 --- a/core/src/parser/grammar.lalrpop +++ b/core/src/parser/grammar.lalrpop @@ -525,7 +525,7 @@ Pattern: Pattern = { Pattern { alias, data, - span: mk_span(src_id, l, r), + pos: mk_pos(src_id, l, r), } }, }; @@ -553,9 +553,13 @@ RecordPattern: RecordPattern = { None => RecordPatternTail::Empty, }; - let span = mk_span(src_id, start, end); - let pattern = RecordPattern { patterns: field_pats, tail, span }; + let pattern = RecordPattern { + patterns: field_pats, + tail, + pos: mk_pos(src_id, start, end) + }; pattern.check_dup()?; + Ok(pattern) }, }; @@ -564,12 +568,12 @@ EnumPattern: EnumPattern = { => EnumPattern { tag, pattern: None, - span: mk_span(src_id, start, end), + pos: mk_pos(src_id, start, end), }, ".." "(" ")" => EnumPattern { tag, pattern: Some(Box::new(pattern)), - span: mk_span(src_id, start, end), + pos: mk_pos(src_id, start, end), }, }; @@ -583,7 +587,7 @@ FieldPattern: FieldPattern = { matched_id, extra, pattern, - span: mk_span(src_id, l, r), + pos: mk_pos(src_id, l, r), } }, ?> => { @@ -596,10 +600,10 @@ FieldPattern: FieldPattern = { data: PatternData::Any(matched_id), //unwrap(): the position of an parsed identifier should always //be defined - span: matched_id.pos.unwrap(), + pos: matched_id.pos, alias: None, }, - span: mk_span(src_id, l, r) + pos: mk_pos(src_id, l, r) } }, }; diff --git a/core/src/term/pattern/mod.rs b/core/src/term/pattern/mod.rs index b67f37f724..fe53d01a05 100644 --- a/core/src/term/pattern/mod.rs +++ b/core/src/term/pattern/mod.rs @@ -7,7 +7,7 @@ use crate::{ label::Label, mk_app, parser::error::ParseError, - position::{RawSpan, TermPos}, + position::TermPos, stdlib::internals, term::{ record::{Field, RecordAttrs, RecordData}, @@ -38,8 +38,8 @@ pub struct Pattern { /// A potential alias for this pattern, capturing the whole matched value. In the source /// language, an alias is introduced by `x @ `, where `x` is an arbitrary identifier. pub alias: Option, - /// The span of the pattern in the source. - pub span: RawSpan, + /// The position of the pattern in the source. + pub pos: TermPos, } /// An enum pattern, including both an enum tag and an enum variant. @@ -47,7 +47,7 @@ pub struct Pattern { pub struct EnumPattern { pub tag: LocIdent, pub pattern: Option>, - pub span: RawSpan, + pub pos: TermPos, } /// A field pattern inside a record pattern. Every field can be annotated with a type, contracts or @@ -64,7 +64,7 @@ pub struct FieldPattern { /// sign, is parsed as `{foo=foo, bar=bar}`. In this case, `pattern.data` will be /// [PatternData::Any]. pub pattern: Pattern, - pub span: RawSpan, + pub pos: TermPos, } /// The last match in a data structure pattern. This can either be a normal match, or an ellipsis @@ -97,7 +97,7 @@ pub struct RecordPattern { /// The tail of the pattern, indicating if the pattern is open, i.e. if it ended with an /// ellipsis, capturing the rest or not. pub tail: RecordPatternTail, - pub span: RawSpan, + pub pos: TermPos, } /// The tail of a record pattern which might capture the rest of the record. @@ -213,8 +213,6 @@ impl ElaborateContract for Pattern { impl ElaborateContract for EnumPattern { fn elaborate_contract(&self) -> Option { - let pos = TermPos::Original(self.span); - // TODO[adts]: it would be better to simply build a type like `[| 'tag arg |]` or `[| 'tag // |]` and to rely on its derived contract. However, for the time being, the contract // derived from enum variants isn't implemented yet. @@ -226,14 +224,18 @@ impl ElaborateContract for EnumPattern { let typ = Type { typ: TypeF::Flat(contract), - pos, + pos: self.pos, }; Some(LabeledType { typ: typ.clone(), label: Label { typ: typ.into(), - span: self.span, + // [^unwrap-span]: We need the position to be defined here. Hopefully, + // contract-generating pattern are pattern used in destructuring, and destructuring + // patterns aren't currently generated by the Nickel interpreter. So we should only + // encounter user-written patterns here, which should have a position. + span: self.pos.unwrap(), ..Default::default() }, }) @@ -242,8 +244,6 @@ impl ElaborateContract for EnumPattern { impl ElaborateContract for RecordPattern { fn elaborate_contract(&self) -> Option { - let pos = TermPos::Original(self.span); - let typ = Type { typ: TypeF::Flat( Term::Record(RecordData::new( @@ -259,14 +259,15 @@ impl ElaborateContract for RecordPattern { )) .into(), ), - pos, + pos: self.pos, }; Some(LabeledType { typ: typ.clone(), label: Label { typ: typ.into(), - span: self.span, + // unwrap(): cf [^unwrap-span] + span: self.pos.unwrap(), ..Default::default() }, })