diff --git a/pikelet/src/lang.rs b/pikelet/src/lang.rs index 9f4542846..2882e1011 100644 --- a/pikelet/src/lang.rs +++ b/pikelet/src/lang.rs @@ -1,7 +1,5 @@ //! Intermediate languages of the Pikelet compiler. -use std::ops::Range; - pub mod surface; // 🠃 pub mod core; @@ -12,21 +10,39 @@ pub mod cc; // 🠃 // ... +/// A range of source code. +#[derive(Debug, Copy, Clone)] +pub struct Range { + pub start: usize, + pub end: usize, +} + +impl Into> for Range { + fn into(self) -> std::ops::Range { + self.start..self.end + } +} + +impl From> for Range { + fn from(src: std::ops::Range) -> Range { + Range { + start: src.start, + end: src.end, + } + } +} + /// Data that covers some range of source code. #[derive(Debug, Clone)] pub struct Ranged { - pub range: Range, + pub range: Range, pub data: Data, } impl Ranged { - pub fn new(range: Range, data: Data) -> Ranged { + pub fn new(range: Range, data: Data) -> Ranged { Ranged { range, data } } - - pub fn range(&self) -> Range { - self.range.clone() - } } impl From for Ranged { @@ -34,6 +50,6 @@ impl From for Ranged { fn from(data: Data) -> Ranged { // TODO: Use a better marker for data that does not originate from to a // specific source location. - Ranged::new(0..0, data) + Ranged::new(Range::from(0..0), data) } } diff --git a/pikelet/src/lang/surface/grammar.lalrpop b/pikelet/src/lang/surface/grammar.lalrpop index 9632fd983..56ecccf32 100644 --- a/pikelet/src/lang/surface/grammar.lalrpop +++ b/pikelet/src/lang/surface/grammar.lalrpop @@ -1,4 +1,4 @@ -use crate::lang::Ranged; +use crate::lang::{Range, Ranged}; use crate::lang::surface::{Term, TermData, TypeEntry, TermEntry}; use crate::lang::surface::lexer::Token; use crate::reporting::LexerError; @@ -120,5 +120,5 @@ Name: String = { #[inline] Ranged: Ranged = { - => Ranged::new(start..end, data), + => Ranged::new(Range::from(start..end), data), }; diff --git a/pikelet/src/lang/surface/lexer.rs b/pikelet/src/lang/surface/lexer.rs index b18ac6ce4..336c884db 100644 --- a/pikelet/src/lang/surface/lexer.rs +++ b/pikelet/src/lang/surface/lexer.rs @@ -105,7 +105,9 @@ pub fn tokens<'a>( Token::lexer(source) .spanned() .map(|(token, range)| match token { - Token::Error => Err(LexerError::InvalidToken { range }), + Token::Error => Err(LexerError::InvalidToken { + range: range.into(), + }), token => Ok((range.start, token, range.end)), }) } diff --git a/pikelet/src/literal.rs b/pikelet/src/literal.rs index 6ee2040ea..a86c955cd 100644 --- a/pikelet/src/literal.rs +++ b/pikelet/src/literal.rs @@ -5,8 +5,8 @@ use crossbeam_channel::Sender; use logos::Logos; use num_traits::{Float, PrimInt, Signed, Unsigned}; -use std::ops::Range; +use crate::lang::Range; use crate::reporting::LiteralParseMessage::*; use crate::reporting::Message; @@ -193,14 +193,14 @@ enum AsciiEscape<'source> { /// Literal parser state. pub struct State<'source, 'messages> { - range: Range, + range: Range, source: &'source str, message_tx: &'messages Sender, } impl<'source, 'messages> State<'source, 'messages> { pub fn new( - range: Range, + range: Range, source: &'source str, message_tx: &'messages Sender, ) -> State<'source, 'messages> { @@ -217,18 +217,13 @@ impl<'source, 'messages> State<'source, 'messages> { None } - /// The range of the entire literal. - fn range(&self) -> Range { - self.range.clone() - } - /// Get the file-relative range of the current token. - fn token_range(&self, lexer: &logos::Lexer<'source, Token>) -> Range + fn token_range(&self, lexer: &logos::Lexer<'source, Token>) -> Range where Token: Logos<'source>, { let span = lexer.span(); - (self.range.start + span.start)..(self.range.start + span.end) + Range::from((self.range.start + span.start)..(self.range.start + span.end)) } /// Parse a numeric literal into an unsigned integer. @@ -242,7 +237,7 @@ impl<'source, 'messages> State<'source, 'messages> { let (base, start_digit) = match self.expect_numeric_literal_start(&mut lexer)? { (Sign::Positive, base, start_digit) => (base, start_digit), - (Sign::Negative, _, _) => return self.report(NegativeUnsignedInteger(self.range())), + (Sign::Negative, _, _) => return self.report(NegativeUnsignedInteger(self.range)), }; let mut lexer = lexer.morph(); @@ -420,7 +415,7 @@ impl<'source, 'messages> State<'source, 'messages> { Some(float) } else { - self.report(UnsupportedFloatLiteralBase(self.range(), base)) + self.report(UnsupportedFloatLiteralBase(self.range, base)) } } @@ -454,7 +449,7 @@ impl<'source, 'messages> State<'source, 'messages> { Sign::Positive => T::checked_add(&place_shifted, &T::from(digit).unwrap()), Sign::Negative => T::checked_sub(&place_shifted, &T::from(digit).unwrap()), }) - .or_else(|| self.report(LiteralOutOfRange(self.range()))) + .or_else(|| self.report(LiteralOutOfRange(self.range))) } /// Parse a quoted literal into a Unicode encoded character. @@ -479,7 +474,7 @@ impl<'source, 'messages> State<'source, 'messages> { for ch in text.chars() { match character { None => character = Some(ch), - Some(_) => return self.report(OverlongCharLiteral(self.range())), + Some(_) => return self.report(OverlongCharLiteral(self.range)), } } } @@ -499,7 +494,7 @@ impl<'source, 'messages> State<'source, 'messages> { }, QuotedText::End(quote) => match character { None => character = Some(quote.to_char()), - Some(_) => return self.report(OverlongCharLiteral(self.range())), + Some(_) => return self.report(OverlongCharLiteral(self.range)), }, QuotedText::Error => return self.report(InvalidToken(self.token_range(&lexer))), @@ -508,7 +503,7 @@ impl<'source, 'messages> State<'source, 'messages> { match character { Some(ch) => Some(ch), - None => self.report(EmptyCharLiteral(self.range())), + None => self.report(EmptyCharLiteral(self.range)), } } diff --git a/pikelet/src/pass/surface_to_core.rs b/pikelet/src/pass/surface_to_core.rs index 9ddc88abf..8b68d7161 100644 --- a/pikelet/src/pass/surface_to_core.rs +++ b/pikelet/src/pass/surface_to_core.rs @@ -8,12 +8,11 @@ use contracts::debug_ensures; use crossbeam_channel::Sender; use num_traits::{Float, PrimInt, Signed, Unsigned}; -use std::ops::Range; use std::sync::Arc; -use crate::lang::core; use crate::lang::core::semantics::{self, Elim, RecordClosure, Unfold, Value}; use crate::lang::surface::{Term, TermData}; +use crate::lang::{core, Range}; use crate::literal; use crate::pass::core_to_surface; use crate::reporting::{AmbiguousTerm, ExpectedType, Message, SurfaceToCoreMessage}; @@ -197,15 +196,15 @@ impl<'me> State<'me> { let (core_term, r#type) = self.synth_type(term); match r#type.force(self.globals) { Value::TypeType(level) => (core_term, Some(*level)), - Value::Error => (core::Term::new(term.range(), core::TermData::Error), None), + Value::Error => (core::Term::new(term.range, core::TermData::Error), None), found_type => { let found_type = self.read_back_to_surface_term(&found_type); self.report(SurfaceToCoreMessage::MismatchedTypes { - range: term.range(), + range: term.range, found_type, expected_type: ExpectedType::Universe, }); - (core::Term::new(term.range(), core::TermData::Error), None) + (core::Term::new(term.range, core::TermData::Error), None) } } } @@ -217,7 +216,7 @@ impl<'me> State<'me> { #[debug_ensures(self.local_definitions.size() == old(self.local_definitions.size()))] pub fn check_type(&mut self, term: &Term, expected_type: &Arc) -> core::Term { match (&term.data, expected_type.force(self.globals)) { - (_, Value::Error) => core::Term::new(term.range(), core::TermData::Error), + (_, Value::Error) => core::Term::new(term.range, core::TermData::Error), (TermData::FunctionTerm(input_names, output_term), _) => { let mut seen_input_count = 0; @@ -234,17 +233,17 @@ impl<'me> State<'me> { } Value::Error => { self.pop_many_locals(seen_input_count); - return core::Term::new(term.range(), core::TermData::Error); + return core::Term::new(term.range, core::TermData::Error); } _ => { self.report(SurfaceToCoreMessage::TooManyInputsInFunctionTerm { - unexpected_inputs: std::iter::once(input_name.range()) - .chain(pending_input_names.map(|input_name| input_name.range())) + unexpected_inputs: std::iter::once(input_name.range) + .chain(pending_input_names.map(|input_name| input_name.range)) .collect(), }); self.check_type(output_term, &expected_type); self.pop_many_locals(seen_input_count); - return core::Term::new(term.range(), core::TermData::Error); + return core::Term::new(term.range, core::TermData::Error); } } } @@ -253,7 +252,7 @@ impl<'me> State<'me> { self.pop_many_locals(seen_input_count); (input_names.iter().rev()).fold(core_output_term, |core_output_term, input_name| { core::Term::new( - input_name.range().start..core_output_term.range().end, + Range::from(input_name.range.start..core_output_term.range.end), core::TermData::FunctionTerm( input_name.data.clone(), Arc::new(core_output_term), @@ -285,7 +284,7 @@ impl<'me> State<'me> { return core_entry_value; } - Some((next_label, _, _)) => unexpected_labels.push(next_label.range()), + Some((next_label, _, _)) => unexpected_labels.push(next_label.range), None => { missing_labels.push(label.to_owned()); return Arc::new(Value::Error); @@ -294,18 +293,18 @@ impl<'me> State<'me> { }); self.pop_many_locals(core_term_entries.len()); - unexpected_labels.extend(pending_term_entries.map(|(label, _, _)| label.range())); + unexpected_labels.extend(pending_term_entries.map(|(label, _, _)| label.range)); if !missing_labels.is_empty() || !unexpected_labels.is_empty() { self.report(SurfaceToCoreMessage::InvalidRecordTerm { - range: term.range(), + range: term.range, missing_labels, unexpected_labels, }); } core::Term::new( - term.range(), + term.range, core::TermData::RecordTerm(core_term_entries.into()), ) } @@ -324,19 +323,19 @@ impl<'me> State<'me> { if *len as usize == entry_terms.len() => { core::Term::new( - term.range(), + term.range, core::TermData::SequenceTerm(core_entry_terms), ) } - Value::Error => core::Term::new(term.range(), core::TermData::Error), + Value::Error => core::Term::new(term.range, core::TermData::Error), _ => { let expected_len = self.read_back_to_surface_term(&len); self.report(SurfaceToCoreMessage::MismatchedSequenceLength { - range: term.range(), + range: term.range, found_len: entry_terms.len(), expected_len, }); - core::Term::new(term.range(), core::TermData::Error) + core::Term::new(term.range, core::TermData::Error) } } } @@ -347,61 +346,61 @@ impl<'me> State<'me> { .map(|entry_term| Arc::new(self.check_type(entry_term, core_entry_type))) .collect(); - core::Term::new(term.range(), core::TermData::SequenceTerm(core_entry_terms)) + core::Term::new(term.range, core::TermData::SequenceTerm(core_entry_terms)) } Some(_) | None => { let expected_type = self.read_back_to_surface_term(expected_type); self.report(SurfaceToCoreMessage::NoSequenceConversion { - range: term.range(), + range: term.range, expected_type, }); - core::Term::new(term.range(), core::TermData::Error) + core::Term::new(term.range, core::TermData::Error) } }, (TermData::NumberTerm(data), forced_type) => { use crate::lang::core::Constant::*; match forced_type.try_global() { - Some(("U8", _, [])) => self.parse_unsigned(term.range(), data, U8), - Some(("U16", _, [])) => self.parse_unsigned(term.range(), data, U16), - Some(("U32", _, [])) => self.parse_unsigned(term.range(), data, U32), - Some(("U64", _, [])) => self.parse_unsigned(term.range(), data, U64), - Some(("S8", _, [])) => self.parse_signed(term.range(), data, S8), - Some(("S16", _, [])) => self.parse_signed(term.range(), data, S16), - Some(("S32", _, [])) => self.parse_signed(term.range(), data, S32), - Some(("S64", _, [])) => self.parse_signed(term.range(), data, S64), - Some(("F32", _, [])) => self.parse_float(term.range(), data, F32), - Some(("F64", _, [])) => self.parse_float(term.range(), data, F64), + Some(("U8", _, [])) => self.parse_unsigned(term.range, data, U8), + Some(("U16", _, [])) => self.parse_unsigned(term.range, data, U16), + Some(("U32", _, [])) => self.parse_unsigned(term.range, data, U32), + Some(("U64", _, [])) => self.parse_unsigned(term.range, data, U64), + Some(("S8", _, [])) => self.parse_signed(term.range, data, S8), + Some(("S16", _, [])) => self.parse_signed(term.range, data, S16), + Some(("S32", _, [])) => self.parse_signed(term.range, data, S32), + Some(("S64", _, [])) => self.parse_signed(term.range, data, S64), + Some(("F32", _, [])) => self.parse_float(term.range, data, F32), + Some(("F64", _, [])) => self.parse_float(term.range, data, F64), Some(_) | None => { let expected_type = self.read_back_to_surface_term(expected_type); self.report(SurfaceToCoreMessage::NoLiteralConversion { - range: term.range(), + range: term.range, expected_type, }); - core::Term::new(term.range(), core::TermData::Error) + core::Term::new(term.range, core::TermData::Error) } } } (TermData::CharTerm(data), forced_type) => match forced_type.try_global() { - Some(("Char", _, [])) => self.parse_char(term.range(), data), + Some(("Char", _, [])) => self.parse_char(term.range, data), Some(_) | None => { let expected_type = self.read_back_to_surface_term(expected_type); self.report(SurfaceToCoreMessage::NoLiteralConversion { - range: term.range(), + range: term.range, expected_type, }); - core::Term::new(term.range(), core::TermData::Error) + core::Term::new(term.range, core::TermData::Error) } }, (TermData::StringTerm(data), forced_type) => match forced_type.try_global() { - Some(("String", _, [])) => self.parse_string(term.range(), data), + Some(("String", _, [])) => self.parse_string(term.range, data), Some(_) | None => { let expected_type = self.read_back_to_surface_term(expected_type); self.report(SurfaceToCoreMessage::NoLiteralConversion { - range: term.range(), + range: term.range, expected_type, }); - core::Term::new(term.range(), core::TermData::Error) + core::Term::new(term.range, core::TermData::Error) } }, @@ -411,11 +410,11 @@ impl<'me> State<'me> { let found_type = self.read_back_to_surface_term(&found_type); let expected_type = self.read_back_to_surface_term(expected_type); self.report(SurfaceToCoreMessage::MismatchedTypes { - range: term.range(), + range: term.range, found_type, expected_type: ExpectedType::Type(expected_type), }); - core::Term::new(term.range(), core::TermData::Error) + core::Term::new(term.range, core::TermData::Error) } }, } @@ -429,18 +428,18 @@ impl<'me> State<'me> { pub fn synth_type(&mut self, term: &Term) -> (core::Term, Arc) { use std::collections::BTreeMap; - let error_term = || core::Term::new(term.range(), core::TermData::Error); + let error_term = || core::Term::new(term.range, core::TermData::Error); match &term.data { TermData::Name(name) => { if let Some((index, r#type)) = self.get_local(name.as_ref()) { - let core_term = core::Term::new(term.range(), core::TermData::Local(index)); + let core_term = core::Term::new(term.range, core::TermData::Local(index)); return (core_term, r#type.clone()); } if let Some((r#type, _)) = self.globals.get(name.as_ref()) { let name = name.clone(); - let global = core::Term::new(term.range(), core::TermData::Global(name)); + let global = core::Term::new(term.range, core::TermData::Global(name)); let core_term = match self.universe_offset { core::UniverseOffset(0) => global, offset => core::Term::from(core::TermData::Lift(Arc::new(global), offset)), @@ -449,7 +448,7 @@ impl<'me> State<'me> { } self.report(SurfaceToCoreMessage::UnboundName { - range: term.range(), + range: term.range, name: name.clone(), }); (error_term(), Arc::new(Value::Error)) @@ -461,7 +460,7 @@ impl<'me> State<'me> { let core_term = self.check_type(term, &core_type_value); ( core::Term::new( - term.range(), + term.range, core::TermData::Ann(Arc::new(core_term), Arc::new(core_type)), ), core_type_value, @@ -478,7 +477,7 @@ impl<'me> State<'me> { } None => { self.report(SurfaceToCoreMessage::MaximumUniverseLevelReached { - range: term.range(), + range: term.range, }); (error_term(), Arc::new(Value::Error)) } @@ -515,7 +514,7 @@ impl<'me> State<'me> { let mut core_type = core_output_type; for (input_name, input_type) in core_inputs.into_iter().rev() { core_type = core::Term::new( - input_name.range().start..output_type.range().end, + Range::from(input_name.range.start..output_type.range.end), core::TermData::FunctionType( Some(input_name.data), Arc::new(input_type), @@ -542,7 +541,7 @@ impl<'me> State<'me> { match (input_level, output_level) { (Some(input_level), Some(output_level)) => ( core::Term::new( - term.range(), + term.range, core::TermData::FunctionType( None, Arc::new(core_input_type), @@ -556,24 +555,24 @@ impl<'me> State<'me> { } TermData::FunctionTerm(_, _) => { self.report(SurfaceToCoreMessage::AmbiguousTerm { - range: term.range(), + range: term.range, term: AmbiguousTerm::FunctionTerm, }); (error_term(), Arc::new(Value::Error)) } TermData::FunctionElim(head_term, input_terms) => { - let mut head_range = head_term.range(); + let mut head_range = head_term.range; let (mut core_head_term, mut head_type) = self.synth_type(head_term); let mut input_terms = input_terms.iter(); while let Some(input) = input_terms.next() { match head_type.force(self.globals) { Value::FunctionType(_, input_type, output_closure) => { - head_range.end = input.range().end; + head_range.end = input.range.end; let core_input = self.check_type(input, &input_type); let core_input_value = self.eval_term(&core_input); core_head_term = core::Term::new( - head_range.start..input.range().end, + Range::from(head_range.start..input.range.end), core::TermData::FunctionElim( Arc::new(core_head_term), Arc::new(core_input), @@ -584,8 +583,7 @@ impl<'me> State<'me> { Value::Error => return (error_term(), Arc::new(Value::Error)), _ => { let head_type = self.read_back_to_surface_term(&head_type); - let unexpected_input_terms = - input_terms.map(|arg| arg.range()).collect(); + let unexpected_input_terms = input_terms.map(|arg| arg.range).collect(); self.report(SurfaceToCoreMessage::TooManyInputsInFunctionElim { head_range, head_type, @@ -602,7 +600,7 @@ impl<'me> State<'me> { TermData::RecordTerm(term_entries) => { if term_entries.is_empty() { ( - core::Term::new(term.range(), core::TermData::RecordTerm(Arc::new([]))), + core::Term::new(term.range, core::TermData::RecordTerm(Arc::new([]))), Arc::from(Value::RecordType(RecordClosure::new( self.universe_offset, self.local_definitions.clone(), @@ -611,7 +609,7 @@ impl<'me> State<'me> { ) } else { self.report(SurfaceToCoreMessage::AmbiguousTerm { - range: term.range(), + range: term.range, term: AmbiguousTerm::RecordTerm, }); (error_term(), Arc::new(Value::Error)) @@ -641,13 +639,13 @@ impl<'me> State<'me> { let core_type_value = self.eval_term(&core_type); core_type_entries.push((label.data.clone(), core_type)); self.push_local_param(Some(&name.data), core_type_value); - entry.insert(label.range()); + entry.insert(label.range); } Entry::Occupied(entry) => { duplicate_labels.push(( (*entry.key()).to_owned(), entry.get().clone(), - label.range(), + label.range, )); self.is_type(entry_type); } @@ -661,7 +659,7 @@ impl<'me> State<'me> { self.pop_many_locals(seen_labels.len()); ( core::Term::new( - term.range(), + term.range, core::TermData::RecordType(core_type_entries.into()), ), Arc::new(Value::TypeType(max_level)), @@ -679,7 +677,7 @@ impl<'me> State<'me> { { let core_head_term = Arc::new(core_head_term); let core_term = core::Term::new( - term.range(), + term.range, core::TermData::RecordElim(core_head_term, label.data.clone()), ); return (core_term, entry_type); @@ -691,8 +689,8 @@ impl<'me> State<'me> { let head_type = self.read_back_to_surface_term(&head_type); self.report(SurfaceToCoreMessage::LabelNotFound { - head_range: head_term.range(), - label_range: label.range(), + head_range: head_term.range, + label_range: label.range, expected_label: label.data.clone(), head_type, }); @@ -701,7 +699,7 @@ impl<'me> State<'me> { TermData::SequenceTerm(_) => { self.report(SurfaceToCoreMessage::AmbiguousTerm { - range: term.range(), + range: term.range, term: AmbiguousTerm::Sequence, }); (error_term(), Arc::new(Value::Error)) @@ -709,17 +707,17 @@ impl<'me> State<'me> { TermData::NumberTerm(_) => { self.report(SurfaceToCoreMessage::AmbiguousTerm { - range: term.range(), + range: term.range, term: AmbiguousTerm::NumberLiteral, }); (error_term(), Arc::new(Value::Error)) } TermData::CharTerm(data) => ( - self.parse_char(term.range(), data), + self.parse_char(term.range, data), Arc::new(Value::global("Char", 0)), ), TermData::StringTerm(data) => ( - self.parse_string(term.range(), data), + self.parse_string(term.range, data), Arc::new(Value::global("String", 0)), ), @@ -729,11 +727,11 @@ impl<'me> State<'me> { fn parse_float>( &mut self, - range: Range, + range: Range, data: &str, make_constant: fn(T) -> core::Constant, ) -> core::Term { - let term_data = literal::State::new(range.clone(), data, &self.message_tx) + let term_data = literal::State::new(range, data, &self.message_tx) .number_to_float() .map(make_constant) .map_or(core::TermData::Error, core::TermData::from); @@ -743,11 +741,11 @@ impl<'me> State<'me> { fn parse_unsigned( &mut self, - range: Range, + range: Range, source: &str, make_constant: fn(T) -> core::Constant, ) -> core::Term { - let term_data = literal::State::new(range.clone(), source, &self.message_tx) + let term_data = literal::State::new(range, source, &self.message_tx) .number_to_unsigned_int() .map(make_constant) .map_or(core::TermData::Error, core::TermData::from); @@ -757,11 +755,11 @@ impl<'me> State<'me> { fn parse_signed( &mut self, - range: Range, + range: Range, source: &str, make_constant: fn(T) -> core::Constant, ) -> core::Term { - let term_data = literal::State::new(range.clone(), source, &self.message_tx) + let term_data = literal::State::new(range, source, &self.message_tx) .number_to_signed_int() .map(make_constant) .map_or(core::TermData::Error, core::TermData::from); @@ -769,8 +767,8 @@ impl<'me> State<'me> { core::Term::new(range, term_data) } - fn parse_char(&mut self, range: Range, source: &str) -> core::Term { - let term_data = literal::State::new(range.clone(), source, &self.message_tx) + fn parse_char(&mut self, range: Range, source: &str) -> core::Term { + let term_data = literal::State::new(range, source, &self.message_tx) .quoted_to_unicode_char() .map(core::Constant::Char) .map_or(core::TermData::Error, core::TermData::from); @@ -778,8 +776,8 @@ impl<'me> State<'me> { core::Term::new(range, term_data) } - fn parse_string(&mut self, range: Range, source: &str) -> core::Term { - let term_data = literal::State::new(range.clone(), source, &self.message_tx) + fn parse_string(&mut self, range: Range, source: &str) -> core::Term { + let term_data = literal::State::new(range, source, &self.message_tx) .quoted_to_utf8_string() .map(core::Constant::String) .map_or(core::TermData::Error, core::TermData::from); diff --git a/pikelet/src/reporting.rs b/pikelet/src/reporting.rs index 7dc414d22..e39f63a09 100644 --- a/pikelet/src/reporting.rs +++ b/pikelet/src/reporting.rs @@ -2,9 +2,8 @@ use codespan_reporting::diagnostic::{Diagnostic, Label}; use pretty::DocAllocator; -use std::ops::Range; -use crate::lang::{core, surface}; +use crate::lang::{core, surface, Range}; use crate::literal; /// Global diagnostic messages @@ -64,24 +63,24 @@ impl Message { match error { InvalidToken { location } => Message::from(LexerError::InvalidToken { - range: location..location, + range: Range::from(location..location), }), UnrecognizedEOF { location, expected } => Message::from(ParseError::UnrecognizedEOF { - range: location..location, + range: Range::from(location..location), expected, }), UnrecognizedToken { token: (start, token, end), expected, } => Message::from(ParseError::UnrecognizedToken { - range: start..end, + range: Range::from(start..end), token: token.to_string(), expected, }), ExtraToken { token: (start, token, end), } => Message::from(ParseError::ExtraToken { - range: start..end, + range: Range::from(start..end), token: token.to_string(), }), User { error } => Message::from(error), @@ -106,7 +105,7 @@ impl Message { /// Lexer errors #[derive(Debug, Clone)] pub enum LexerError { - InvalidToken { range: Range }, + InvalidToken { range: Range }, } impl LexerError { @@ -114,7 +113,7 @@ impl LexerError { match self { LexerError::InvalidToken { range } => Diagnostic::error() .with_message("invalid token") - .with_labels(vec![Label::primary((), range.clone())]), + .with_labels(vec![Label::primary((), *range)]), } } } @@ -123,16 +122,16 @@ impl LexerError { #[derive(Clone, Debug)] pub enum ParseError { UnrecognizedEOF { - range: Range, + range: Range, expected: Vec, }, UnrecognizedToken { - range: Range, + range: Range, token: String, expected: Vec, }, ExtraToken { - range: Range, + range: Range, token: String, }, } @@ -143,7 +142,7 @@ impl ParseError { ParseError::UnrecognizedEOF { range, expected } => Diagnostic::error() .with_message("unexpected end of file") .with_labels(vec![ - Label::primary((), range.clone()).with_message("unexpected end of file") + Label::primary((), *range).with_message("unexpected end of file") ]) .with_notes(format_expected(expected).map_or(Vec::new(), |message| vec![message])), ParseError::UnrecognizedToken { @@ -153,14 +152,12 @@ impl ParseError { } => Diagnostic::error() .with_message(format!("unexpected token {}", token)) .with_labels(vec![ - Label::primary((), range.clone()).with_message("unexpected token") + Label::primary((), *range).with_message("unexpected token") ]) .with_notes(format_expected(expected).map_or(Vec::new(), |message| vec![message])), ParseError::ExtraToken { range, token } => Diagnostic::error() .with_message(format!("extra token {}", token)) - .with_labels(vec![ - Label::primary((), range.clone()).with_message("extra token") - ]), + .with_labels(vec![Label::primary((), *range).with_message("extra token")]), } } } @@ -177,29 +174,29 @@ fn format_expected(expected: &[String]) -> Option { #[derive(Clone, Debug)] pub enum LiteralParseMessage { - ExpectedRadixOrDecimalDigit(Range), - ExpectedStartOfNumericLiteral(Range), - NegativeUnsignedInteger(Range), - ExpectedDigit(Range, literal::Base), - ExpectedDigitOrSeparator(Range, literal::Base), - ExpectedDigitSeparatorOrExp(Range, literal::Base), - ExpectedDigitSeparatorFracOrExp(Range, literal::Base), - FloatLiteralExponentNotSupported(Range), - UnsupportedFloatLiteralBase(Range, literal::Base), - LiteralOutOfRange(Range), - OverlongCharLiteral(Range), - EmptyCharLiteral(Range), - OversizedUnicodeEscapeCode(Range), - EmptyUnicodeEscapeCode(Range), - OverlongUnicodeEscapeCode(Range), - InvalidUnicodeEscapeCode(Range), - InvalidUnicodeEscape(Range), - OversizedAsciiEscapeCode(Range), - InvalidAsciiEscape(Range), - UnknownEscapeSequence(Range), - InvalidToken(Range), - ExpectedEndOfLiteral(Range), - UnexpectedEndOfLiteral(Range), + ExpectedRadixOrDecimalDigit(Range), + ExpectedStartOfNumericLiteral(Range), + NegativeUnsignedInteger(Range), + ExpectedDigit(Range, literal::Base), + ExpectedDigitOrSeparator(Range, literal::Base), + ExpectedDigitSeparatorOrExp(Range, literal::Base), + ExpectedDigitSeparatorFracOrExp(Range, literal::Base), + FloatLiteralExponentNotSupported(Range), + UnsupportedFloatLiteralBase(Range, literal::Base), + LiteralOutOfRange(Range), + OverlongCharLiteral(Range), + EmptyCharLiteral(Range), + OversizedUnicodeEscapeCode(Range), + EmptyUnicodeEscapeCode(Range), + OverlongUnicodeEscapeCode(Range), + InvalidUnicodeEscapeCode(Range), + InvalidUnicodeEscape(Range), + OversizedAsciiEscapeCode(Range), + InvalidAsciiEscape(Range), + UnknownEscapeSequence(Range), + InvalidToken(Range), + ExpectedEndOfLiteral(Range), + UnexpectedEndOfLiteral(Range), } impl LiteralParseMessage { @@ -207,104 +204,104 @@ impl LiteralParseMessage { match self { LiteralParseMessage::ExpectedRadixOrDecimalDigit(range) => Diagnostic::error() .with_message("expected a radix or decimal digit") - .with_labels(vec![Label::primary((), range.clone())]), + .with_labels(vec![Label::primary((), *range)]), LiteralParseMessage::ExpectedStartOfNumericLiteral(range) => Diagnostic::error() .with_message("expected the start of a numeric literal") - .with_labels(vec![Label::primary((), range.clone())]), + .with_labels(vec![Label::primary((), *range)]), LiteralParseMessage::NegativeUnsignedInteger(range) => Diagnostic::error() .with_message("unsigned integer literals cannot be negative") - .with_labels(vec![Label::primary((), range.clone())]), + .with_labels(vec![Label::primary((), *range)]), LiteralParseMessage::ExpectedDigit(range, base) => Diagnostic::error() .with_message(format!("expected a base {} digit", base.to_u8())) - .with_labels(vec![Label::primary((), range.clone())]), + .with_labels(vec![Label::primary((), *range)]), LiteralParseMessage::ExpectedDigitOrSeparator(range, base) => Diagnostic::error() .with_message(format!( "expected a base {} digit or digit separator", base.to_u8(), )) - .with_labels(vec![Label::primary((), range.clone())]), + .with_labels(vec![Label::primary((), *range)]), LiteralParseMessage::ExpectedDigitSeparatorOrExp(range, base) => Diagnostic::error() .with_message(format!( "expected a base {} digit, digit separator, or exponent", base.to_u8(), )) - .with_labels(vec![Label::primary((), range.clone())]), + .with_labels(vec![Label::primary((), *range)]), LiteralParseMessage::ExpectedDigitSeparatorFracOrExp(range, base) => { Diagnostic::error() .with_message(format!( "expected a base {} digit, digit separator, period, or exponent", base.to_u8(), )) - .with_labels(vec![Label::primary((), range.clone())]) + .with_labels(vec![Label::primary((), *range)]) } LiteralParseMessage::FloatLiteralExponentNotSupported(range) => Diagnostic::error() .with_message("exponents are not yet supported for float literals") - .with_labels(vec![Label::primary((), range.clone())]), + .with_labels(vec![Label::primary((), *range)]), LiteralParseMessage::UnsupportedFloatLiteralBase(range, base) => Diagnostic::error() .with_message(format!( "base {} float literals are not yet supported", base.to_u8(), )) - .with_labels(vec![Label::primary((), range.clone())]) + .with_labels(vec![Label::primary((), *range)]) .with_notes(vec![ "only base 10 float literals are currently supported".to_owned() ]), LiteralParseMessage::LiteralOutOfRange(range) => Diagnostic::error() .with_message("literal out of range") - .with_labels(vec![Label::primary((), range.clone())]), + .with_labels(vec![Label::primary((), *range)]), LiteralParseMessage::OverlongCharLiteral(range) => Diagnostic::error() .with_message("too many codepoints in character literal") - .with_labels(vec![Label::primary((), range.clone())]) + .with_labels(vec![Label::primary((), *range)]) .with_notes(vec![ "character literals may only contain one codepoint".to_owned() ]), LiteralParseMessage::EmptyCharLiteral(range) => Diagnostic::error() .with_message("empty character literal") - .with_labels(vec![Label::primary((), range.clone())]) + .with_labels(vec![Label::primary((), *range)]) .with_notes(vec!["character literals must not be empty".to_owned()]), LiteralParseMessage::OversizedUnicodeEscapeCode(range) => Diagnostic::error() .with_message("unicode escape code exceeds maximum allowed range") - .with_labels(vec![Label::primary((), range.clone())]) + .with_labels(vec![Label::primary((), *range)]) .with_notes(vec![format!("must be at most {:X} ", literal::MAX_UNICODE)]), LiteralParseMessage::EmptyUnicodeEscapeCode(range) => Diagnostic::error() .with_message("empty unicode character code") - .with_labels(vec![Label::primary((), range.clone())]) + .with_labels(vec![Label::primary((), *range)]) .with_notes(vec!["must contain at least one hex digit".to_owned()]), LiteralParseMessage::OverlongUnicodeEscapeCode(range) => Diagnostic::error() .with_message("too many digits in unicode character code") - .with_labels(vec![Label::primary((), range.clone())]) + .with_labels(vec![Label::primary((), *range)]) .with_notes(vec!["must contain at most six hex digits".to_owned()]), LiteralParseMessage::InvalidUnicodeEscapeCode(range) => Diagnostic::error() .with_message("invalid unicode escape code") - .with_labels(vec![Label::primary((), range.clone())]) + .with_labels(vec![Label::primary((), *range)]) .with_notes(vec!["must contain only hex digits".to_owned()]), LiteralParseMessage::InvalidUnicodeEscape(range) => Diagnostic::error() .with_message("invalid unicode escape sequence") - .with_labels(vec![Label::primary((), range.clone())]) + .with_labels(vec![Label::primary((), *range)]) .with_notes(vec![ "must be followed with a braced sequence of hex digits".to_owned(), "for example: `\\u{..}`".to_owned(), ]), LiteralParseMessage::OversizedAsciiEscapeCode(range) => Diagnostic::error() .with_message("ACII escape code exceeds maximum allowed range") - .with_labels(vec![Label::primary((), range.clone())]) + .with_labels(vec![Label::primary((), *range)]) .with_notes(vec![format!("must be at most {:X} ", literal::MAX_ASCII)]), LiteralParseMessage::InvalidAsciiEscape(range) => Diagnostic::error() .with_message("invalid ASCII escape") - .with_labels(vec![Label::primary((), range.clone())]) + .with_labels(vec![Label::primary((), *range)]) .with_notes(vec!["must contain exactly two hex digits ".to_owned()]), LiteralParseMessage::UnknownEscapeSequence(range) => Diagnostic::error() .with_message("unknown escape sequence") - .with_labels(vec![Label::primary((), range.clone())]), + .with_labels(vec![Label::primary((), *range)]), LiteralParseMessage::InvalidToken(range) => Diagnostic::error() .with_message("invalid token") - .with_labels(vec![Label::primary((), range.clone())]), + .with_labels(vec![Label::primary((), *range)]), LiteralParseMessage::ExpectedEndOfLiteral(range) => Diagnostic::error() .with_message("expected end of literal") - .with_labels(vec![Label::primary((), range.clone())]), + .with_labels(vec![Label::primary((), *range)]), LiteralParseMessage::UnexpectedEndOfLiteral(range) => Diagnostic::error() .with_message("unexpected end of literal") - .with_labels(vec![Label::primary((), range.clone())]), + .with_labels(vec![Label::primary((), *range)]), } } } @@ -491,53 +488,53 @@ impl CoreTypingMessage { #[derive(Clone, Debug)] pub enum SurfaceToCoreMessage { MaximumUniverseLevelReached { - range: Range, + range: Range, }, UnboundName { - range: Range, + range: Range, name: String, }, InvalidRecordType { - duplicate_labels: Vec<(String, Range, Range)>, + duplicate_labels: Vec<(String, Range, Range)>, }, InvalidRecordTerm { - range: Range, + range: Range, missing_labels: Vec, - unexpected_labels: Vec>, + unexpected_labels: Vec, }, LabelNotFound { - head_range: Range, - label_range: Range, + head_range: Range, + label_range: Range, expected_label: String, head_type: surface::Term, }, TooManyInputsInFunctionTerm { - unexpected_inputs: Vec>, + unexpected_inputs: Vec, }, TooManyInputsInFunctionElim { - head_range: Range, + head_range: Range, head_type: surface::Term, - unexpected_input_terms: Vec>, + unexpected_input_terms: Vec, }, NoLiteralConversion { - range: Range, + range: Range, expected_type: surface::Term, }, MismatchedSequenceLength { - range: Range, + range: Range, found_len: usize, expected_len: surface::Term, }, NoSequenceConversion { - range: Range, + range: Range, expected_type: surface::Term, }, AmbiguousTerm { - range: Range, + range: Range, term: AmbiguousTerm, }, MismatchedTypes { - range: Range, + range: Range, found_type: surface::Term, expected_type: ExpectedType, }, @@ -559,14 +556,14 @@ impl SurfaceToCoreMessage { SurfaceToCoreMessage::MaximumUniverseLevelReached { range } => Diagnostic::error() .with_message("maximum universe level reached") .with_labels(vec![ - Label::primary((), range.clone()).with_message("overflowing universe level") + Label::primary((), *range).with_message("overflowing universe level") ]), SurfaceToCoreMessage::UnboundName { range, name } => Diagnostic::error() .with_message(format!("cannot find `{}` in this scope", name)) // TODO: name suggestions? .with_labels(vec![ - Label::primary((), range.clone()).with_message("not found in this scope") + Label::primary((), *range).with_message("not found in this scope") ]), SurfaceToCoreMessage::InvalidRecordType { duplicate_labels } => Diagnostic::error() @@ -601,13 +598,12 @@ impl SurfaceToCoreMessage { for label_range in unexpected_labels { labels.push( - Label::primary((), label_range.clone()) - .with_message("unexpected entry label"), + Label::primary((), *label_range).with_message("unexpected entry label"), ); } if !missing_labels.is_empty() { - labels.push(Label::primary((), range.clone()).with_message(format!( + labels.push(Label::primary((), *range).with_message(format!( "missing the labels {} in this record term", missing_labels .iter() @@ -632,8 +628,8 @@ impl SurfaceToCoreMessage { to_doc(&head_type).pretty(std::usize::MAX), )) .with_labels(vec![ - Label::primary((), label_range.clone()).with_message("unknown entry label"), - Label::secondary((), head_range.clone()).with_message(format!( + Label::primary((), *label_range).with_message("unknown entry label"), + Label::secondary((), *head_range).with_message(format!( "the type here is `{}`", to_doc(&head_type).pretty(std::usize::MAX), )), @@ -646,8 +642,7 @@ impl SurfaceToCoreMessage { unexpected_inputs .iter() .map(|input_range| { - Label::primary((), input_range.clone()) - .with_message("unexpected input") + Label::primary((), *input_range).with_message("unexpected input") }) .collect(), ) @@ -660,14 +655,13 @@ impl SurfaceToCoreMessage { } => Diagnostic::error() .with_message("term was applied to too many inputs") .with_labels( - std::iter::once(Label::primary((), head_range.clone()).with_message(format!( + std::iter::once(Label::primary((), *head_range).with_message(format!( // TODO: multi-line? "expected a function, found `{}`", to_doc(&head_type).pretty(std::usize::MAX), ))) .chain(unexpected_input_terms.iter().map(|input_range| { - Label::primary((), input_range.clone()) - .with_message("unexpected input".to_owned()) + Label::primary((), *input_range).with_message("unexpected input".to_owned()) })) .collect(), ), @@ -677,13 +671,11 @@ impl SurfaceToCoreMessage { expected_type, } => Diagnostic::error() .with_message("no known literal conversion") - .with_labels(vec![Label::primary((), range.clone()).with_message( - format!( - // TODO: multi-line? - "expected `{}`, found a literal", - to_doc(&expected_type).pretty(std::usize::MAX), - ), - )]), + .with_labels(vec![Label::primary((), *range).with_message(format!( + // TODO: multi-line? + "expected `{}`, found a literal", + to_doc(&expected_type).pretty(std::usize::MAX), + ))]), SurfaceToCoreMessage::MismatchedSequenceLength { range, @@ -691,32 +683,28 @@ impl SurfaceToCoreMessage { expected_len, } => Diagnostic::error() .with_message("mismatched sequence length") - .with_labels(vec![Label::primary((), range.clone()).with_message( - format!( - // TODO: multi-line? - "expected `{}` entries, found `{}` entries", - to_doc(&expected_len).pretty(std::usize::MAX), - found_len, - ), - )]), + .with_labels(vec![Label::primary((), *range).with_message(format!( + // TODO: multi-line? + "expected `{}` entries, found `{}` entries", + to_doc(&expected_len).pretty(std::usize::MAX), + found_len, + ))]), SurfaceToCoreMessage::NoSequenceConversion { range, expected_type, } => Diagnostic::error() .with_message("no known sequence conversion") - .with_labels(vec![Label::primary((), range.clone()).with_message( - format!( - // TODO: multi-line? - "expected `{}`, found a sequence", - to_doc(&expected_type).pretty(std::usize::MAX), - ), - )]), + .with_labels(vec![Label::primary((), *range).with_message(format!( + // TODO: multi-line? + "expected `{}`, found a sequence", + to_doc(&expected_type).pretty(std::usize::MAX), + ))]), SurfaceToCoreMessage::AmbiguousTerm { range, term } => Diagnostic::error() .with_message(format!("ambiguous {}", term.description())) .with_labels(vec![ - Label::primary((), range.clone()).with_message("type annotations needed") + Label::primary((), *range).with_message("type annotations needed") ]), SurfaceToCoreMessage::MismatchedTypes { @@ -725,7 +713,7 @@ impl SurfaceToCoreMessage { expected_type, } => Diagnostic::error() .with_message("mismatched types") - .with_labels(vec![Label::primary((), range.clone()).with_message( + .with_labels(vec![Label::primary((), *range).with_message( match expected_type { ExpectedType::Universe => format!( // TODO: multi-line?