mirror of
https://github.com/edg-l/edlang.git
synced 2024-11-22 16:08:24 +00:00
add asref check
This commit is contained in:
parent
9a7e510e1f
commit
7657a05ebd
|
@ -201,16 +201,28 @@ pub fn lowering_error_to_report(
|
||||||
)
|
)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
LoweringError::NotMutable { span, file_id } => {
|
LoweringError::NotMutable {
|
||||||
|
span,
|
||||||
|
declare_span,
|
||||||
|
file_id,
|
||||||
|
} => {
|
||||||
let path = session.file_paths[file_id].display().to_string();
|
let path = session.file_paths[file_id].display().to_string();
|
||||||
Report::build(ReportKind::Error, path.clone(), span.lo)
|
let mut report = Report::build(ReportKind::Error, path.clone(), span.lo)
|
||||||
.with_code("NotMutable")
|
.with_code("NotMutable")
|
||||||
.with_label(
|
.with_label(
|
||||||
Label::new((path, span.into()))
|
Label::new((path.clone(), span.into()))
|
||||||
.with_message("can't mutate this value because it's not declared mutable")
|
.with_message("can't mutate this variable because it's not mutable")
|
||||||
.with_color(colors.next()),
|
.with_color(colors.next()),
|
||||||
)
|
);
|
||||||
.finish()
|
|
||||||
|
if let Some(declare_span) = declare_span {
|
||||||
|
report = report.with_label(
|
||||||
|
Label::new((path, declare_span.into()))
|
||||||
|
.with_message("variable declared here")
|
||||||
|
.with_color(colors.next()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
report.finish()
|
||||||
}
|
}
|
||||||
LoweringError::NotMutableSelf {
|
LoweringError::NotMutableSelf {
|
||||||
span,
|
span,
|
||||||
|
@ -232,5 +244,28 @@ pub fn lowering_error_to_report(
|
||||||
)
|
)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
|
LoweringError::CantTakeMutableBorrow {
|
||||||
|
span,
|
||||||
|
declare_span,
|
||||||
|
file_id,
|
||||||
|
} => {
|
||||||
|
let path = session.file_paths[file_id].display().to_string();
|
||||||
|
let mut report = Report::build(ReportKind::Error, path.clone(), span.lo)
|
||||||
|
.with_code("CantTakeMutableBorrow")
|
||||||
|
.with_label(
|
||||||
|
Label::new((path.clone(), span.into()))
|
||||||
|
.with_message("can't take a mutate borrow to this variable because it's not declared mutable")
|
||||||
|
.with_color(colors.next()),
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(declare_span) = declare_span {
|
||||||
|
report = report.with_label(
|
||||||
|
Label::new((path, declare_span.into()))
|
||||||
|
.with_message("variable declared here")
|
||||||
|
.with_color(colors.next()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
report.finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
fn main() -> i32 {
|
fn main() -> i32 {
|
||||||
let foo: i32 = 7;
|
let mut foo: i32 = 7;
|
||||||
|
|
||||||
if true {
|
if true {
|
||||||
if false {
|
if false {
|
||||||
|
|
|
@ -178,6 +178,18 @@ impl Local {
|
||||||
mutable: false,
|
mutable: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_mutable(&self) -> bool {
|
||||||
|
if self.mutable {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.ty.kind {
|
||||||
|
TypeKind::Ptr(is_mut, _) => is_mut,
|
||||||
|
TypeKind::Ref(is_mut, _) => is_mut,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
@ -424,6 +436,19 @@ pub enum RValue {
|
||||||
Cast(Operand, TypeInfo, Span),
|
Cast(Operand, TypeInfo, Span),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl RValue {
|
||||||
|
pub fn get_local(&self) -> Option<usize> {
|
||||||
|
match self {
|
||||||
|
RValue::Use(op, _) => op.get_local(),
|
||||||
|
RValue::Ref(_, op, _) => op.get_local(),
|
||||||
|
RValue::BinOp(_, _, _, _) => None,
|
||||||
|
RValue::LogicOp(_, _, _, _) => None,
|
||||||
|
RValue::UnOp(_, _, _) => None,
|
||||||
|
RValue::Cast(op, _, _) => op.get_local(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Operand {
|
pub enum Operand {
|
||||||
Copy(Place),
|
Copy(Place),
|
||||||
|
@ -431,6 +456,16 @@ pub enum Operand {
|
||||||
Constant(ConstData),
|
Constant(ConstData),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Operand {
|
||||||
|
pub fn get_local(&self) -> Option<usize> {
|
||||||
|
match self {
|
||||||
|
Operand::Copy(place) => Some(place.local),
|
||||||
|
Operand::Move(place) => Some(place.local),
|
||||||
|
Operand::Constant(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Place {
|
pub struct Place {
|
||||||
pub local: usize,
|
pub local: usize,
|
||||||
|
|
|
@ -71,7 +71,17 @@ pub enum LoweringError {
|
||||||
file_id: usize,
|
file_id: usize,
|
||||||
},
|
},
|
||||||
#[error("can't mutate this value because it's not declared mutable")]
|
#[error("can't mutate this value because it's not declared mutable")]
|
||||||
NotMutable { span: Span, file_id: usize },
|
NotMutable {
|
||||||
|
span: Span,
|
||||||
|
declare_span: Option<Span>,
|
||||||
|
file_id: usize,
|
||||||
|
},
|
||||||
|
#[error("can't take a mutable borrow to this value because it's not declared mutable")]
|
||||||
|
CantTakeMutableBorrow {
|
||||||
|
span: Span,
|
||||||
|
declare_span: Option<Span>,
|
||||||
|
file_id: usize,
|
||||||
|
},
|
||||||
#[error("this method requires a mutable 'self'")]
|
#[error("this method requires a mutable 'self'")]
|
||||||
NotMutableSelf {
|
NotMutableSelf {
|
||||||
span: Span,
|
span: Span,
|
||||||
|
|
|
@ -536,6 +536,14 @@ fn lower_assign(builder: &mut BodyBuilder, info: &ast::AssignStmt) -> Result<(),
|
||||||
kind: ty,
|
kind: ty,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if !builder.body.locals[place.local].is_mutable() {
|
||||||
|
return Err(LoweringError::NotMutable {
|
||||||
|
span: info.span,
|
||||||
|
declare_span: builder.body.locals[place.local].span,
|
||||||
|
file_id: builder.file_id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
for _ in 0..info.deref_times {
|
for _ in 0..info.deref_times {
|
||||||
match &path_ty.kind {
|
match &path_ty.kind {
|
||||||
TypeKind::Ptr(is_mut, inner) => {
|
TypeKind::Ptr(is_mut, inner) => {
|
||||||
|
@ -687,7 +695,7 @@ fn lower_expr(
|
||||||
let ty = match ty {
|
let ty = match ty {
|
||||||
TypeKind::Ptr(_, inner) => *inner,
|
TypeKind::Ptr(_, inner) => *inner,
|
||||||
TypeKind::Ref(_, inner) => *inner,
|
TypeKind::Ref(_, inner) => *inner,
|
||||||
_ => todo!("proepr error here"),
|
_ => todo!("proper error here"),
|
||||||
};
|
};
|
||||||
|
|
||||||
(
|
(
|
||||||
|
@ -706,6 +714,16 @@ fn lower_expr(
|
||||||
};
|
};
|
||||||
let (mut value, ty, _span) = lower_expr(builder, inner, type_hint)?;
|
let (mut value, ty, _span) = lower_expr(builder, inner, type_hint)?;
|
||||||
|
|
||||||
|
if let Some(local) = value.get_local() {
|
||||||
|
if *mutable && !builder.body.locals[local].mutable {
|
||||||
|
return Err(LoweringError::CantTakeMutableBorrow {
|
||||||
|
span: *as_ref_span,
|
||||||
|
declare_span: builder.body.locals[local].span,
|
||||||
|
file_id: builder.file_id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check if its a use directly, to avoid a temporary.
|
// check if its a use directly, to avoid a temporary.
|
||||||
value = match value {
|
value = match value {
|
||||||
RValue::Use(op, _span) => RValue::Ref(*mutable, op, *as_ref_span),
|
RValue::Use(op, _span) => RValue::Ref(*mutable, op, *as_ref_span),
|
||||||
|
|
Loading…
Reference in a new issue