Fix redundant warning when destructuring validator params
This is not a "proper" fix as it simply get rid of the warning altogether (whether you use or not the destructured values). The reason for removing the warning entirely is because (1) it's simpler, but more so (2) there's no impact on the final code produced _anyway_. Redundant let bindings are already removed by the compiler; and while it's an implicit behaviour that requires a proper warning when it's coming from a user-defined assignment; here the redundant assignment is introduced by the compiler to begin with as another implicit behavior! So we have an implicit behaviour triggering a warning on another implicit behaviour. Truth is, there's no impact in having those parameters destructured and unused. So since users are already not aware that this results in an implicit let assignment being inserted in place for them; there's no need for the warning at all.
This commit is contained in:
parent
5737556efc
commit
0060804d1a
|
@ -9,6 +9,7 @@
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- **aiken-lang**: Fix compiler crash on trace + expect as last expression of a clause. See #1029. @KtorZ
|
- **aiken-lang**: Fix compiler crash on trace + expect as last expression of a clause. See #1029. @KtorZ
|
||||||
|
- **aiken-lang**: Fix redundant warning on introduced identifiers when destructuring validator params. @KtorZ
|
||||||
- **uplc**: Fix (again :grimacing:) cost-models for PlutusV1 & PlutusV2. @MicroProofs
|
- **uplc**: Fix (again :grimacing:) cost-models for PlutusV1 & PlutusV2. @MicroProofs
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
|
@ -1047,7 +1047,7 @@ impl UntypedArg {
|
||||||
// NOTE: We use ordinal here not only because it's cute, but because
|
// NOTE: We use ordinal here not only because it's cute, but because
|
||||||
// such a name cannot be parsed to begin with and thus, will not clash
|
// such a name cannot be parsed to begin with and thus, will not clash
|
||||||
// with any user-defined name.
|
// with any user-defined name.
|
||||||
let name = format!("{}_arg", Ordinal::<usize>(ix).suffix());
|
let name = format!("{}{}_arg", ix + 1, Ordinal::<usize>(ix + 1).suffix());
|
||||||
ArgName::Named {
|
ArgName::Named {
|
||||||
label: name.clone(),
|
label: name.clone(),
|
||||||
name,
|
name,
|
||||||
|
@ -1770,6 +1770,36 @@ impl UntypedPattern {
|
||||||
is_record: false,
|
is_record: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn collect_identifiers<F>(&self, collect: &mut F)
|
||||||
|
where
|
||||||
|
F: FnMut((String, Span)),
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
Pattern::Var { name, location } => {
|
||||||
|
collect((name.to_string(), *location));
|
||||||
|
}
|
||||||
|
Pattern::List { elements, .. } => {
|
||||||
|
elements.iter().for_each(|e| e.collect_identifiers(collect));
|
||||||
|
}
|
||||||
|
Pattern::Pair { fst, snd, .. } => {
|
||||||
|
fst.collect_identifiers(collect);
|
||||||
|
snd.collect_identifiers(collect);
|
||||||
|
}
|
||||||
|
Pattern::Tuple { elems, .. } => {
|
||||||
|
elems.iter().for_each(|e| e.collect_identifiers(collect));
|
||||||
|
}
|
||||||
|
Pattern::Constructor { arguments, .. } => {
|
||||||
|
arguments
|
||||||
|
.iter()
|
||||||
|
.for_each(|arg| arg.value.collect_identifiers(collect));
|
||||||
|
}
|
||||||
|
Pattern::Int { .. }
|
||||||
|
| Pattern::ByteArray { .. }
|
||||||
|
| Pattern::Discard { .. }
|
||||||
|
| Pattern::Assign { .. } => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypedPattern {
|
impl TypedPattern {
|
||||||
|
|
|
@ -3342,3 +3342,55 @@ fn dangling_trace_let_in_trace() {
|
||||||
Err((_, Error::LastExpressionIsAssignment { .. }))
|
Err((_, Error::LastExpressionIsAssignment { .. }))
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn destructuring_validator_params_tuple() {
|
||||||
|
let source_code = r#"
|
||||||
|
validator foo((x, y): (Int, Int)) {
|
||||||
|
mint(_redeemer, _policy_id, _self) {
|
||||||
|
x + y > 42
|
||||||
|
}
|
||||||
|
|
||||||
|
else(_) {
|
||||||
|
fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
|
let result = check_validator(parse(source_code));
|
||||||
|
assert!(result.is_ok());
|
||||||
|
|
||||||
|
let (warnings, _) = result.unwrap();
|
||||||
|
assert!(
|
||||||
|
matches!(&warnings[..], &[]),
|
||||||
|
"should be empty: {warnings:#?}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn destructuring_validator_params_record() {
|
||||||
|
let source_code = r#"
|
||||||
|
pub type Foo {
|
||||||
|
Foo(Int, Int)
|
||||||
|
}
|
||||||
|
|
||||||
|
validator foo(Foo(x, y): Foo) {
|
||||||
|
mint(_redeemer, _policy_id, _self) {
|
||||||
|
x + y > 42
|
||||||
|
}
|
||||||
|
|
||||||
|
else(_) {
|
||||||
|
fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
|
let result = check_validator(parse(source_code));
|
||||||
|
assert!(result.is_ok());
|
||||||
|
|
||||||
|
let (warnings, _) = result.unwrap();
|
||||||
|
assert!(
|
||||||
|
matches!(&warnings[..], &[]),
|
||||||
|
"should be empty: {warnings:#?}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ pub struct Environment<'a> {
|
||||||
pub entity_usages: Vec<HashMap<String, (EntityKind, Span, bool)>>,
|
pub entity_usages: Vec<HashMap<String, (EntityKind, Span, bool)>>,
|
||||||
pub id_gen: IdGenerator,
|
pub id_gen: IdGenerator,
|
||||||
pub importable_modules: &'a HashMap<String, TypeInfo>,
|
pub importable_modules: &'a HashMap<String, TypeInfo>,
|
||||||
|
pub validator_params: HashSet<(String, Span)>,
|
||||||
|
|
||||||
/// Modules that have been imported by the current module, along with the
|
/// Modules that have been imported by the current module, along with the
|
||||||
/// location of the import statement where they were imported.
|
/// location of the import statement where they were imported.
|
||||||
|
@ -792,6 +793,7 @@ impl<'a> Environment<'a> {
|
||||||
annotations: HashMap::new(),
|
annotations: HashMap::new(),
|
||||||
warnings,
|
warnings,
|
||||||
entity_usages: vec![HashMap::new()],
|
entity_usages: vec![HashMap::new()],
|
||||||
|
validator_params: HashSet::new(),
|
||||||
target_env,
|
target_env,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,10 @@ use super::{
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
Annotation, ArgName, ArgVia, DataType, Definition, Function, ModuleConstant, ModuleKind,
|
Annotation, ArgBy, ArgName, ArgVia, DataType, Definition, Function, ModuleConstant,
|
||||||
RecordConstructor, RecordConstructorArg, Tracing, TypeAlias, TypedArg, TypedDefinition,
|
ModuleKind, RecordConstructor, RecordConstructorArg, Tracing, TypeAlias, TypedArg,
|
||||||
TypedModule, TypedValidator, UntypedArg, UntypedDefinition, UntypedModule, UntypedPattern,
|
TypedDefinition, TypedModule, TypedValidator, UntypedArg, UntypedDefinition, UntypedModule,
|
||||||
UntypedValidator, Use, Validator,
|
UntypedPattern, UntypedValidator, Use, Validator,
|
||||||
},
|
},
|
||||||
expr::{TypedExpr, UntypedAssignmentKind},
|
expr::{TypedExpr, UntypedAssignmentKind},
|
||||||
tipo::{expr::infer_function, Span, Type, TypeVar},
|
tipo::{expr::infer_function, Span, Type, TypeVar},
|
||||||
|
@ -100,6 +100,14 @@ impl UntypedModule {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// Generate warnings for unused items
|
// Generate warnings for unused items
|
||||||
|
println!("warnings: {:#?}", environment.warnings);
|
||||||
|
println!("params: {:#?}", environment.validator_params);
|
||||||
|
environment.warnings.retain(|warning| match warning {
|
||||||
|
Warning::UnusedVariable { location, name } => !environment
|
||||||
|
.validator_params
|
||||||
|
.contains(&(name.to_string(), *location)),
|
||||||
|
_ => true,
|
||||||
|
});
|
||||||
environment.convert_unused_to_warnings();
|
environment.convert_unused_to_warnings();
|
||||||
|
|
||||||
// Remove private and imported types and values to create the public interface
|
// Remove private and imported types and values to create the public interface
|
||||||
|
@ -812,7 +820,11 @@ fn annotate_fuzzer(tipo: &Type, location: &Span) -> Result<Annotation, Error> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn put_params_in_scope(name: &str, environment: &mut Environment, params: &[UntypedArg]) {
|
fn put_params_in_scope<'a>(
|
||||||
|
name: &'_ str,
|
||||||
|
environment: &'a mut Environment,
|
||||||
|
params: &'a [UntypedArg],
|
||||||
|
) {
|
||||||
let preregistered_fn = environment
|
let preregistered_fn = environment
|
||||||
.get_variable(name)
|
.get_variable(name)
|
||||||
.expect("Could not find preregistered type for function");
|
.expect("Could not find preregistered type for function");
|
||||||
|
@ -828,7 +840,7 @@ fn put_params_in_scope(name: &str, environment: &mut Environment, params: &[Unty
|
||||||
.zip(args_types[0..params.len()].iter())
|
.zip(args_types[0..params.len()].iter())
|
||||||
.enumerate()
|
.enumerate()
|
||||||
{
|
{
|
||||||
match &arg.arg_name(ix) {
|
match arg.arg_name(ix) {
|
||||||
ArgName::Named {
|
ArgName::Named {
|
||||||
name,
|
name,
|
||||||
label: _,
|
label: _,
|
||||||
|
@ -842,7 +854,13 @@ fn put_params_in_scope(name: &str, environment: &mut Environment, params: &[Unty
|
||||||
t.clone(),
|
t.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
environment.init_usage(name.to_string(), EntityKind::Variable, arg.location);
|
if let ArgBy::ByPattern(ref pattern) = arg.by {
|
||||||
|
pattern.collect_identifiers(&mut |identifier| {
|
||||||
|
environment.validator_params.insert(identifier);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
environment.init_usage(name, EntityKind::Variable, arg.location);
|
||||||
}
|
}
|
||||||
ArgName::Named { .. } | ArgName::Discarded { .. } => (),
|
ArgName::Named { .. } | ArgName::Discarded { .. } => (),
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue