mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 07:41:12 +00:00
Two shadowing report tests
This commit is contained in:
parent
671eb0f32e
commit
d8511e3285
3 changed files with 109 additions and 25 deletions
|
@ -1326,7 +1326,14 @@ fn to_pending_def<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(err) => panic!("TODO gracefully handle shadowing of type alias {:?}", err),
|
Err((original_region, shadow)) => {
|
||||||
|
env.problem(Problem::ShadowingInAnnotation {
|
||||||
|
original_region,
|
||||||
|
shadow,
|
||||||
|
});
|
||||||
|
|
||||||
|
panic!("TODO gracefully handle shadowing of type alias {:?}", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
use crate::report::ReportText::{BinOp, Concat, Module, Region, Value};
|
use crate::report::ReportText::{BinOp, Concat, Module, Region, Value};
|
||||||
use roc_module::symbol::{Interns, ModuleId, Symbol};
|
use roc_module::symbol::{Interns, ModuleId, Symbol};
|
||||||
use roc_problem::can::PrecedenceProblem::BothNonAssociative;
|
use roc_problem::can::PrecedenceProblem::BothNonAssociative;
|
||||||
use roc_problem::can::Problem;
|
use roc_problem::can::{Problem, RuntimeError};
|
||||||
use roc_types::pretty_print::content_to_string;
|
use roc_types::pretty_print::content_to_string;
|
||||||
use roc_types::subs::{Content, Subs};
|
use roc_types::subs::{Content, Subs};
|
||||||
use roc_types::types::{write_error_type, ErrorType};
|
use roc_types::types::{write_error_type, ErrorType};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use roc_module::ident::Ident;
|
||||||
|
use roc_region::all::Located;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use ven_pretty::{BoxAllocator, DocAllocator, DocBuilder, Render, RenderAnnotated};
|
use ven_pretty::{BoxAllocator, DocAllocator, DocBuilder, Render, RenderAnnotated};
|
||||||
|
|
||||||
|
@ -110,14 +112,21 @@ pub fn can_problem(filename: PathBuf, problem: Problem) -> Report {
|
||||||
original_region,
|
original_region,
|
||||||
shadow,
|
shadow,
|
||||||
} => {
|
} => {
|
||||||
// v-- just to satisfy clippy
|
shadowing_report(&mut texts, original_region, shadow);
|
||||||
let _a = original_region;
|
|
||||||
let _b = shadow;
|
|
||||||
panic!("TODO implement shadow report");
|
|
||||||
}
|
|
||||||
Problem::RuntimeError(_runtime_error) => {
|
|
||||||
panic!("TODO implement run time error report");
|
|
||||||
}
|
}
|
||||||
|
Problem::RuntimeError(runtime_error) => match runtime_error {
|
||||||
|
RuntimeError::Shadowing {
|
||||||
|
original_region,
|
||||||
|
shadow,
|
||||||
|
} => {
|
||||||
|
shadowing_report(&mut texts, original_region, shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {
|
||||||
|
dbg!(runtime_error);
|
||||||
|
panic!("TODO implement run time error reporting");
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Report {
|
Report {
|
||||||
|
@ -126,11 +135,27 @@ pub fn can_problem(filename: PathBuf, problem: Problem) -> Report {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn shadowing_report(
|
||||||
|
texts: &mut Vec<ReportText>,
|
||||||
|
original_region: roc_region::all::Region,
|
||||||
|
shadow: Located<Ident>,
|
||||||
|
) {
|
||||||
|
texts.push(name(shadow.value));
|
||||||
|
texts.push(plain_text(" is first defined here:"));
|
||||||
|
texts.push(Region(original_region));
|
||||||
|
texts.push(plain_text("But then it's defined a second time here:"));
|
||||||
|
texts.push(Region(shadow.region));
|
||||||
|
texts.push(plain_text("Since these variables have the same name, it's easy to use the wrong one on accident. Give one of them a new name."));
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum ReportText {
|
pub enum ReportText {
|
||||||
/// A value. Render it qualified unless it was defined in the current module.
|
/// A value. Render it qualified unless it was defined in the current module.
|
||||||
Value(Symbol),
|
Value(Symbol),
|
||||||
|
|
||||||
|
/// An identifier, should probably be rendered the same way as a symbol.
|
||||||
|
Name(Ident),
|
||||||
|
|
||||||
/// A module,
|
/// A module,
|
||||||
Module(ModuleId),
|
Module(ModuleId),
|
||||||
|
|
||||||
|
@ -181,6 +206,10 @@ pub fn plain_text(str: &str) -> ReportText {
|
||||||
ReportText::Plain(Box::from(str))
|
ReportText::Plain(Box::from(str))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn name(ident: Ident) -> ReportText {
|
||||||
|
ReportText::Name(ident)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn em_text(str: &str) -> ReportText {
|
pub fn em_text(str: &str) -> ReportText {
|
||||||
ReportText::EmText(Box::from(str))
|
ReportText::EmText(Box::from(str))
|
||||||
}
|
}
|
||||||
|
@ -658,6 +687,9 @@ impl ReportText {
|
||||||
.append(alloc.line())
|
.append(alloc.line())
|
||||||
.append(alloc.line())
|
.append(alloc.line())
|
||||||
}
|
}
|
||||||
|
Name(ident) => alloc
|
||||||
|
.text(format!("{}", ident.as_inline_str()))
|
||||||
|
.annotate(Annotation::Symbol),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -305,22 +305,67 @@ mod test_reporting {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test]
|
#[test]
|
||||||
// fn report_shadow() {
|
fn report_shadowing() {
|
||||||
// report_problem_as(
|
report_problem_as(
|
||||||
// indoc!(
|
indoc!(
|
||||||
// r#"
|
r#"
|
||||||
// i = 1
|
i = 1
|
||||||
//
|
|
||||||
// s = \i ->
|
s = \i ->
|
||||||
// i + 1
|
i + 1
|
||||||
//
|
|
||||||
// s i
|
s i
|
||||||
// "#
|
"#
|
||||||
// ),
|
),
|
||||||
// indoc!(r#" "#),
|
indoc!(
|
||||||
// )
|
r#"
|
||||||
// }
|
i is first defined here:
|
||||||
|
|
||||||
|
1 ┆ i = 1
|
||||||
|
┆ ^
|
||||||
|
|
||||||
|
But then it's defined a second time here:
|
||||||
|
|
||||||
|
3 ┆ s = \i ->
|
||||||
|
┆ ^
|
||||||
|
|
||||||
|
Since these variables have the same name, it's easy to use the wrong one on accident. Give one of them a new name."#
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn report_shadowing_in_annotation() {
|
||||||
|
report_problem_as(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
Booly : [ Yes, No ]
|
||||||
|
|
||||||
|
Booly : [ Yes, No, Maybe ]
|
||||||
|
|
||||||
|
x =
|
||||||
|
No
|
||||||
|
|
||||||
|
x
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
Booly is first defined here:
|
||||||
|
|
||||||
|
1 ┆ Booly : [ Yes, No ]
|
||||||
|
┆ ^^^^^
|
||||||
|
|
||||||
|
But then it's defined a second time here:
|
||||||
|
|
||||||
|
3 ┆ Booly : [ Yes, No, Maybe ]
|
||||||
|
┆ ^^^^^
|
||||||
|
|
||||||
|
Since these variables have the same name, it's easy to use the wrong one on accident. Give one of them a new name."#
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// #[test]
|
// #[test]
|
||||||
// fn report_unsupported_top_level_def() {
|
// fn report_unsupported_top_level_def() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue