mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 12:24:45 +00:00
Add AtomicStr
This commit is contained in:
parent
fb36c0d633
commit
fe1b0fab70
11 changed files with 300 additions and 105 deletions
166
compiler/erg_common/astr.rs
Normal file
166
compiler/erg_common/astr.rs
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
use std::borrow::Borrow;
|
||||||
|
use std::fmt;
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
|
use std::ops::{Add, Deref};
|
||||||
|
|
||||||
|
use crate::Str;
|
||||||
|
|
||||||
|
pub type ArcStr = std::sync::Arc<str>;
|
||||||
|
|
||||||
|
/// Used to hold an immutable string.
|
||||||
|
///
|
||||||
|
/// It can construct as a const (by AtomicStr::ever).
|
||||||
|
#[derive(Debug, Clone, Eq)]
|
||||||
|
pub enum AtomicStr {
|
||||||
|
Arc(ArcStr),
|
||||||
|
Static(&'static str),
|
||||||
|
}
|
||||||
|
|
||||||
|
// unsafe impl Sync for AtomicStr {}
|
||||||
|
|
||||||
|
impl PartialEq for AtomicStr {
|
||||||
|
#[inline]
|
||||||
|
fn eq(&self, other: &AtomicStr) -> bool {
|
||||||
|
self[..] == other[..]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add<&str> for AtomicStr {
|
||||||
|
type Output = AtomicStr;
|
||||||
|
#[inline]
|
||||||
|
fn add(self, other: &str) -> AtomicStr {
|
||||||
|
AtomicStr::from(&format!("{self}{other}"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hash for AtomicStr {
|
||||||
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
match self {
|
||||||
|
AtomicStr::Arc(s) => (s[..]).hash(state),
|
||||||
|
AtomicStr::Static(s) => s.hash(state),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for AtomicStr {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
AtomicStr::Arc(s) => write!(f, "{s}"),
|
||||||
|
AtomicStr::Static(s) => write!(f, "{s}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// &'static str -> &strになってしまわないように
|
||||||
|
// あえて`impl<S: Into<Str>> From<S> for AtomicStr { ... }`はしない
|
||||||
|
impl From<&'static str> for AtomicStr {
|
||||||
|
#[inline]
|
||||||
|
fn from(s: &'static str) -> Self {
|
||||||
|
AtomicStr::ever(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&String> for AtomicStr {
|
||||||
|
#[inline]
|
||||||
|
fn from(s: &String) -> Self {
|
||||||
|
AtomicStr::Arc((s[..]).into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for AtomicStr {
|
||||||
|
#[inline]
|
||||||
|
fn from(s: String) -> Self {
|
||||||
|
AtomicStr::Arc((s[..]).into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&ArcStr> for AtomicStr {
|
||||||
|
#[inline]
|
||||||
|
fn from(s: &ArcStr) -> Self {
|
||||||
|
AtomicStr::Arc(s.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ArcStr> for AtomicStr {
|
||||||
|
#[inline]
|
||||||
|
fn from(s: ArcStr) -> Self {
|
||||||
|
AtomicStr::Arc(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&AtomicStr> for AtomicStr {
|
||||||
|
#[inline]
|
||||||
|
fn from(s: &AtomicStr) -> Self {
|
||||||
|
match s {
|
||||||
|
AtomicStr::Arc(s) => AtomicStr::Arc(s.clone()),
|
||||||
|
AtomicStr::Static(s) => AtomicStr::Static(s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Str> for AtomicStr {
|
||||||
|
#[inline]
|
||||||
|
fn from(s: Str) -> Self {
|
||||||
|
match s {
|
||||||
|
Str::Rc(s) => AtomicStr::Arc((&s[..]).into()),
|
||||||
|
Str::Static(s) => AtomicStr::Static(s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&Str> for AtomicStr {
|
||||||
|
#[inline]
|
||||||
|
fn from(s: &Str) -> Self {
|
||||||
|
match s {
|
||||||
|
Str::Rc(s) => AtomicStr::Arc((&s[..]).into()),
|
||||||
|
Str::Static(s) => AtomicStr::Static(s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for AtomicStr {
|
||||||
|
type Target = str;
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
self.borrow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Borrow<str> for AtomicStr {
|
||||||
|
#[inline]
|
||||||
|
fn borrow(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
AtomicStr::Arc(s) => s.borrow(),
|
||||||
|
AtomicStr::Static(s) => s,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRef<str> for AtomicStr {
|
||||||
|
fn as_ref(&self) -> &str {
|
||||||
|
self.borrow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AtomicStr {
|
||||||
|
pub const fn ever(s: &'static str) -> Self {
|
||||||
|
AtomicStr::Static(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn arc(s: &str) -> Self {
|
||||||
|
AtomicStr::Arc(s.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_rc(self) -> ArcStr {
|
||||||
|
match self {
|
||||||
|
AtomicStr::Arc(s) => s,
|
||||||
|
AtomicStr::Static(s) => ArcStr::from(s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_uppercase(&self) -> bool {
|
||||||
|
self.chars()
|
||||||
|
.next()
|
||||||
|
.map(|c| c.is_uppercase())
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,10 +6,10 @@ use std::fmt;
|
||||||
use std::fmt::Write as _;
|
use std::fmt::Write as _;
|
||||||
use std::io::{stderr, BufWriter, Write as _};
|
use std::io::{stderr, BufWriter, Write as _};
|
||||||
|
|
||||||
|
use crate::astr::AtomicStr;
|
||||||
use crate::color::*;
|
use crate::color::*;
|
||||||
use crate::config::Input;
|
use crate::config::Input;
|
||||||
use crate::traits::{Locational, Stream};
|
use crate::traits::{Locational, Stream};
|
||||||
use crate::Str;
|
|
||||||
use crate::{fmt_option, impl_display_from_debug, switch_lang};
|
use crate::{fmt_option, impl_display_from_debug, switch_lang};
|
||||||
|
|
||||||
/// ErrorKindと言っているが、ErrorだけでなくWarning, Exceptionも含まれる
|
/// ErrorKindと言っているが、ErrorだけでなくWarning, Exceptionも含まれる
|
||||||
|
@ -306,17 +306,17 @@ pub struct ErrorCore {
|
||||||
pub errno: usize,
|
pub errno: usize,
|
||||||
pub kind: ErrorKind,
|
pub kind: ErrorKind,
|
||||||
pub loc: Location,
|
pub loc: Location,
|
||||||
pub desc: Str,
|
pub desc: AtomicStr,
|
||||||
pub hint: Option<Str>,
|
pub hint: Option<AtomicStr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ErrorCore {
|
impl ErrorCore {
|
||||||
pub fn new<S: Into<Str>>(
|
pub fn new<S: Into<AtomicStr>>(
|
||||||
errno: usize,
|
errno: usize,
|
||||||
kind: ErrorKind,
|
kind: ErrorKind,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
desc: S,
|
desc: S,
|
||||||
hint: Option<Str>,
|
hint: Option<AtomicStr>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
errno,
|
errno,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! provides utilities for parser, compiler, and vm crate.
|
//! provides utilities for parser, compiler, and vm crate.
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
pub mod astr;
|
||||||
pub mod cache;
|
pub mod cache;
|
||||||
pub mod color;
|
pub mod color;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::process;
|
use std::process;
|
||||||
|
|
||||||
|
use erg_common::astr::AtomicStr;
|
||||||
use erg_common::cache::CacheSet;
|
use erg_common::cache::CacheSet;
|
||||||
use erg_common::config::{ErgConfig, Input};
|
use erg_common::config::{ErgConfig, Input};
|
||||||
use erg_common::error::{Location, MultiErrorDisplay};
|
use erg_common::error::{Location, MultiErrorDisplay};
|
||||||
|
@ -1220,7 +1221,7 @@ impl CodeGenerator {
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
unary.op.loc(),
|
unary.op.loc(),
|
||||||
"",
|
"",
|
||||||
unary.op.content.clone(),
|
AtomicStr::from(unary.op.content),
|
||||||
));
|
));
|
||||||
NOT_IMPLEMENTED
|
NOT_IMPLEMENTED
|
||||||
}
|
}
|
||||||
|
@ -1267,7 +1268,7 @@ impl CodeGenerator {
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
bin.op.loc(),
|
bin.op.loc(),
|
||||||
"",
|
"",
|
||||||
bin.op.content.clone(),
|
AtomicStr::from(bin.op.content),
|
||||||
));
|
));
|
||||||
NOT_IMPLEMENTED
|
NOT_IMPLEMENTED
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
use erg_common::Str;
|
use erg_common::astr::AtomicStr;
|
||||||
|
|
||||||
use erg_type::Type;
|
use erg_type::Type;
|
||||||
|
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
pub(crate) fn get_type_mismatch_hint(&self, expected: &Type, found: &Type) -> Option<Str> {
|
pub(crate) fn get_type_mismatch_hint(
|
||||||
|
&self,
|
||||||
|
expected: &Type,
|
||||||
|
found: &Type,
|
||||||
|
) -> Option<AtomicStr> {
|
||||||
let expected = if let Type::FreeVar(fv) = expected {
|
let expected = if let Type::FreeVar(fv) = expected {
|
||||||
if fv.is_linked() {
|
if fv.is_linked() {
|
||||||
fv.crack().clone()
|
fv.crack().clone()
|
||||||
|
@ -17,7 +21,7 @@ impl Context {
|
||||||
expected.clone()
|
expected.clone()
|
||||||
};
|
};
|
||||||
match (&expected.name()[..], &found.name()[..]) {
|
match (&expected.name()[..], &found.name()[..]) {
|
||||||
("Eq", "Float") => Some(Str::ever("Float has no equivalence relation defined. you should use `l - r <= Float.EPSILON` instead of `l == r`.")),
|
("Eq", "Float") => Some(AtomicStr::ever("Float has no equivalence relation defined. you should use `l - r <= Float.EPSILON` instead of `l == r`.")),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@ impl Context {
|
||||||
Err(TyCheckError::no_var_error(
|
Err(TyCheckError::no_var_error(
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
obj.loc(),
|
obj.loc(),
|
||||||
namespace.clone(),
|
namespace.into(),
|
||||||
ident.inspect(),
|
ident.inspect(),
|
||||||
self.get_similar_name(ident.inspect()),
|
self.get_similar_name(ident.inspect()),
|
||||||
))
|
))
|
||||||
|
@ -213,7 +213,7 @@ impl Context {
|
||||||
Err(TyCheckError::no_var_error(
|
Err(TyCheckError::no_var_error(
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
ident.loc(),
|
ident.loc(),
|
||||||
namespace.clone(),
|
namespace.into(),
|
||||||
ident.inspect(),
|
ident.inspect(),
|
||||||
self.get_similar_name(ident.inspect()),
|
self.get_similar_name(ident.inspect()),
|
||||||
))
|
))
|
||||||
|
@ -269,7 +269,7 @@ impl Context {
|
||||||
Err(TyCheckError::no_attr_error(
|
Err(TyCheckError::no_attr_error(
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
name.loc(),
|
name.loc(),
|
||||||
namespace.clone(),
|
namespace.into(),
|
||||||
&self_t,
|
&self_t,
|
||||||
name.inspect(),
|
name.inspect(),
|
||||||
self.get_similar_attr(&self_t, name.inspect()),
|
self.get_similar_attr(&self_t, name.inspect()),
|
||||||
|
@ -308,7 +308,7 @@ impl Context {
|
||||||
Err(TyCheckError::no_attr_error(
|
Err(TyCheckError::no_attr_error(
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
ident.loc(),
|
ident.loc(),
|
||||||
namespace.clone(),
|
namespace.into(),
|
||||||
&t,
|
&t,
|
||||||
ident.inspect(),
|
ident.inspect(),
|
||||||
self.get_similar_attr(&t, ident.inspect()),
|
self.get_similar_attr(&t, ident.inspect()),
|
||||||
|
@ -393,7 +393,7 @@ impl Context {
|
||||||
return Err(TyCheckError::singular_no_attr_error(
|
return Err(TyCheckError::singular_no_attr_error(
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
method_name.loc(),
|
method_name.loc(),
|
||||||
namespace.clone(),
|
namespace.into(),
|
||||||
obj.__name__().unwrap_or("?"),
|
obj.__name__().unwrap_or("?"),
|
||||||
obj.ref_t(),
|
obj.ref_t(),
|
||||||
method_name.inspect(),
|
method_name.inspect(),
|
||||||
|
@ -404,7 +404,7 @@ impl Context {
|
||||||
Err(TyCheckError::no_attr_error(
|
Err(TyCheckError::no_attr_error(
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
method_name.loc(),
|
method_name.loc(),
|
||||||
namespace.clone(),
|
namespace.into(),
|
||||||
obj.ref_t(),
|
obj.ref_t(),
|
||||||
method_name.inspect(),
|
method_name.inspect(),
|
||||||
self.get_similar_attr(obj.ref_t(), method_name.inspect()),
|
self.get_similar_attr(obj.ref_t(), method_name.inspect()),
|
||||||
|
@ -970,7 +970,7 @@ impl Context {
|
||||||
Err(TyCheckError::no_var_error(
|
Err(TyCheckError::no_var_error(
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
name.loc(),
|
name.loc(),
|
||||||
namespace.clone(),
|
namespace.into(),
|
||||||
name.inspect(),
|
name.inspect(),
|
||||||
self.get_similar_name(name.inspect()),
|
self.get_similar_name(name.inspect()),
|
||||||
))
|
))
|
||||||
|
@ -999,7 +999,7 @@ impl Context {
|
||||||
Err(TyCheckError::no_attr_error(
|
Err(TyCheckError::no_attr_error(
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
name.loc(),
|
name.loc(),
|
||||||
namespace.clone(),
|
namespace.into(),
|
||||||
self_t,
|
self_t,
|
||||||
name.inspect(),
|
name.inspect(),
|
||||||
self.get_similar_attr(self_t, name.inspect()),
|
self.get_similar_attr(self_t, name.inspect()),
|
||||||
|
|
|
@ -17,6 +17,7 @@ use std::fmt;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::option::Option; // conflicting to Type::Option
|
use std::option::Option; // conflicting to Type::Option
|
||||||
|
|
||||||
|
use erg_common::astr::AtomicStr;
|
||||||
use erg_common::dict::Dict;
|
use erg_common::dict::Dict;
|
||||||
use erg_common::error::Location;
|
use erg_common::error::Location;
|
||||||
use erg_common::impl_display_from_debug;
|
use erg_common::impl_display_from_debug;
|
||||||
|
@ -476,8 +477,8 @@ impl Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn caused_by(&self) -> Str {
|
pub fn caused_by(&self) -> AtomicStr {
|
||||||
self.name.clone()
|
AtomicStr::arc(&self.name[..])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn grow(
|
pub(crate) fn grow(
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::ops::Add;
|
use std::ops::Add;
|
||||||
|
|
||||||
|
use erg_common::astr::AtomicStr;
|
||||||
use erg_common::color::{GREEN, RED, RESET, YELLOW};
|
use erg_common::color::{GREEN, RED, RESET, YELLOW};
|
||||||
use erg_common::config::Input;
|
use erg_common::config::Input;
|
||||||
use erg_common::error::{ErrorCore, ErrorDisplay, ErrorKind::*, Location, MultiErrorDisplay};
|
use erg_common::error::{ErrorCore, ErrorDisplay, ErrorKind::*, Location, MultiErrorDisplay};
|
||||||
|
@ -96,7 +97,7 @@ pub fn readable_name(name: &str) -> &str {
|
||||||
pub struct CompileError {
|
pub struct CompileError {
|
||||||
pub core: ErrorCore,
|
pub core: ErrorCore,
|
||||||
pub input: Input,
|
pub input: Input,
|
||||||
pub caused_by: Str,
|
pub caused_by: AtomicStr,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ParserRunnerError> for CompileError {
|
impl From<ParserRunnerError> for CompileError {
|
||||||
|
@ -125,7 +126,7 @@ impl ErrorDisplay for CompileError {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompileError {
|
impl CompileError {
|
||||||
pub const fn new(core: ErrorCore, input: Input, caused_by: Str) -> Self {
|
pub const fn new(core: ErrorCore, input: Input, caused_by: AtomicStr) -> Self {
|
||||||
Self {
|
Self {
|
||||||
core,
|
core,
|
||||||
input,
|
input,
|
||||||
|
@ -191,7 +192,7 @@ impl CompileError {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn feature_error(input: Input, loc: Location, name: &str, caused_by: Str) -> Self {
|
pub fn feature_error(input: Input, loc: Location, name: &str, caused_by: AtomicStr) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
0,
|
0,
|
||||||
|
@ -233,7 +234,7 @@ impl CompileError {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TyCheckError {
|
pub struct TyCheckError {
|
||||||
pub core: ErrorCore,
|
pub core: ErrorCore,
|
||||||
pub caused_by: Str,
|
pub caused_by: AtomicStr,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ErrorDisplay for TyCheckError {
|
impl ErrorDisplay for TyCheckError {
|
||||||
|
@ -252,7 +253,7 @@ impl ErrorDisplay for TyCheckError {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TyCheckError {
|
impl TyCheckError {
|
||||||
pub const fn new(core: ErrorCore, caused_by: Str) -> Self {
|
pub const fn new(core: ErrorCore, caused_by: AtomicStr) -> Self {
|
||||||
Self { core, caused_by }
|
Self { core, caused_by }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,7 +283,7 @@ impl TyCheckError {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn feature_error(errno: usize, loc: Location, name: &str, caused_by: Str) -> Self {
|
pub fn feature_error(errno: usize, loc: Location, name: &str, caused_by: AtomicStr) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
errno,
|
errno,
|
||||||
|
@ -300,12 +301,12 @@ impl TyCheckError {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn syntax_error<S: Into<Str>>(
|
pub fn syntax_error<S: Into<AtomicStr>>(
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: Str,
|
caused_by: AtomicStr,
|
||||||
desc: S,
|
desc: S,
|
||||||
hint: Option<Str>,
|
hint: Option<AtomicStr>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(errno, SyntaxError, loc, desc, hint),
|
ErrorCore::new(errno, SyntaxError, loc, desc, hint),
|
||||||
|
@ -313,7 +314,12 @@ impl TyCheckError {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn duplicate_decl_error(errno: usize, loc: Location, caused_by: Str, name: &str) -> Self {
|
pub fn duplicate_decl_error(
|
||||||
|
errno: usize,
|
||||||
|
loc: Location,
|
||||||
|
caused_by: AtomicStr,
|
||||||
|
name: &str,
|
||||||
|
) -> Self {
|
||||||
let name = readable_name(name);
|
let name = readable_name(name);
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
|
@ -326,7 +332,7 @@ impl TyCheckError {
|
||||||
"traditional_chinese" => format!("{name}已聲明"),
|
"traditional_chinese" => format!("{name}已聲明"),
|
||||||
"english" => format!("{name} is already declared"),
|
"english" => format!("{name} is already declared"),
|
||||||
),
|
),
|
||||||
Option::<Str>::None,
|
Option::<AtomicStr>::None,
|
||||||
),
|
),
|
||||||
caused_by,
|
caused_by,
|
||||||
)
|
)
|
||||||
|
@ -335,7 +341,7 @@ impl TyCheckError {
|
||||||
pub fn duplicate_definition_error(
|
pub fn duplicate_definition_error(
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: Str,
|
caused_by: AtomicStr,
|
||||||
name: &str,
|
name: &str,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let name = readable_name(name);
|
let name = readable_name(name);
|
||||||
|
@ -350,7 +356,7 @@ impl TyCheckError {
|
||||||
"traditional_chinese" => format!("{name}已定義"),
|
"traditional_chinese" => format!("{name}已定義"),
|
||||||
"english" => format!("{name} is already defined"),
|
"english" => format!("{name} is already defined"),
|
||||||
),
|
),
|
||||||
Option::<Str>::None,
|
Option::<AtomicStr>::None,
|
||||||
),
|
),
|
||||||
caused_by,
|
caused_by,
|
||||||
)
|
)
|
||||||
|
@ -359,7 +365,7 @@ impl TyCheckError {
|
||||||
pub fn violate_decl_error(
|
pub fn violate_decl_error(
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: Str,
|
caused_by: AtomicStr,
|
||||||
name: &str,
|
name: &str,
|
||||||
spec_t: &Type,
|
spec_t: &Type,
|
||||||
found_t: &Type,
|
found_t: &Type,
|
||||||
|
@ -376,13 +382,18 @@ impl TyCheckError {
|
||||||
"traditional_chinese" => format!("{name}被聲明為{GREEN}{spec_t}{RESET},但分配了一個{RED}{found_t}{RESET}對象"),
|
"traditional_chinese" => format!("{name}被聲明為{GREEN}{spec_t}{RESET},但分配了一個{RED}{found_t}{RESET}對象"),
|
||||||
"english" => format!("{name} was declared as {GREEN}{spec_t}{RESET}, but an {RED}{found_t}{RESET} object is assigned"),
|
"english" => format!("{name} was declared as {GREEN}{spec_t}{RESET}, but an {RED}{found_t}{RESET} object is assigned"),
|
||||||
),
|
),
|
||||||
Option::<Str>::None,
|
Option::<AtomicStr>::None,
|
||||||
),
|
),
|
||||||
caused_by,
|
caused_by,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn no_type_spec_error(errno: usize, loc: Location, caused_by: Str, name: &str) -> Self {
|
pub fn no_type_spec_error(
|
||||||
|
errno: usize,
|
||||||
|
loc: Location,
|
||||||
|
caused_by: AtomicStr,
|
||||||
|
name: &str,
|
||||||
|
) -> Self {
|
||||||
let name = readable_name(name);
|
let name = readable_name(name);
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
|
@ -404,7 +415,7 @@ impl TyCheckError {
|
||||||
pub fn no_var_error(
|
pub fn no_var_error(
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: Str,
|
caused_by: AtomicStr,
|
||||||
name: &str,
|
name: &str,
|
||||||
similar_name: Option<&Str>,
|
similar_name: Option<&Str>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -439,7 +450,7 @@ impl TyCheckError {
|
||||||
pub fn no_attr_error(
|
pub fn no_attr_error(
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: Str,
|
caused_by: AtomicStr,
|
||||||
obj_t: &Type,
|
obj_t: &Type,
|
||||||
name: &str,
|
name: &str,
|
||||||
similar_name: Option<&Str>,
|
similar_name: Option<&Str>,
|
||||||
|
@ -474,7 +485,7 @@ impl TyCheckError {
|
||||||
pub fn singular_no_attr_error(
|
pub fn singular_no_attr_error(
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: Str,
|
caused_by: AtomicStr,
|
||||||
obj_name: &str,
|
obj_name: &str,
|
||||||
obj_t: &Type,
|
obj_t: &Type,
|
||||||
name: &str,
|
name: &str,
|
||||||
|
@ -511,7 +522,7 @@ impl TyCheckError {
|
||||||
errno: usize,
|
errno: usize,
|
||||||
callee: &C,
|
callee: &C,
|
||||||
param_ts: impl Iterator<Item = &'a Type>,
|
param_ts: impl Iterator<Item = &'a Type>,
|
||||||
caused_by: Str,
|
caused_by: AtomicStr,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let param_ts = fmt_iter(param_ts);
|
let param_ts = fmt_iter(param_ts);
|
||||||
Self::new(
|
Self::new(
|
||||||
|
@ -539,12 +550,12 @@ impl TyCheckError {
|
||||||
pub fn type_mismatch_error(
|
pub fn type_mismatch_error(
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: Str,
|
caused_by: AtomicStr,
|
||||||
name: &str,
|
name: &str,
|
||||||
expect: &Type,
|
expect: &Type,
|
||||||
found: &Type,
|
found: &Type,
|
||||||
candidates: Option<Set<Type>>,
|
candidates: Option<Set<Type>>,
|
||||||
hint: Option<Str>,
|
hint: Option<AtomicStr>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
|
@ -566,7 +577,7 @@ impl TyCheckError {
|
||||||
pub fn return_type_error(
|
pub fn return_type_error(
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: Str,
|
caused_by: AtomicStr,
|
||||||
name: &str,
|
name: &str,
|
||||||
expect: &Type,
|
expect: &Type,
|
||||||
found: &Type,
|
found: &Type,
|
||||||
|
@ -591,7 +602,7 @@ impl TyCheckError {
|
||||||
pub fn uninitialized_error(
|
pub fn uninitialized_error(
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: Str,
|
caused_by: AtomicStr,
|
||||||
name: &str,
|
name: &str,
|
||||||
t: &Type,
|
t: &Type,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -615,7 +626,7 @@ impl TyCheckError {
|
||||||
pub fn argument_error(
|
pub fn argument_error(
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: Str,
|
caused_by: AtomicStr,
|
||||||
expect: usize,
|
expect: usize,
|
||||||
found: usize,
|
found: usize,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -636,7 +647,7 @@ impl TyCheckError {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn match_error(errno: usize, loc: Location, caused_by: Str, expr_t: &Type) -> Self {
|
pub fn match_error(errno: usize, loc: Location, caused_by: AtomicStr, expr_t: &Type) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
errno,
|
errno,
|
||||||
|
@ -654,7 +665,7 @@ impl TyCheckError {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn infer_error(errno: usize, loc: Location, caused_by: Str, expr: &str) -> Self {
|
pub fn infer_error(errno: usize, loc: Location, caused_by: AtomicStr, expr: &str) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
errno,
|
errno,
|
||||||
|
@ -680,7 +691,7 @@ impl TyCheckError {
|
||||||
Self::new(ErrorCore::unreachable(fn_name, line), "".into())
|
Self::new(ErrorCore::unreachable(fn_name, line), "".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reassign_error(errno: usize, loc: Location, caused_by: Str, name: &str) -> Self {
|
pub fn reassign_error(errno: usize, loc: Location, caused_by: AtomicStr, name: &str) -> Self {
|
||||||
let name = readable_name(name);
|
let name = readable_name(name);
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
|
@ -703,7 +714,7 @@ impl TyCheckError {
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
callee_name: &str,
|
callee_name: &str,
|
||||||
caused_by: Str,
|
caused_by: AtomicStr,
|
||||||
params_len: usize,
|
params_len: usize,
|
||||||
pos_args_len: usize,
|
pos_args_len: usize,
|
||||||
kw_args_len: usize,
|
kw_args_len: usize,
|
||||||
|
@ -750,7 +761,7 @@ passed keyword args: {RED}{kw_args_len}{RESET}"
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
callee_name: &str,
|
callee_name: &str,
|
||||||
caused_by: Str,
|
caused_by: AtomicStr,
|
||||||
missing_len: usize,
|
missing_len: usize,
|
||||||
missing_params: Vec<Str>,
|
missing_params: Vec<Str>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -776,7 +787,7 @@ passed keyword args: {RED}{kw_args_len}{RESET}"
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
callee_name: &str,
|
callee_name: &str,
|
||||||
caused_by: Str,
|
caused_by: AtomicStr,
|
||||||
arg_name: &str,
|
arg_name: &str,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let name = readable_name(callee_name);
|
let name = readable_name(callee_name);
|
||||||
|
@ -801,7 +812,7 @@ passed keyword args: {RED}{kw_args_len}{RESET}"
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
callee_name: &str,
|
callee_name: &str,
|
||||||
caused_by: Str,
|
caused_by: AtomicStr,
|
||||||
param_name: &str,
|
param_name: &str,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let name = readable_name(callee_name);
|
let name = readable_name(callee_name);
|
||||||
|
@ -822,7 +833,7 @@ passed keyword args: {RED}{kw_args_len}{RESET}"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unused_warning(errno: usize, loc: Location, name: &str, caused_by: Str) -> Self {
|
pub fn unused_warning(errno: usize, loc: Location, name: &str, caused_by: AtomicStr) -> Self {
|
||||||
let name = readable_name(name);
|
let name = readable_name(name);
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
|
@ -847,7 +858,7 @@ passed keyword args: {RED}{kw_args_len}{RESET}"
|
||||||
rhs_t: &Type,
|
rhs_t: &Type,
|
||||||
lhs_loc: Option<Location>,
|
lhs_loc: Option<Location>,
|
||||||
rhs_loc: Option<Location>,
|
rhs_loc: Option<Location>,
|
||||||
caused_by: Str,
|
caused_by: AtomicStr,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let loc = match (lhs_loc, rhs_loc) {
|
let loc = match (lhs_loc, rhs_loc) {
|
||||||
(Some(l), Some(r)) => Location::pair(l, r),
|
(Some(l), Some(r)) => Location::pair(l, r),
|
||||||
|
@ -878,7 +889,7 @@ passed keyword args: {RED}{kw_args_len}{RESET}"
|
||||||
rhs_t: &Type,
|
rhs_t: &Type,
|
||||||
lhs_loc: Option<Location>,
|
lhs_loc: Option<Location>,
|
||||||
rhs_loc: Option<Location>,
|
rhs_loc: Option<Location>,
|
||||||
caused_by: Str,
|
caused_by: AtomicStr,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let loc = match (lhs_loc, rhs_loc) {
|
let loc = match (lhs_loc, rhs_loc) {
|
||||||
(Some(l), Some(r)) => Location::pair(l, r),
|
(Some(l), Some(r)) => Location::pair(l, r),
|
||||||
|
@ -909,7 +920,7 @@ passed keyword args: {RED}{kw_args_len}{RESET}"
|
||||||
sup_t: &Type,
|
sup_t: &Type,
|
||||||
sub_loc: Option<Location>,
|
sub_loc: Option<Location>,
|
||||||
sup_loc: Option<Location>,
|
sup_loc: Option<Location>,
|
||||||
caused_by: Str,
|
caused_by: AtomicStr,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let loc = match (sub_loc, sup_loc) {
|
let loc = match (sub_loc, sup_loc) {
|
||||||
(Some(l), Some(r)) => Location::pair(l, r),
|
(Some(l), Some(r)) => Location::pair(l, r),
|
||||||
|
@ -938,7 +949,7 @@ passed keyword args: {RED}{kw_args_len}{RESET}"
|
||||||
errno: usize,
|
errno: usize,
|
||||||
lhs: &Predicate,
|
lhs: &Predicate,
|
||||||
rhs: &Predicate,
|
rhs: &Predicate,
|
||||||
caused_by: Str,
|
caused_by: AtomicStr,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
|
@ -957,7 +968,7 @@ passed keyword args: {RED}{kw_args_len}{RESET}"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_effect<S: Into<Str>>(errno: usize, expr: &Expr, caused_by: S) -> Self {
|
pub fn has_effect<S: Into<AtomicStr>>(errno: usize, expr: &Expr, caused_by: S) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
errno,
|
errno,
|
||||||
|
@ -975,7 +986,7 @@ passed keyword args: {RED}{kw_args_len}{RESET}"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_error<S: Into<Str>>(
|
pub fn move_error<S: Into<AtomicStr>>(
|
||||||
errno: usize,
|
errno: usize,
|
||||||
name: &str,
|
name: &str,
|
||||||
name_loc: Location,
|
name_loc: Location,
|
||||||
|
@ -1014,7 +1025,7 @@ passed keyword args: {RED}{kw_args_len}{RESET}"
|
||||||
pub fn visibility_error(
|
pub fn visibility_error(
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: Str,
|
caused_by: AtomicStr,
|
||||||
name: &str,
|
name: &str,
|
||||||
vis: Visibility,
|
vis: Visibility,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -1051,7 +1062,7 @@ passed keyword args: {RED}{kw_args_len}{RESET}"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn not_const_expr(errno: usize, loc: Location, caused_by: Str) -> Self {
|
pub fn not_const_expr(errno: usize, loc: Location, caused_by: AtomicStr) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
errno,
|
errno,
|
||||||
|
@ -1069,7 +1080,7 @@ passed keyword args: {RED}{kw_args_len}{RESET}"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn override_error<S: Into<Str>>(
|
pub fn override_error<S: Into<AtomicStr>>(
|
||||||
errno: usize,
|
errno: usize,
|
||||||
name: &str,
|
name: &str,
|
||||||
name_loc: Location,
|
name_loc: Location,
|
||||||
|
@ -1106,7 +1117,12 @@ passed keyword args: {RED}{kw_args_len}{RESET}"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inheritance_error(errno: usize, class: String, loc: Location, caused_by: Str) -> Self {
|
pub fn inheritance_error(
|
||||||
|
errno: usize,
|
||||||
|
class: String,
|
||||||
|
loc: Location,
|
||||||
|
caused_by: AtomicStr,
|
||||||
|
) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
errno,
|
errno,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! implements `ASTLowerer`.
|
//! implements `ASTLowerer`.
|
||||||
//!
|
//!
|
||||||
//! ASTLowerer(ASTからHIRへの変換器)を実装
|
//! ASTLowerer(ASTからHIRへの変換器)を実装
|
||||||
|
use erg_common::astr::AtomicStr;
|
||||||
use erg_common::config::{ErgConfig, Input};
|
use erg_common::config::{ErgConfig, Input};
|
||||||
use erg_common::error::{Location, MultiErrorDisplay};
|
use erg_common::error::{Location, MultiErrorDisplay};
|
||||||
use erg_common::traits::{Locational, Runnable, Stream};
|
use erg_common::traits::{Locational, Runnable, Stream};
|
||||||
|
@ -17,7 +18,7 @@ use erg_parser::Parser;
|
||||||
use erg_type::constructors::{array, array_mut, free_var, func, mono, poly, proc, quant};
|
use erg_type::constructors::{array, array_mut, free_var, func, mono, poly, proc, quant};
|
||||||
use erg_type::free::Constraint;
|
use erg_type::free::Constraint;
|
||||||
use erg_type::typaram::TyParam;
|
use erg_type::typaram::TyParam;
|
||||||
use erg_type::value::{TypeObj, ValueObj};
|
use erg_type::value::{GenTypeObj, TypeObj, ValueObj};
|
||||||
use erg_type::{HasType, ParamTy, Type};
|
use erg_type::{HasType, ParamTy, Type};
|
||||||
|
|
||||||
use crate::context::{ClassDefType, Context, ContextKind, RegistrationMode};
|
use crate::context::{ClassDefType, Context, ContextKind, RegistrationMode};
|
||||||
|
@ -30,34 +31,6 @@ use crate::link::Linker;
|
||||||
use crate::varinfo::VarKind;
|
use crate::varinfo::VarKind;
|
||||||
use Visibility::*;
|
use Visibility::*;
|
||||||
|
|
||||||
/// HACK: Cannot be methodized this because a reference has been taken immediately before.
|
|
||||||
macro_rules! check_inheritable {
|
|
||||||
($self: ident, $type_obj: expr, $sup_class: expr, $sub_sig: expr) => {
|
|
||||||
match $type_obj.require_or_sup.as_ref() {
|
|
||||||
TypeObj::Generated(gen) => {
|
|
||||||
if let Some(impls) = gen.impls.as_ref() {
|
|
||||||
if !impls.contains_intersec(&mono("InheritableType")) {
|
|
||||||
$self.errs.push(LowerError::inheritance_error(
|
|
||||||
line!() as usize,
|
|
||||||
$sup_class.to_string(),
|
|
||||||
$sup_class.loc(),
|
|
||||||
$sub_sig.ident().inspect().clone(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$self.errs.push(LowerError::inheritance_error(
|
|
||||||
line!() as usize,
|
|
||||||
$sup_class.to_string(),
|
|
||||||
$sup_class.loc(),
|
|
||||||
$sub_sig.ident().inspect().clone(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ASTLowererRunner {
|
pub struct ASTLowererRunner {
|
||||||
cfg: ErgConfig,
|
cfg: ErgConfig,
|
||||||
lowerer: ASTLowerer,
|
lowerer: ASTLowerer,
|
||||||
|
@ -186,7 +159,7 @@ impl ASTLowerer {
|
||||||
Err(LowerError::syntax_error(
|
Err(LowerError::syntax_error(
|
||||||
0,
|
0,
|
||||||
expr.loc(),
|
expr.loc(),
|
||||||
self.ctx.name.clone(),
|
AtomicStr::arc(&self.ctx.name[..]),
|
||||||
switch_lang!(
|
switch_lang!(
|
||||||
"japanese" => format!("式の評価結果(: {})が使われていません", expr.ref_t()),
|
"japanese" => format!("式の評価結果(: {})が使われていません", expr.ref_t()),
|
||||||
"simplified_chinese" => format!("表达式评估结果(: {})未使用", expr.ref_t()),
|
"simplified_chinese" => format!("表达式评估结果(: {})未使用", expr.ref_t()),
|
||||||
|
@ -237,7 +210,7 @@ impl ASTLowerer {
|
||||||
return Err(LowerError::syntax_error(
|
return Err(LowerError::syntax_error(
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
elem.loc(),
|
elem.loc(),
|
||||||
self.ctx.name.clone(),
|
AtomicStr::arc(&self.ctx.name[..]),
|
||||||
switch_lang!(
|
switch_lang!(
|
||||||
"japanese" => "配列の要素は全て同じ型である必要があります",
|
"japanese" => "配列の要素は全て同じ型である必要があります",
|
||||||
"simplified_chinese" => "数组元素必须全部是相同类型",
|
"simplified_chinese" => "数组元素必须全部是相同类型",
|
||||||
|
@ -750,7 +723,7 @@ impl ASTLowerer {
|
||||||
self.errs.push(LowerError::duplicate_definition_error(
|
self.errs.push(LowerError::duplicate_definition_error(
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
newly_defined_name.loc(),
|
newly_defined_name.loc(),
|
||||||
methods.name.clone(),
|
methods.name.clone().into(),
|
||||||
newly_defined_name.inspect(),
|
newly_defined_name.inspect(),
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
|
@ -782,7 +755,7 @@ impl ASTLowerer {
|
||||||
.args
|
.args
|
||||||
.get_left_or_key("Super")
|
.get_left_or_key("Super")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
check_inheritable!(self, type_obj, sup_type, &hir_def.sig);
|
Self::check_inheritable(&mut self.errs, type_obj, sup_type, &hir_def.sig);
|
||||||
// vi.t.non_default_params().unwrap()[0].typ().clone()
|
// vi.t.non_default_params().unwrap()[0].typ().clone()
|
||||||
let (__new__, need_to_gen_new) = if let (Some(dunder_new_vi), Some(new_vi)) = (
|
let (__new__, need_to_gen_new) = if let (Some(dunder_new_vi), Some(new_vi)) = (
|
||||||
ctx.get_current_scope_var("__new__"),
|
ctx.get_current_scope_var("__new__"),
|
||||||
|
@ -804,6 +777,34 @@ impl ASTLowerer {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// HACK: Cannot be methodized this because `&self` has been taken immediately before.
|
||||||
|
fn check_inheritable(
|
||||||
|
errs: &mut LowerErrors,
|
||||||
|
type_obj: &GenTypeObj,
|
||||||
|
sup_class: &hir::Expr,
|
||||||
|
sub_sig: &hir::Signature,
|
||||||
|
) {
|
||||||
|
if let TypeObj::Generated(gen) = type_obj.require_or_sup.as_ref() {
|
||||||
|
if let Some(impls) = gen.impls.as_ref() {
|
||||||
|
if !impls.contains_intersec(&mono("InheritableType")) {
|
||||||
|
errs.push(LowerError::inheritance_error(
|
||||||
|
line!() as usize,
|
||||||
|
sup_class.to_string(),
|
||||||
|
sup_class.loc(),
|
||||||
|
sub_sig.ident().inspect().into(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errs.push(LowerError::inheritance_error(
|
||||||
|
line!() as usize,
|
||||||
|
sup_class.to_string(),
|
||||||
|
sup_class.loc(),
|
||||||
|
sub_sig.ident().inspect().into(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn check_override(&mut self, class: &Type, ctx: &Context) {
|
fn check_override(&mut self, class: &Type, ctx: &Context) {
|
||||||
if let Some(sups) = self.ctx.get_nominal_super_type_ctxs(class) {
|
if let Some(sups) = self.ctx.get_nominal_super_type_ctxs(class) {
|
||||||
for (sup_t, sup) in sups.skip(1) {
|
for (sup_t, sup) in sups.skip(1) {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
//! defines `ParseError` and others.
|
//! defines `ParseError` and others.
|
||||||
//!
|
//!
|
||||||
//! パーサーが出すエラーを定義
|
//! パーサーが出すエラーを定義
|
||||||
|
use erg_common::astr::AtomicStr;
|
||||||
use erg_common::config::Input;
|
use erg_common::config::Input;
|
||||||
use erg_common::error::{ErrorCore, ErrorDisplay, ErrorKind::*, Location, MultiErrorDisplay};
|
use erg_common::error::{ErrorCore, ErrorDisplay, ErrorKind::*, Location, MultiErrorDisplay};
|
||||||
use erg_common::traits::Stream;
|
use erg_common::traits::Stream;
|
||||||
use erg_common::Str;
|
|
||||||
use erg_common::{impl_stream_for_wrapper, switch_lang};
|
use erg_common::{impl_stream_for_wrapper, switch_lang};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -65,20 +65,20 @@ impl LexError {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn syntax_error<S: Into<Str>>(
|
pub fn syntax_error<S: Into<AtomicStr>>(
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
desc: S,
|
desc: S,
|
||||||
hint: Option<Str>,
|
hint: Option<AtomicStr>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new(ErrorCore::new(errno, SyntaxError, loc, desc, hint))
|
Self::new(ErrorCore::new(errno, SyntaxError, loc, desc, hint))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn syntax_warning<S: Into<Str>>(
|
pub fn syntax_warning<S: Into<AtomicStr>>(
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
desc: S,
|
desc: S,
|
||||||
hint: Option<Str>,
|
hint: Option<AtomicStr>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new(ErrorCore::new(errno, SyntaxWarning, loc, desc, hint))
|
Self::new(ErrorCore::new(errno, SyntaxWarning, loc, desc, hint))
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
use std::process;
|
use std::process;
|
||||||
use std::string::FromUtf8Error;
|
use std::string::FromUtf8Error;
|
||||||
|
|
||||||
|
use erg_common::astr::AtomicStr;
|
||||||
use erg_common::cache::CacheSet;
|
use erg_common::cache::CacheSet;
|
||||||
use erg_common::config::{ErgConfig, Input};
|
use erg_common::config::{ErgConfig, Input};
|
||||||
use erg_common::error::{ErrorCore, ErrorKind, Location};
|
use erg_common::error::{ErrorCore, ErrorKind, Location};
|
||||||
|
@ -18,8 +19,8 @@ use crate::{HasType, Type};
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DeserializeError {
|
pub struct DeserializeError {
|
||||||
pub errno: usize,
|
pub errno: usize,
|
||||||
pub caused_by: Str,
|
pub caused_by: AtomicStr,
|
||||||
pub desc: Str,
|
pub desc: AtomicStr,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<std::io::Error> for DeserializeError {
|
impl From<std::io::Error> for DeserializeError {
|
||||||
|
@ -41,13 +42,17 @@ impl From<DeserializeError> for ErrorCore {
|
||||||
ErrorKind::ImportError,
|
ErrorKind::ImportError,
|
||||||
Location::Unknown,
|
Location::Unknown,
|
||||||
err.desc,
|
err.desc,
|
||||||
Option::<Str>::None,
|
Option::<AtomicStr>::None,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeserializeError {
|
impl DeserializeError {
|
||||||
pub fn new<S: Into<Str>, T: Into<Str>>(errno: usize, caused_by: S, desc: T) -> Self {
|
pub fn new<S: Into<AtomicStr>, T: Into<AtomicStr>>(
|
||||||
|
errno: usize,
|
||||||
|
caused_by: S,
|
||||||
|
desc: T,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
errno,
|
errno,
|
||||||
caused_by: caused_by.into(),
|
caused_by: caused_by.into(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue