mirror of
https://github.com/alexgo-io/stacks-puppet-node.git
synced 2026-04-29 04:05:21 +08:00
fix: improve error in type checker
The error from the type checker when attempting to retrieve a trait type was incorrect. If the current contract is "foo", and the type "bar.baz" is not found in the analysis database, the error message said: ``` use of unresolved contract 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.foo' ``` When the actual problem was that the contract "bar" was not found. Similarly, if the contract "bar" is found, but the trait "baz" is not found, the same error was given, instead of correctly showing that the trait "baz" was not found. See #3064
This commit is contained in:
@@ -77,6 +77,8 @@ tests (#2989).
|
||||
key in the cost estimator. (#2984)
|
||||
- Fixed a few prometheus metrics to be more accurate compared to `/v2` endpoints
|
||||
when polling data (#2987)
|
||||
- Fixed an error message from the type-checker that shows up when the type of a
|
||||
parameter refers to a trait defined in the same contract (#3064).
|
||||
|
||||
## [2.05.0.0.0]
|
||||
|
||||
|
||||
@@ -156,6 +156,7 @@ pub enum CheckErrors {
|
||||
UnknownFunction(String),
|
||||
|
||||
// traits
|
||||
NoSuchTrait(String, String),
|
||||
TraitReferenceUnknown(String),
|
||||
TraitMethodUnknown(String, String),
|
||||
ExpectedTraitIdentifier,
|
||||
@@ -393,6 +394,7 @@ impl DiagnosableError for CheckErrors {
|
||||
CheckErrors::DefineNFTBadSignature => format!("(define-asset ...) expects an asset name and an asset identifier type signature as arguments"),
|
||||
CheckErrors::NoSuchNFT(asset_name) => format!("tried to use asset function with a undefined asset ('{}')", asset_name),
|
||||
CheckErrors::NoSuchFT(asset_name) => format!("tried to use token function with a undefined token ('{}')", asset_name),
|
||||
CheckErrors::NoSuchTrait(contract_name, trait_name) => format!("use of unresolved trait {}.{}", contract_name, trait_name),
|
||||
CheckErrors::TraitReferenceUnknown(trait_name) => format!("use of undeclared trait <{}>", trait_name),
|
||||
CheckErrors::TraitMethodUnknown(trait_name, func_name) => format!("method '{}' unspecified in trait <{}>", func_name, trait_name),
|
||||
CheckErrors::ImportTraitBadSignature => format!("(use-trait ...) expects a trait name and a trait identifier"),
|
||||
|
||||
@@ -1288,3 +1288,38 @@ fn test_return_trait_with_contract_of_wrapped_in_let() {
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trait_contract_not_found() {
|
||||
let trait_contract_src = "(define-trait my-trait
|
||||
((hello (int) (response uint uint)))
|
||||
)
|
||||
(define-private (pass-trait (a <my-trait>))
|
||||
(print a)
|
||||
)
|
||||
(define-public (call-it)
|
||||
(ok (pass-trait .impl-contract))
|
||||
)";
|
||||
let impl_contract_src = "(define-public (hello (a int))
|
||||
(ok u0)
|
||||
)";
|
||||
|
||||
let trait_contract_id = QualifiedContractIdentifier::local("trait-contract").unwrap();
|
||||
let impl_contract_id = QualifiedContractIdentifier::local("impl-contract").unwrap();
|
||||
|
||||
let mut impl_contract = parse(&impl_contract_id, impl_contract_src).unwrap();
|
||||
let mut trait_contract = parse(&trait_contract_id, trait_contract_src).unwrap();
|
||||
let mut marf = MemoryBackingStore::new();
|
||||
let mut db = marf.as_analysis_db();
|
||||
|
||||
let err = db
|
||||
.execute(|db| {
|
||||
type_check(&impl_contract_id, &mut impl_contract, db, true)?;
|
||||
type_check(&trait_contract_id, &mut trait_contract, db, true)
|
||||
})
|
||||
.unwrap_err();
|
||||
match err.err {
|
||||
CheckErrors::NoSuchContract(contract) => assert!(contract.ends_with(".trait-contract")),
|
||||
_ => panic!("{:?}", err),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,11 +418,16 @@ impl<'a, 'b> TypeChecker<'a, 'b> {
|
||||
let contract_defining_trait = self
|
||||
.db
|
||||
.load_contract(&trait_identifier.contract_identifier)
|
||||
.ok_or(CheckErrors::NoSuchContract(contract_identifier.to_string()))?;
|
||||
.ok_or(CheckErrors::NoSuchContract(
|
||||
trait_identifier.contract_identifier.to_string(),
|
||||
))?;
|
||||
|
||||
let trait_definition = contract_defining_trait
|
||||
.get_defined_trait(&trait_identifier.name)
|
||||
.ok_or(CheckErrors::NoSuchContract(contract_identifier.to_string()))?;
|
||||
.ok_or(CheckErrors::NoSuchTrait(
|
||||
trait_identifier.contract_identifier.to_string(),
|
||||
trait_identifier.name.to_string(),
|
||||
))?;
|
||||
|
||||
contract_to_check.check_trait_compliance(trait_identifier, trait_definition)?;
|
||||
return Ok(expected_type.clone());
|
||||
|
||||
Reference in New Issue
Block a user