return dedicated error on invalid type field access, instead of confusing 'unknown module.'
Signed-off-by: KtorZ <matthias.benkort@gmail.com>
This commit is contained in:
parent
18d2beeadb
commit
d7af418a63
|
@ -2724,6 +2724,64 @@ fn use_non_imported_module_as_namespace() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_type_field_access_chain() {
|
||||
let dependency = r#"
|
||||
pub type Foo {
|
||||
I(Int)
|
||||
B(Bool)
|
||||
}
|
||||
"#;
|
||||
|
||||
let source_code = r#"
|
||||
use foo.{Foo}
|
||||
|
||||
test my_test() {
|
||||
trace Foo.I.Int(42)
|
||||
Void
|
||||
}
|
||||
"#;
|
||||
|
||||
let result = check_with_deps(parse(source_code), vec![(parse_as(dependency, "foo"))]);
|
||||
|
||||
assert!(
|
||||
matches!(
|
||||
&result,
|
||||
Err((warnings, Error::InvalidFieldAccess { .. })) if warnings.is_empty(),
|
||||
),
|
||||
"{result:#?}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_type_field_access_chain_2() {
|
||||
let dependency = r#"
|
||||
pub type Foo {
|
||||
I(Int)
|
||||
B(Bool)
|
||||
}
|
||||
"#;
|
||||
|
||||
let source_code = r#"
|
||||
use foo.{Foo}
|
||||
|
||||
test my_test() {
|
||||
trace Foo.i(42)
|
||||
Void
|
||||
}
|
||||
"#;
|
||||
|
||||
let result = check_with_deps(parse(source_code), vec![(parse_as(dependency, "foo"))]);
|
||||
|
||||
assert!(
|
||||
matches!(
|
||||
&result,
|
||||
Err((warnings, Error::UnknownTypeConstructor { .. })) if warnings.is_empty(),
|
||||
),
|
||||
"{result:#?}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn forbid_importing_or_using_opaque_constructors() {
|
||||
let dependency = r#"
|
||||
|
|
|
@ -1079,7 +1079,7 @@ The best thing to do from here is to remove it."#))]
|
|||
available_purposes: Vec<String>,
|
||||
},
|
||||
|
||||
#[error("I could not find an appropriate handler in the validator definition\n")]
|
||||
#[error("I could not find an appropriate handler in the validator definition.\n")]
|
||||
#[diagnostic(code("unknown::handler"))]
|
||||
#[diagnostic(help(
|
||||
"When referring to a validator handler via record access, you must refer to one of the declared handlers{}{}",
|
||||
|
@ -1095,7 +1095,7 @@ The best thing to do from here is to remove it."#))]
|
|||
available_handlers: Vec<String>,
|
||||
},
|
||||
|
||||
#[error("I caught an extraneous fallback handler in an already exhaustive validator\n")]
|
||||
#[error("I caught an extraneous fallback handler in an already exhaustive validator.\n")]
|
||||
#[diagnostic(code("extraneous::fallback"))]
|
||||
#[diagnostic(help(
|
||||
"Validator handlers must be exhaustive and either cover all purposes, or provide a fallback handler. Here, you have successfully covered all script purposes with your handler, but left an extraneous fallback branch. I cannot let that happen, but removing it for you would probably be deemed rude. So please, remove the fallback."
|
||||
|
@ -1104,6 +1104,16 @@ The best thing to do from here is to remove it."#))]
|
|||
#[label("redundant fallback handler")]
|
||||
fallback: Span,
|
||||
},
|
||||
|
||||
#[error("I was stopped by a suspicious field access chain.\n")]
|
||||
#[diagnostic(code("invalid::field_access"))]
|
||||
#[diagnostic(help(
|
||||
"It seems like you've got things mixed up a little here? You can only access fields exported by modules or, by types within those modules. Double-check the culprit field access chain, there's likely something wrong about it."
|
||||
))]
|
||||
InvalidFieldAccess {
|
||||
#[label("invalid field access")]
|
||||
location: Span,
|
||||
},
|
||||
}
|
||||
|
||||
impl ExtraData for Error {
|
||||
|
@ -1166,7 +1176,8 @@ impl ExtraData for Error {
|
|||
| Error::UnknownValidatorHandler { .. }
|
||||
| Error::UnexpectedValidatorFallback { .. }
|
||||
| Error::IncorrectBenchmarkArity { .. }
|
||||
| Error::MustInferFirst { .. } => None,
|
||||
| Error::MustInferFirst { .. }
|
||||
| Error::InvalidFieldAccess { .. } => None,
|
||||
|
||||
Error::UnknownType { name, .. }
|
||||
| Error::UnknownTypeConstructor { name, .. }
|
||||
|
|
|
@ -1095,6 +1095,12 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
location: module_location,
|
||||
} = type_container.as_ref()
|
||||
{
|
||||
if TypeConstructor::might_be(module_name) {
|
||||
return Err(Error::InvalidFieldAccess {
|
||||
location: access_location,
|
||||
});
|
||||
}
|
||||
|
||||
// Lookup the module using the declared name (which may have been rebind with
|
||||
// 'as'), to obtain its _full unambiguous name_.
|
||||
let (_, module) = self
|
||||
|
|
Loading…
Reference in New Issue