From 87218cb6d70ef54d9639d2afaddb1abf1ae7cffe Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 8 May 2025 11:59:10 +0100 Subject: [PATCH 01/86] Rust: Test more examples of sensitive data. --- .../test/library-tests/sensitivedata/test.rs | 117 +++++++++++++++++- 1 file changed, 111 insertions(+), 6 deletions(-) diff --git a/rust/ql/test/library-tests/sensitivedata/test.rs b/rust/ql/test/library-tests/sensitivedata/test.rs index ff5496fb736..f42c82edd8c 100644 --- a/rust/ql/test/library-tests/sensitivedata/test.rs +++ b/rust/ql/test/library-tests/sensitivedata/test.rs @@ -10,6 +10,7 @@ struct MyStruct { password: String, password_file_path: String, password_enabled: String, + mfa: String, } impl MyStruct { @@ -22,8 +23,8 @@ fn get_password() -> String { get_string() } fn test_passwords( password: &str, pass_word: &str, passwd: &str, my_password: &str, password_str: &str, - pass_phrase: &str, passphrase: &str, passPhrase: &str, - auth_key: &str, authkey: &str, authKey: &str, authentication_key: &str, authenticationkey: &str, authenticationKey: &str, + pass_phrase: &str, passphrase: &str, passPhrase: &str, backup_code: &str, + auth_key: &str, authkey: &str, authKey: &str, authentication_key: &str, authenticationkey: &str, authenticationKey: &str, oauth: &str, harmless: &str, encrypted_password: &str, password_hash: &str, ms: &MyStruct ) { @@ -36,6 +37,7 @@ fn test_passwords( sink(pass_phrase); // $ sensitive=password sink(passphrase); // $ sensitive=password sink(passPhrase); // $ sensitive=password + sink(backup_code); // $ MISSING: sensitive=password sink(auth_key); // $ sensitive=password sink(authkey); // $ sensitive=password @@ -43,14 +45,19 @@ fn test_passwords( sink(authentication_key); // $ sensitive=password sink(authenticationkey); // $ sensitive=password sink(authenticationKey); // $ sensitive=password + sink(oauth); // $ MISSING: sensitive=password sink(ms); // $ MISSING: sensitive=password sink(ms.password.as_str()); // $ MISSING: sensitive=password + sink(ms.mfa.as_str()); // $ MISSING: sensitive=password sink(get_password()); // $ sensitive=password let password2 = get_string(); sink(password2); // $ sensitive=password + let qry = "password=abc"; + sink(qry); // $ MISSING: sensitive=password + // not passwords sink(harmless); sink(encrypted_password); @@ -115,32 +122,98 @@ fn test_credentials( sink(get_next_token()); } +struct MacAddr { + values: [u8;12], +} + +struct DeviceInfo { + api_key: String, + deviceApiToken: String, + finger_print: String, + ip_address: String, + macaddr12: [u8;12], + mac_addr: MacAddr, + networkMacAddress: String, +} + +impl DeviceInfo { + fn test_device_info(&self, other: &DeviceInfo) { + // private device info + sink(&self.api_key); // $ MISSING: sensitive=id + sink(&other.api_key); // $ MISSING: sensitive=id + sink(&self.deviceApiToken); // $ MISSING: sensitive=id + sink(&self.finger_print); // $ MISSING: sensitive=id + sink(&self.ip_address); // $ MISSING: sensitive=id + sink(self.macaddr12); // $ MISSING: sensitive=id + sink(&self.mac_addr); // $ MISSING: sensitive=id + sink(self.mac_addr.values); // $ MISSING: sensitive=id + sink(self.mac_addr.values[0]); // $ MISSING: sensitive=id + sink(&self.networkMacAddress); // $ MISSING: sensitive=id + } +} + struct Financials { harmless: String, my_bank_account_number: String, credit_card_no: String, credit_rating: i32, - user_ccn: String + user_ccn: String, + cvv: String, + beneficiary: String, + routing_number: u64, + routingNumberText: String, + iban: String, + iBAN: String, +} + +enum Gender { + Male, + Female, +} + +struct SSN { + data: u128, +} + +impl SSN { + fn get_data(&self) -> u128 { + return self.data; + } } struct MyPrivateInfo { mobile_phone_num: String, contact_email: String, contact_e_mail_2: String, - my_ssn: String, - birthday: String, emergency_contact: String, + my_ssn: String, + ssn: SSN, + birthday: String, name_of_employer: String, + gender: Gender, + genderString: String, + + patient_id: u64, + linkedPatientId: u64, + patient_record: String, medical_notes: Vec, + confidentialMessage: String, + latitude: f64, longitude: Option, financials: Financials } +enum ContactDetails { + HomePhoneNumber(String), + MobileNumber(String), + Email(String), +} + fn test_private_info( - info: &MyPrivateInfo + info: &MyPrivateInfo, details: &ContactDetails, ) { // private info sink(info.mobile_phone_num.as_str()); // $ MISSING: sensitive=private @@ -148,15 +221,33 @@ fn test_private_info( sink(info.contact_email.as_str()); // $ MISSING: sensitive=private sink(info.contact_e_mail_2.as_str()); // $ MISSING: sensitive=private sink(info.my_ssn.as_str()); // $ MISSING: sensitive=private + sink(&info.ssn); // $ MISSING: sensitive=private + sink(info.ssn.data); // $ MISSING: sensitive=private + sink(info.ssn.get_data()); // $ MISSING: sensitive=private sink(info.birthday.as_str()); // $ MISSING: sensitive=private sink(info.emergency_contact.as_str()); // $ MISSING: sensitive=private sink(info.name_of_employer.as_str()); // $ MISSING: sensitive=private + sink(&info.gender); // $ MISSING: sensitive=private + sink(info.genderString.as_str()); // $ MISSING: sensitive=private + let sex = "Male"; + let gender = Gender::Female; + let a = Gender::Female; + sink(sex); // $ MISSING: sensitive=private + sink(gender); // $ MISSING: sensitive=private + sink(a); // $ MISSING: sensitive=private + + sink(info.patient_id); // $ MISSING: sensitive=private + sink(info.linkedPatientId); // $ MISSING: sensitive=private + sink(info.patient_record.as_str()); // $ MISSING: sensitive=private + sink(info.patient_record.trim()); // $ MISSING: sensitive=private sink(&info.medical_notes); // $ MISSING: sensitive=private sink(info.medical_notes[0].as_str()); // $ MISSING: sensitive=private for n in info.medical_notes.iter() { sink(n.as_str()); // $ MISSING: sensitive=private } + sink(info.confidentialMessage.as_str()); // $ MISSING: sensitive=private + sink(info.confidentialMessage.to_lowercase()); // $ MISSING: sensitive=private sink(info.latitude); // $ MISSING: sensitive=private let x = info.longitude.unwrap(); @@ -166,7 +257,21 @@ fn test_private_info( sink(info.financials.credit_card_no.as_str()); // $ MISSING: sensitive=private sink(info.financials.credit_rating); // $ MISSING: sensitive=private sink(info.financials.user_ccn.as_str()); // $ MISSING: sensitive=private + sink(info.financials.cvv.as_str()); // $ MISSING: sensitive=private + sink(info.financials.beneficiary.as_str()); // $ MISSING: sensitive=private + sink(info.financials.routing_number); // $ MISSING: sensitive=private + sink(info.financials.routingNumberText.as_str()); // $ MISSING: sensitive=private + sink(info.financials.iban.as_str()); // $ MISSING: sensitive=private + sink(info.financials.iBAN.as_str()); // $ MISSING: sensitive=private + + sink(ContactDetails::HomePhoneNumber("123".to_string())); // $ MISSING: sensitive=private + sink(ContactDetails::MobileNumber("123".to_string())); // $ MISSING: sensitive=private + sink(ContactDetails::Email("a@b".to_string())); // $ MISSING: sensitive=private + if let ContactDetails::MobileNumber(num) = details { + sink(num.as_str()); // $ MISSING: sensitive=private + } // not private info + sink(info.financials.harmless.as_str()); } From 8825eefea6afe25f046016cbda2751112eb8cef0 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 8 May 2025 16:00:46 +0100 Subject: [PATCH 02/86] Rust: More counterexamples for sensitive data as well. --- .../test/library-tests/sensitivedata/test.rs | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/rust/ql/test/library-tests/sensitivedata/test.rs b/rust/ql/test/library-tests/sensitivedata/test.rs index f42c82edd8c..4718a2b451e 100644 --- a/rust/ql/test/library-tests/sensitivedata/test.rs +++ b/rust/ql/test/library-tests/sensitivedata/test.rs @@ -11,6 +11,7 @@ struct MyStruct { password_file_path: String, password_enabled: String, mfa: String, + numfailed: String, } impl MyStruct { @@ -25,10 +26,11 @@ fn test_passwords( password: &str, pass_word: &str, passwd: &str, my_password: &str, password_str: &str, pass_phrase: &str, passphrase: &str, passPhrase: &str, backup_code: &str, auth_key: &str, authkey: &str, authKey: &str, authentication_key: &str, authenticationkey: &str, authenticationKey: &str, oauth: &str, - harmless: &str, encrypted_password: &str, password_hash: &str, + harmless: &str, encrypted_password: &str, password_hash: &str, passwordFile: &str, ms: &MyStruct ) { // passwords + sink(password); // $ sensitive=password sink(pass_word); // $ MISSING: sensitive=password sink(passwd); // $ sensitive=password @@ -59,13 +61,16 @@ fn test_passwords( sink(qry); // $ MISSING: sensitive=password // not passwords + sink(harmless); sink(encrypted_password); sink(password_hash); + sink(passwordFile); // $ SPURIOUS: sensitive=password sink(ms.harmless.as_str()); sink(ms.password_file_path.as_str()); sink(ms.password_enabled.as_str()); + sink(ms.numfailed.as_str()); sink(get_string()); let harmless2 = get_string(); @@ -82,10 +87,11 @@ fn get_next_token() -> String { get_string() } fn test_credentials( account_key: &str, accnt_key: &str, license_key: &str, secret_key: &str, is_secret: bool, num_accounts: i64, username: String, user_name: String, userid: i64, user_id: i64, my_user_id_64: i64, unique_id: i64, uid: i64, - sessionkey: &[u64; 4], session_key: &[u64; 4], hashkey: &[u64; 4], hash_key: &[u64; 4], + sessionkey: &[u64; 4], session_key: &[u64; 4], hashkey: &[u64; 4], hash_key: &[u64; 4], sessionkeypath: &[u64; 4], account_key_path: &[u64; 4], ms: &MyStruct ) { // credentials + sink(account_key); // $ sensitive=id sink(accnt_key); // $ sensitive=id sink(license_key); // $ MISSING: sensitive=secret @@ -108,12 +114,15 @@ fn test_credentials( sink(get_secret_token()); // $ sensitive=secret // not (necessarily) credentials + sink(is_secret); sink(num_accounts); // $ SPURIOUS: sensitive=id sink(unique_id); sink(uid); // $ SPURIOUS: sensitive=id sink(hashkey); sink(hash_key); + sink(sessionkeypath); // $ SPURIOUS: sensitive=id + sink(account_key_path); // $ SPURIOUS: sensitive=id sink(ms.get_certificate_url()); // $ SPURIOUS: sensitive=certificate sink(ms.get_certificate_file()); // $ SPURIOUS: sensitive=certificate @@ -134,11 +143,17 @@ struct DeviceInfo { macaddr12: [u8;12], mac_addr: MacAddr, networkMacAddress: String, + + // not private device info + macro_value: bool, + mac_command: u32, + skip_address: String, } impl DeviceInfo { fn test_device_info(&self, other: &DeviceInfo) { // private device info + sink(&self.api_key); // $ MISSING: sensitive=id sink(&other.api_key); // $ MISSING: sensitive=id sink(&self.deviceApiToken); // $ MISSING: sensitive=id @@ -149,6 +164,12 @@ impl DeviceInfo { sink(self.mac_addr.values); // $ MISSING: sensitive=id sink(self.mac_addr.values[0]); // $ MISSING: sensitive=id sink(&self.networkMacAddress); // $ MISSING: sensitive=id + + // not private device info + + sink(self.macro_value); + sink(self.mac_command); + sink(&self.skip_address); } } @@ -164,6 +185,12 @@ struct Financials { routingNumberText: String, iban: String, iBAN: String, + + num_accounts: i32, + total_accounts: i32, + accounting: i32, + unaccounted: bool, + multiband: bool, } enum Gender { @@ -210,12 +237,14 @@ enum ContactDetails { HomePhoneNumber(String), MobileNumber(String), Email(String), + FavouriteColor(String), } fn test_private_info( info: &MyPrivateInfo, details: &ContactDetails, ) { // private info + sink(info.mobile_phone_num.as_str()); // $ MISSING: sensitive=private sink(info.mobile_phone_num.to_string()); // $ MISSING: sensitive=private sink(info.contact_email.as_str()); // $ MISSING: sensitive=private @@ -273,5 +302,15 @@ fn test_private_info( // not private info + let modulesEx = 1; + sink(modulesEx); + sink(info.financials.harmless.as_str()); + sink(info.financials.num_accounts); + sink(info.financials.total_accounts); + sink(info.financials.accounting); + sink(info.financials.unaccounted); + sink(info.financials.multiband); + + sink(ContactDetails::FavouriteColor("blue".to_string())); } From a537197691fba15f07676187151f2d6bd63b1da7 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 9 May 2025 10:39:53 +0100 Subject: [PATCH 03/86] Rust: Understand sensitive field access expressions. --- .../codeql/rust/security/SensitiveData.qll | 19 ++++++++- .../test/library-tests/sensitivedata/test.rs | 42 +++++++++---------- 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/rust/ql/lib/codeql/rust/security/SensitiveData.qll b/rust/ql/lib/codeql/rust/security/SensitiveData.qll index 5a5f5a6dec0..698fa83197d 100644 --- a/rust/ql/lib/codeql/rust/security/SensitiveData.qll +++ b/rust/ql/lib/codeql/rust/security/SensitiveData.qll @@ -67,7 +67,7 @@ private class SensitiveDataVariable extends Variable { } /** - * A variable access data flow node that might produce sensitive data. + * A variable access data flow node that might be sensitive data. */ private class SensitiveVariableAccess extends SensitiveData { SensitiveDataClassification classification; @@ -84,3 +84,20 @@ private class SensitiveVariableAccess extends SensitiveData { override SensitiveDataClassification getClassification() { result = classification } } + +/** + * A field access data flow node that might be sensitive data. + */ +private class SensitiveFieldAccess extends SensitiveData { + SensitiveDataClassification classification; + + SensitiveFieldAccess() { + HeuristicNames::nameIndicatesSensitiveData(this.asExpr() + .getAstNode() + .(FieldExpr) + .getIdentifier() + .getText(), classification) + } + + override SensitiveDataClassification getClassification() { result = classification } +} diff --git a/rust/ql/test/library-tests/sensitivedata/test.rs b/rust/ql/test/library-tests/sensitivedata/test.rs index 4718a2b451e..42fb2f0693b 100644 --- a/rust/ql/test/library-tests/sensitivedata/test.rs +++ b/rust/ql/test/library-tests/sensitivedata/test.rs @@ -50,7 +50,7 @@ fn test_passwords( sink(oauth); // $ MISSING: sensitive=password sink(ms); // $ MISSING: sensitive=password - sink(ms.password.as_str()); // $ MISSING: sensitive=password + sink(ms.password.as_str()); // $ sensitive=password sink(ms.mfa.as_str()); // $ MISSING: sensitive=password sink(get_password()); // $ sensitive=password @@ -68,8 +68,8 @@ fn test_passwords( sink(passwordFile); // $ SPURIOUS: sensitive=password sink(ms.harmless.as_str()); - sink(ms.password_file_path.as_str()); - sink(ms.password_enabled.as_str()); + sink(ms.password_file_path.as_str()); // $ SPURIOUS: sensitive=password + sink(ms.password_enabled.as_str()); // $ SPURIOUS: sensitive=password sink(ms.numfailed.as_str()); sink(get_string()); @@ -245,17 +245,17 @@ fn test_private_info( ) { // private info - sink(info.mobile_phone_num.as_str()); // $ MISSING: sensitive=private - sink(info.mobile_phone_num.to_string()); // $ MISSING: sensitive=private + sink(info.mobile_phone_num.as_str()); // $ sensitive=private + sink(info.mobile_phone_num.to_string()); // $ sensitive=private sink(info.contact_email.as_str()); // $ MISSING: sensitive=private sink(info.contact_e_mail_2.as_str()); // $ MISSING: sensitive=private - sink(info.my_ssn.as_str()); // $ MISSING: sensitive=private - sink(&info.ssn); // $ MISSING: sensitive=private + sink(info.my_ssn.as_str()); // $ sensitive=private + sink(&info.ssn); // $ sensitive=private sink(info.ssn.data); // $ MISSING: sensitive=private sink(info.ssn.get_data()); // $ MISSING: sensitive=private - sink(info.birthday.as_str()); // $ MISSING: sensitive=private - sink(info.emergency_contact.as_str()); // $ MISSING: sensitive=private - sink(info.name_of_employer.as_str()); // $ MISSING: sensitive=private + sink(info.birthday.as_str()); // $ sensitive=private + sink(info.emergency_contact.as_str()); // $ sensitive=private + sink(info.name_of_employer.as_str()); // $ sensitive=private sink(&info.gender); // $ MISSING: sensitive=private sink(info.genderString.as_str()); // $ MISSING: sensitive=private @@ -270,22 +270,22 @@ fn test_private_info( sink(info.linkedPatientId); // $ MISSING: sensitive=private sink(info.patient_record.as_str()); // $ MISSING: sensitive=private sink(info.patient_record.trim()); // $ MISSING: sensitive=private - sink(&info.medical_notes); // $ MISSING: sensitive=private - sink(info.medical_notes[0].as_str()); // $ MISSING: sensitive=private + sink(&info.medical_notes); // $ sensitive=private + sink(info.medical_notes[0].as_str()); // $ sensitive=private for n in info.medical_notes.iter() { sink(n.as_str()); // $ MISSING: sensitive=private } sink(info.confidentialMessage.as_str()); // $ MISSING: sensitive=private sink(info.confidentialMessage.to_lowercase()); // $ MISSING: sensitive=private - sink(info.latitude); // $ MISSING: sensitive=private + sink(info.latitude); // $ sensitive=private let x = info.longitude.unwrap(); sink(x); // $ MISSING: sensitive=private - sink(info.financials.my_bank_account_number.as_str()); // $ MISSING: sensitive=private - sink(info.financials.credit_card_no.as_str()); // $ MISSING: sensitive=private - sink(info.financials.credit_rating); // $ MISSING: sensitive=private - sink(info.financials.user_ccn.as_str()); // $ MISSING: sensitive=private + sink(info.financials.my_bank_account_number.as_str()); // $ sensitive=private SPURIOUS: sensitive=id + sink(info.financials.credit_card_no.as_str()); // $ sensitive=private + sink(info.financials.credit_rating); // $ sensitive=private + sink(info.financials.user_ccn.as_str()); // $ sensitive=private sink(info.financials.cvv.as_str()); // $ MISSING: sensitive=private sink(info.financials.beneficiary.as_str()); // $ MISSING: sensitive=private sink(info.financials.routing_number); // $ MISSING: sensitive=private @@ -306,10 +306,10 @@ fn test_private_info( sink(modulesEx); sink(info.financials.harmless.as_str()); - sink(info.financials.num_accounts); - sink(info.financials.total_accounts); - sink(info.financials.accounting); - sink(info.financials.unaccounted); + sink(info.financials.num_accounts); // $ SPURIOUS: sensitive=id + sink(info.financials.total_accounts); // $ SPURIOUS: sensitive=id + sink(info.financials.accounting); // $ SPURIOUS: sensitive=id + sink(info.financials.unaccounted); // $ SPURIOUS: sensitive=id sink(info.financials.multiband); sink(ContactDetails::FavouriteColor("blue".to_string())); From 0f36e1d625cbd6e57f8c6060327ff76cc8331bff Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 9 May 2025 11:26:23 +0100 Subject: [PATCH 04/86] Rust: Understand sensitive qualifier expressions. --- rust/ql/lib/codeql/rust/security/SensitiveData.qll | 8 +++----- rust/ql/test/library-tests/sensitivedata/test.rs | 8 ++++---- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/rust/ql/lib/codeql/rust/security/SensitiveData.qll b/rust/ql/lib/codeql/rust/security/SensitiveData.qll index 698fa83197d..5a384feabc2 100644 --- a/rust/ql/lib/codeql/rust/security/SensitiveData.qll +++ b/rust/ql/lib/codeql/rust/security/SensitiveData.qll @@ -92,11 +92,9 @@ private class SensitiveFieldAccess extends SensitiveData { SensitiveDataClassification classification; SensitiveFieldAccess() { - HeuristicNames::nameIndicatesSensitiveData(this.asExpr() - .getAstNode() - .(FieldExpr) - .getIdentifier() - .getText(), classification) + exists(FieldExpr fe | fe.getParentNode*() = this.asExpr().getAstNode() | + HeuristicNames::nameIndicatesSensitiveData(fe.getIdentifier().getText(), classification) + ) } override SensitiveDataClassification getClassification() { result = classification } diff --git a/rust/ql/test/library-tests/sensitivedata/test.rs b/rust/ql/test/library-tests/sensitivedata/test.rs index 42fb2f0693b..e1d07f16d47 100644 --- a/rust/ql/test/library-tests/sensitivedata/test.rs +++ b/rust/ql/test/library-tests/sensitivedata/test.rs @@ -251,8 +251,8 @@ fn test_private_info( sink(info.contact_e_mail_2.as_str()); // $ MISSING: sensitive=private sink(info.my_ssn.as_str()); // $ sensitive=private sink(&info.ssn); // $ sensitive=private - sink(info.ssn.data); // $ MISSING: sensitive=private - sink(info.ssn.get_data()); // $ MISSING: sensitive=private + sink(info.ssn.data); // $ sensitive=private + sink(info.ssn.get_data()); // $ sensitive=private sink(info.birthday.as_str()); // $ sensitive=private sink(info.emergency_contact.as_str()); // $ sensitive=private sink(info.name_of_employer.as_str()); // $ sensitive=private @@ -273,14 +273,14 @@ fn test_private_info( sink(&info.medical_notes); // $ sensitive=private sink(info.medical_notes[0].as_str()); // $ sensitive=private for n in info.medical_notes.iter() { - sink(n.as_str()); // $ MISSING: sensitive=private + sink(n.as_str()); // $ sensitive=private } sink(info.confidentialMessage.as_str()); // $ MISSING: sensitive=private sink(info.confidentialMessage.to_lowercase()); // $ MISSING: sensitive=private sink(info.latitude); // $ sensitive=private let x = info.longitude.unwrap(); - sink(x); // $ MISSING: sensitive=private + sink(x); // $ sensitive=private sink(info.financials.my_bank_account_number.as_str()); // $ sensitive=private SPURIOUS: sensitive=id sink(info.financials.credit_card_no.as_str()); // $ sensitive=private From 5f5d6f679a71ce695059720d39c7af196fcf9482 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 9 May 2025 11:58:51 +0100 Subject: [PATCH 05/86] Rust: Understand sensitive enum variants calls. --- .../codeql/rust/security/SensitiveData.qll | 31 +++++++++++++++++-- .../test/library-tests/sensitivedata/test.rs | 4 +-- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/rust/ql/lib/codeql/rust/security/SensitiveData.qll b/rust/ql/lib/codeql/rust/security/SensitiveData.qll index 5a384feabc2..1a7571a912e 100644 --- a/rust/ql/lib/codeql/rust/security/SensitiveData.qll +++ b/rust/ql/lib/codeql/rust/security/SensitiveData.qll @@ -37,10 +37,10 @@ private class SensitiveDataFunction extends Function { /** * A function call data flow node that might produce sensitive data. */ -private class SensitiveDataCall extends SensitiveData { +private class SensitiveDataFunctionCall extends SensitiveData { SensitiveDataClassification classification; - SensitiveDataCall() { + SensitiveDataFunctionCall() { classification = this.asExpr() .getAstNode() @@ -53,6 +53,33 @@ private class SensitiveDataCall extends SensitiveData { override SensitiveDataClassification getClassification() { result = classification } } +/** + * An enum variant that might produce sensitive data. + */ +private class SensitiveDataVariant extends Variant { + SensitiveDataClassification classification; + + SensitiveDataVariant() { + HeuristicNames::nameIndicatesSensitiveData(this.getName().getText(), classification) + } + + SensitiveDataClassification getClassification() { result = classification } +} + +/** + * An enum variant call data flow node that might produce sensitive data. + */ +private class SensitiveDataVariantCall extends SensitiveData { + SensitiveDataClassification classification; + + SensitiveDataVariantCall() { + classification = + this.asExpr().getAstNode().(CallExpr).getVariant().(SensitiveDataVariant).getClassification() + } + + override SensitiveDataClassification getClassification() { result = classification } +} + /** * A variable that might contain sensitive data. */ diff --git a/rust/ql/test/library-tests/sensitivedata/test.rs b/rust/ql/test/library-tests/sensitivedata/test.rs index e1d07f16d47..c4f4a57b8de 100644 --- a/rust/ql/test/library-tests/sensitivedata/test.rs +++ b/rust/ql/test/library-tests/sensitivedata/test.rs @@ -293,8 +293,8 @@ fn test_private_info( sink(info.financials.iban.as_str()); // $ MISSING: sensitive=private sink(info.financials.iBAN.as_str()); // $ MISSING: sensitive=private - sink(ContactDetails::HomePhoneNumber("123".to_string())); // $ MISSING: sensitive=private - sink(ContactDetails::MobileNumber("123".to_string())); // $ MISSING: sensitive=private + sink(ContactDetails::HomePhoneNumber("123".to_string())); // $ sensitive=private + sink(ContactDetails::MobileNumber("123".to_string())); // $ sensitive=private sink(ContactDetails::Email("a@b".to_string())); // $ MISSING: sensitive=private if let ContactDetails::MobileNumber(num) = details { sink(num.as_str()); // $ MISSING: sensitive=private From d02d5c5baf435e73b9bc7fada768631831ec6cba Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 9 May 2025 14:33:26 +0100 Subject: [PATCH 06/86] Rust: Update cleartext logging test with new found results. --- .../security/CWE-312/CleartextLogging.expected | 8 ++++++++ rust/ql/test/query-tests/security/CWE-312/test_logging.rs | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected index 61218e9c908..19efc0e1971 100644 --- a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected +++ b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected @@ -28,6 +28,8 @@ | test_logging.rs:100:5:100:19 | ...::log | test_logging.rs:99:38:99:45 | password | test_logging.rs:100:5:100:19 | ...::log | This operation writes $@ to a log file. | test_logging.rs:99:38:99:45 | password | password | | test_logging.rs:118:5:118:42 | ...::log | test_logging.rs:118:28:118:41 | get_password(...) | test_logging.rs:118:5:118:42 | ...::log | This operation writes $@ to a log file. | test_logging.rs:118:28:118:41 | get_password(...) | get_password(...) | | test_logging.rs:131:5:131:32 | ...::log | test_logging.rs:129:25:129:32 | password | test_logging.rs:131:5:131:32 | ...::log | This operation writes $@ to a log file. | test_logging.rs:129:25:129:32 | password | password | +| test_logging.rs:138:5:138:38 | ...::log | test_logging.rs:138:11:138:37 | MacroExpr | test_logging.rs:138:5:138:38 | ...::log | This operation writes $@ to a log file. | test_logging.rs:138:11:138:37 | MacroExpr | MacroExpr | +| test_logging.rs:145:5:145:38 | ...::log | test_logging.rs:145:11:145:37 | MacroExpr | test_logging.rs:145:5:145:38 | ...::log | This operation writes $@ to a log file. | test_logging.rs:145:11:145:37 | MacroExpr | MacroExpr | | test_logging.rs:152:5:152:38 | ...::_print | test_logging.rs:152:30:152:37 | password | test_logging.rs:152:5:152:38 | ...::_print | This operation writes $@ to a log file. | test_logging.rs:152:30:152:37 | password | password | | test_logging.rs:153:5:153:38 | ...::_print | test_logging.rs:153:30:153:37 | password | test_logging.rs:153:5:153:38 | ...::_print | This operation writes $@ to a log file. | test_logging.rs:153:30:153:37 | password | password | | test_logging.rs:154:5:154:39 | ...::_eprint | test_logging.rs:154:31:154:38 | password | test_logging.rs:154:5:154:39 | ...::_eprint | This operation writes $@ to a log file. | test_logging.rs:154:31:154:38 | password | password | @@ -148,6 +150,8 @@ edges | test_logging.rs:131:12:131:31 | MacroExpr | test_logging.rs:131:5:131:32 | ...::log | provenance | MaD:9 Sink:MaD:9 | | test_logging.rs:131:28:131:29 | t1 [tuple.1] | test_logging.rs:131:28:131:31 | t1.1 | provenance | | | test_logging.rs:131:28:131:31 | t1.1 | test_logging.rs:131:12:131:31 | MacroExpr | provenance | | +| test_logging.rs:138:11:138:37 | MacroExpr | test_logging.rs:138:5:138:38 | ...::log | provenance | MaD:9 Sink:MaD:9 | +| test_logging.rs:145:11:145:37 | MacroExpr | test_logging.rs:145:5:145:38 | ...::log | provenance | MaD:9 Sink:MaD:9 | | test_logging.rs:152:12:152:37 | MacroExpr | test_logging.rs:152:5:152:38 | ...::_print | provenance | MaD:8 Sink:MaD:8 | | test_logging.rs:152:30:152:37 | password | test_logging.rs:152:12:152:37 | MacroExpr | provenance | | | test_logging.rs:153:14:153:37 | MacroExpr | test_logging.rs:153:5:153:38 | ...::_print | provenance | MaD:8 Sink:MaD:8 | @@ -352,6 +356,10 @@ nodes | test_logging.rs:131:12:131:31 | MacroExpr | semmle.label | MacroExpr | | test_logging.rs:131:28:131:29 | t1 [tuple.1] | semmle.label | t1 [tuple.1] | | test_logging.rs:131:28:131:31 | t1.1 | semmle.label | t1.1 | +| test_logging.rs:138:5:138:38 | ...::log | semmle.label | ...::log | +| test_logging.rs:138:11:138:37 | MacroExpr | semmle.label | MacroExpr | +| test_logging.rs:145:5:145:38 | ...::log | semmle.label | ...::log | +| test_logging.rs:145:11:145:37 | MacroExpr | semmle.label | MacroExpr | | test_logging.rs:152:5:152:38 | ...::_print | semmle.label | ...::_print | | test_logging.rs:152:12:152:37 | MacroExpr | semmle.label | MacroExpr | | test_logging.rs:152:30:152:37 | password | semmle.label | password | diff --git a/rust/ql/test/query-tests/security/CWE-312/test_logging.rs b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs index 970a9caf0ee..8606d2f9b22 100644 --- a/rust/ql/test/query-tests/security/CWE-312/test_logging.rs +++ b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs @@ -135,14 +135,14 @@ fn test_log(harmless: String, password: String, encrypted_password: String) { // logging from a struct let s1 = MyStruct1 { harmless: "foo".to_string(), password: "123456".to_string() }; // $ MISSING: Source=s1 warn!("message = {}", s1.harmless); - warn!("message = {}", s1.password); // $ MISSING: Alert[rust/cleartext-logging] + warn!("message = {}", s1.password); // $ Alert[rust/cleartext-logging] warn!("message = {}", s1); // $ MISSING: Alert[rust/cleartext-logging]=s1 warn!("message = {:?}", s1); // $ MISSING: Alert[rust/cleartext-logging]=s1 warn!("message = {:#?}", s1); // $ MISSING: Alert[rust/cleartext-logging]=s1 let s2 = MyStruct2 { harmless: "foo".to_string(), password: "123456".to_string() }; // $ MISSING: Source=s2 warn!("message = {}", s2.harmless); - warn!("message = {}", s2.password); // $ MISSING: Alert[rust/cleartext-logging] + warn!("message = {}", s2.password); // $ Alert[rust/cleartext-logging] warn!("message = {}", s2); // (this implementation does not output the password field) warn!("message = {:?}", s2); // $ MISSING: Alert[rust/cleartext-logging]=s2 warn!("message = {:#?}", s2); // $ MISSING: Alert[rust/cleartext-logging]=s2 From 0a3275e0b3fb80ac50cbb4b89934bd37387fdec1 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 12 May 2025 11:50:57 +0100 Subject: [PATCH 07/86] Rust: One more test case. --- rust/ql/test/library-tests/sensitivedata/test.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rust/ql/test/library-tests/sensitivedata/test.rs b/rust/ql/test/library-tests/sensitivedata/test.rs index c4f4a57b8de..02ac0bdfff3 100644 --- a/rust/ql/test/library-tests/sensitivedata/test.rs +++ b/rust/ql/test/library-tests/sensitivedata/test.rs @@ -26,6 +26,7 @@ fn test_passwords( password: &str, pass_word: &str, passwd: &str, my_password: &str, password_str: &str, pass_phrase: &str, passphrase: &str, passPhrase: &str, backup_code: &str, auth_key: &str, authkey: &str, authKey: &str, authentication_key: &str, authenticationkey: &str, authenticationKey: &str, oauth: &str, + one_time_code: &str, harmless: &str, encrypted_password: &str, password_hash: &str, passwordFile: &str, ms: &MyStruct ) { @@ -48,6 +49,7 @@ fn test_passwords( sink(authenticationkey); // $ sensitive=password sink(authenticationKey); // $ sensitive=password sink(oauth); // $ MISSING: sensitive=password + sink(one_time_code); // $ MISSING: sensitive=password sink(ms); // $ MISSING: sensitive=password sink(ms.password.as_str()); // $ sensitive=password From b907cfe468de58cd90c46d66c19e9f2fe8862bcb Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 12 May 2025 12:30:50 +0100 Subject: [PATCH 08/86] Rust: Add a few more test cases involving 'map'. --- .../test/library-tests/sensitivedata/test.rs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/rust/ql/test/library-tests/sensitivedata/test.rs b/rust/ql/test/library-tests/sensitivedata/test.rs index 02ac0bdfff3..f74de9f5bf8 100644 --- a/rust/ql/test/library-tests/sensitivedata/test.rs +++ b/rust/ql/test/library-tests/sensitivedata/test.rs @@ -242,6 +242,10 @@ enum ContactDetails { FavouriteColor(String), } +struct ContactDetails2 { + home_phone_number: String, +} + fn test_private_info( info: &MyPrivateInfo, details: &ContactDetails, ) { @@ -298,9 +302,34 @@ fn test_private_info( sink(ContactDetails::HomePhoneNumber("123".to_string())); // $ sensitive=private sink(ContactDetails::MobileNumber("123".to_string())); // $ sensitive=private sink(ContactDetails::Email("a@b".to_string())); // $ MISSING: sensitive=private + + let numbers = [1, 2, 3]; + if let ContactDetails::MobileNumber(num) = details { sink(num.as_str()); // $ MISSING: sensitive=private } + let contacts = numbers.map(|number| + { + let contact = ContactDetails::MobileNumber(number.to_string()); + sink(&contact); // $ sensitive=private + contact + } + ); + sink(&contacts[0]); // $ MISSING: sensitive=private + if let ContactDetails::HomePhoneNumber(num) = &contacts[0] { + sink(num.as_str()); // $ MISSING: sensitive=private + } + + let contacts2 = numbers.map(|number| + { + let contact = ContactDetails2 { + home_phone_number: number.to_string(), + }; + sink(&contact.home_phone_number); // $ sensitive=private + contact + } + ); + sink(&contacts2[0].home_phone_number); // $ sensitive=private // not private info From ac5ec06736b002cca4fd1ad271188d2d1128d640 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 12 May 2025 12:47:31 +0100 Subject: [PATCH 09/86] Rust: Constrain SensitiveFieldAccess to avoid including unwanted parents. --- rust/ql/lib/codeql/rust/security/SensitiveData.qll | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rust/ql/lib/codeql/rust/security/SensitiveData.qll b/rust/ql/lib/codeql/rust/security/SensitiveData.qll index 1a7571a912e..43282ed7d93 100644 --- a/rust/ql/lib/codeql/rust/security/SensitiveData.qll +++ b/rust/ql/lib/codeql/rust/security/SensitiveData.qll @@ -112,6 +112,10 @@ private class SensitiveVariableAccess extends SensitiveData { override SensitiveDataClassification getClassification() { result = classification } } +Expr fieldExprParentField(FieldExpr fe) { + result = fe.getParentNode() +} + /** * A field access data flow node that might be sensitive data. */ @@ -119,7 +123,7 @@ private class SensitiveFieldAccess extends SensitiveData { SensitiveDataClassification classification; SensitiveFieldAccess() { - exists(FieldExpr fe | fe.getParentNode*() = this.asExpr().getAstNode() | + exists(FieldExpr fe | fieldExprParentField*(fe) = this.asExpr().getAstNode() | HeuristicNames::nameIndicatesSensitiveData(fe.getIdentifier().getText(), classification) ) } From 682f59fc11a1374ca0fd5fc3b7c3e0c50a0f9324 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 12 May 2025 12:49:58 +0100 Subject: [PATCH 10/86] Rust: Make helper predicate private + autoformat. --- rust/ql/lib/codeql/rust/security/SensitiveData.qll | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/rust/ql/lib/codeql/rust/security/SensitiveData.qll b/rust/ql/lib/codeql/rust/security/SensitiveData.qll index 43282ed7d93..3dcc48a799a 100644 --- a/rust/ql/lib/codeql/rust/security/SensitiveData.qll +++ b/rust/ql/lib/codeql/rust/security/SensitiveData.qll @@ -112,9 +112,7 @@ private class SensitiveVariableAccess extends SensitiveData { override SensitiveDataClassification getClassification() { result = classification } } -Expr fieldExprParentField(FieldExpr fe) { - result = fe.getParentNode() -} +private Expr fieldExprParentField(FieldExpr fe) { result = fe.getParentNode() } /** * A field access data flow node that might be sensitive data. From f04d6fd8c827d585dfc4e543193e86b6240bb635 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 12 May 2025 17:45:00 +0100 Subject: [PATCH 11/86] Rust: Accept minor test changes for the cleartext logging query. --- .../security/CWE-312/CleartextLogging.expected | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected index 19efc0e1971..dc304a699e5 100644 --- a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected +++ b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected @@ -28,8 +28,8 @@ | test_logging.rs:100:5:100:19 | ...::log | test_logging.rs:99:38:99:45 | password | test_logging.rs:100:5:100:19 | ...::log | This operation writes $@ to a log file. | test_logging.rs:99:38:99:45 | password | password | | test_logging.rs:118:5:118:42 | ...::log | test_logging.rs:118:28:118:41 | get_password(...) | test_logging.rs:118:5:118:42 | ...::log | This operation writes $@ to a log file. | test_logging.rs:118:28:118:41 | get_password(...) | get_password(...) | | test_logging.rs:131:5:131:32 | ...::log | test_logging.rs:129:25:129:32 | password | test_logging.rs:131:5:131:32 | ...::log | This operation writes $@ to a log file. | test_logging.rs:129:25:129:32 | password | password | -| test_logging.rs:138:5:138:38 | ...::log | test_logging.rs:138:11:138:37 | MacroExpr | test_logging.rs:138:5:138:38 | ...::log | This operation writes $@ to a log file. | test_logging.rs:138:11:138:37 | MacroExpr | MacroExpr | -| test_logging.rs:145:5:145:38 | ...::log | test_logging.rs:145:11:145:37 | MacroExpr | test_logging.rs:145:5:145:38 | ...::log | This operation writes $@ to a log file. | test_logging.rs:145:11:145:37 | MacroExpr | MacroExpr | +| test_logging.rs:138:5:138:38 | ...::log | test_logging.rs:138:27:138:37 | s1.password | test_logging.rs:138:5:138:38 | ...::log | This operation writes $@ to a log file. | test_logging.rs:138:27:138:37 | s1.password | s1.password | +| test_logging.rs:145:5:145:38 | ...::log | test_logging.rs:145:27:145:37 | s2.password | test_logging.rs:145:5:145:38 | ...::log | This operation writes $@ to a log file. | test_logging.rs:145:27:145:37 | s2.password | s2.password | | test_logging.rs:152:5:152:38 | ...::_print | test_logging.rs:152:30:152:37 | password | test_logging.rs:152:5:152:38 | ...::_print | This operation writes $@ to a log file. | test_logging.rs:152:30:152:37 | password | password | | test_logging.rs:153:5:153:38 | ...::_print | test_logging.rs:153:30:153:37 | password | test_logging.rs:153:5:153:38 | ...::_print | This operation writes $@ to a log file. | test_logging.rs:153:30:153:37 | password | password | | test_logging.rs:154:5:154:39 | ...::_eprint | test_logging.rs:154:31:154:38 | password | test_logging.rs:154:5:154:39 | ...::_eprint | This operation writes $@ to a log file. | test_logging.rs:154:31:154:38 | password | password | @@ -151,7 +151,9 @@ edges | test_logging.rs:131:28:131:29 | t1 [tuple.1] | test_logging.rs:131:28:131:31 | t1.1 | provenance | | | test_logging.rs:131:28:131:31 | t1.1 | test_logging.rs:131:12:131:31 | MacroExpr | provenance | | | test_logging.rs:138:11:138:37 | MacroExpr | test_logging.rs:138:5:138:38 | ...::log | provenance | MaD:9 Sink:MaD:9 | +| test_logging.rs:138:27:138:37 | s1.password | test_logging.rs:138:11:138:37 | MacroExpr | provenance | | | test_logging.rs:145:11:145:37 | MacroExpr | test_logging.rs:145:5:145:38 | ...::log | provenance | MaD:9 Sink:MaD:9 | +| test_logging.rs:145:27:145:37 | s2.password | test_logging.rs:145:11:145:37 | MacroExpr | provenance | | | test_logging.rs:152:12:152:37 | MacroExpr | test_logging.rs:152:5:152:38 | ...::_print | provenance | MaD:8 Sink:MaD:8 | | test_logging.rs:152:30:152:37 | password | test_logging.rs:152:12:152:37 | MacroExpr | provenance | | | test_logging.rs:153:14:153:37 | MacroExpr | test_logging.rs:153:5:153:38 | ...::_print | provenance | MaD:8 Sink:MaD:8 | @@ -358,8 +360,10 @@ nodes | test_logging.rs:131:28:131:31 | t1.1 | semmle.label | t1.1 | | test_logging.rs:138:5:138:38 | ...::log | semmle.label | ...::log | | test_logging.rs:138:11:138:37 | MacroExpr | semmle.label | MacroExpr | +| test_logging.rs:138:27:138:37 | s1.password | semmle.label | s1.password | | test_logging.rs:145:5:145:38 | ...::log | semmle.label | ...::log | | test_logging.rs:145:11:145:37 | MacroExpr | semmle.label | MacroExpr | +| test_logging.rs:145:27:145:37 | s2.password | semmle.label | s2.password | | test_logging.rs:152:5:152:38 | ...::_print | semmle.label | ...::_print | | test_logging.rs:152:12:152:37 | MacroExpr | semmle.label | MacroExpr | | test_logging.rs:152:30:152:37 | password | semmle.label | password | From 4bbdc9a1cddd9bbabb5013357a12714471184e27 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 19 May 2025 12:08:53 +0100 Subject: [PATCH 12/86] Rust: Simplify SensitiveData.qll. --- .../codeql/rust/security/SensitiveData.qll | 82 ++++--------------- 1 file changed, 15 insertions(+), 67 deletions(-) diff --git a/rust/ql/lib/codeql/rust/security/SensitiveData.qll b/rust/ql/lib/codeql/rust/security/SensitiveData.qll index 3dcc48a799a..703a5099317 100644 --- a/rust/ql/lib/codeql/rust/security/SensitiveData.qll +++ b/rust/ql/lib/codeql/rust/security/SensitiveData.qll @@ -22,77 +22,26 @@ abstract class SensitiveData extends DataFlow::Node { } /** - * A function that might produce sensitive data. + * A function call or enum variant data flow node that might produce sensitive data. */ -private class SensitiveDataFunction extends Function { +private class SensitiveDataCall extends SensitiveData { SensitiveDataClassification classification; - SensitiveDataFunction() { - HeuristicNames::nameIndicatesSensitiveData(this.getName().getText(), classification) - } - - SensitiveDataClassification getClassification() { result = classification } -} - -/** - * A function call data flow node that might produce sensitive data. - */ -private class SensitiveDataFunctionCall extends SensitiveData { - SensitiveDataClassification classification; - - SensitiveDataFunctionCall() { - classification = - this.asExpr() - .getAstNode() - .(CallExprBase) - .getStaticTarget() - .(SensitiveDataFunction) - .getClassification() + SensitiveDataCall() { + exists(CallExprBase call, string name | + call = this.asExpr().getExpr() and + name = + [ + call.getStaticTarget().(Function).getName().getText(), + call.(CallExpr).getVariant().getName().getText(), + ] and + HeuristicNames::nameIndicatesSensitiveData(name, classification) + ) } override SensitiveDataClassification getClassification() { result = classification } } -/** - * An enum variant that might produce sensitive data. - */ -private class SensitiveDataVariant extends Variant { - SensitiveDataClassification classification; - - SensitiveDataVariant() { - HeuristicNames::nameIndicatesSensitiveData(this.getName().getText(), classification) - } - - SensitiveDataClassification getClassification() { result = classification } -} - -/** - * An enum variant call data flow node that might produce sensitive data. - */ -private class SensitiveDataVariantCall extends SensitiveData { - SensitiveDataClassification classification; - - SensitiveDataVariantCall() { - classification = - this.asExpr().getAstNode().(CallExpr).getVariant().(SensitiveDataVariant).getClassification() - } - - override SensitiveDataClassification getClassification() { result = classification } -} - -/** - * A variable that might contain sensitive data. - */ -private class SensitiveDataVariable extends Variable { - SensitiveDataClassification classification; - - SensitiveDataVariable() { - HeuristicNames::nameIndicatesSensitiveData(this.getText(), classification) - } - - SensitiveDataClassification getClassification() { result = classification } -} - /** * A variable access data flow node that might be sensitive data. */ @@ -100,13 +49,12 @@ private class SensitiveVariableAccess extends SensitiveData { SensitiveDataClassification classification; SensitiveVariableAccess() { - classification = - this.asExpr() + HeuristicNames::nameIndicatesSensitiveData(this.asExpr() .getAstNode() .(VariableAccess) .getVariable() - .(SensitiveDataVariable) - .getClassification() + .(Variable) + .getText(), classification) } override SensitiveDataClassification getClassification() { result = classification } From b503b1ef6ccae745b728267da585dc0559333bb5 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 19 May 2025 12:09:27 +0100 Subject: [PATCH 13/86] Rust: Prefer getExpr() over getAstNode(). --- rust/ql/lib/codeql/rust/security/SensitiveData.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/ql/lib/codeql/rust/security/SensitiveData.qll b/rust/ql/lib/codeql/rust/security/SensitiveData.qll index 703a5099317..bf3364abdb6 100644 --- a/rust/ql/lib/codeql/rust/security/SensitiveData.qll +++ b/rust/ql/lib/codeql/rust/security/SensitiveData.qll @@ -50,7 +50,7 @@ private class SensitiveVariableAccess extends SensitiveData { SensitiveVariableAccess() { HeuristicNames::nameIndicatesSensitiveData(this.asExpr() - .getAstNode() + .getExpr() .(VariableAccess) .getVariable() .(Variable) @@ -69,7 +69,7 @@ private class SensitiveFieldAccess extends SensitiveData { SensitiveDataClassification classification; SensitiveFieldAccess() { - exists(FieldExpr fe | fieldExprParentField*(fe) = this.asExpr().getAstNode() | + exists(FieldExpr fe | fieldExprParentField*(fe) = this.asExpr().getExpr() | HeuristicNames::nameIndicatesSensitiveData(fe.getIdentifier().getText(), classification) ) } From 533aa7fc268a2ac7c51ed0d27d59b617e2945b7a Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 16 May 2025 18:34:33 +0100 Subject: [PATCH 14/86] Rust: Add tests for std::Pin. --- .../dataflow/modeled/inline-flow.expected | 16 ++++++ .../library-tests/dataflow/modeled/main.rs | 55 +++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/rust/ql/test/library-tests/dataflow/modeled/inline-flow.expected b/rust/ql/test/library-tests/dataflow/modeled/inline-flow.expected index b7afe9dae35..b8d2136fcc0 100644 --- a/rust/ql/test/library-tests/dataflow/modeled/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/modeled/inline-flow.expected @@ -55,6 +55,12 @@ edges | main.rs:84:29:84:29 | [post] y [&ref] | main.rs:85:33:85:33 | y [&ref] | provenance | | | main.rs:84:32:84:41 | source(...) | main.rs:84:29:84:29 | [post] y [&ref] | provenance | MaD:7 | | main.rs:85:33:85:33 | y [&ref] | main.rs:85:18:85:34 | ...::read(...) | provenance | MaD:6 | +| main.rs:100:13:100:17 | mut i | main.rs:105:14:105:14 | i | provenance | | +| main.rs:100:21:100:30 | source(...) | main.rs:100:13:100:17 | mut i | provenance | | +| main.rs:114:13:114:18 | mut ms [MyStruct] | main.rs:119:14:119:15 | ms [MyStruct] | provenance | | +| main.rs:114:22:114:49 | MyStruct {...} [MyStruct] | main.rs:114:13:114:18 | mut ms [MyStruct] | provenance | | +| main.rs:114:38:114:47 | source(...) | main.rs:114:22:114:49 | MyStruct {...} [MyStruct] | provenance | | +| main.rs:119:14:119:15 | ms [MyStruct] | main.rs:119:14:119:19 | ms.val | provenance | | nodes | main.rs:12:9:12:9 | a [Some] | semmle.label | a [Some] | | main.rs:12:13:12:28 | Some(...) [Some] | semmle.label | Some(...) [Some] | @@ -108,6 +114,14 @@ nodes | main.rs:84:32:84:41 | source(...) | semmle.label | source(...) | | main.rs:85:18:85:34 | ...::read(...) | semmle.label | ...::read(...) | | main.rs:85:33:85:33 | y [&ref] | semmle.label | y [&ref] | +| main.rs:100:13:100:17 | mut i | semmle.label | mut i | +| main.rs:100:21:100:30 | source(...) | semmle.label | source(...) | +| main.rs:105:14:105:14 | i | semmle.label | i | +| main.rs:114:13:114:18 | mut ms [MyStruct] | semmle.label | mut ms [MyStruct] | +| main.rs:114:22:114:49 | MyStruct {...} [MyStruct] | semmle.label | MyStruct {...} [MyStruct] | +| main.rs:114:38:114:47 | source(...) | semmle.label | source(...) | +| main.rs:119:14:119:15 | ms [MyStruct] | semmle.label | ms [MyStruct] | +| main.rs:119:14:119:19 | ms.val | semmle.label | ms.val | subpaths testFailures #select @@ -121,3 +135,5 @@ testFailures | main.rs:47:38:47:38 | n | main.rs:41:30:41:39 | source(...) | main.rs:47:38:47:38 | n | $@ | main.rs:41:30:41:39 | source(...) | source(...) | | main.rs:63:22:63:22 | m | main.rs:58:22:58:31 | source(...) | main.rs:63:22:63:22 | m | $@ | main.rs:58:22:58:31 | source(...) | source(...) | | main.rs:85:18:85:34 | ...::read(...) | main.rs:84:32:84:41 | source(...) | main.rs:85:18:85:34 | ...::read(...) | $@ | main.rs:84:32:84:41 | source(...) | source(...) | +| main.rs:105:14:105:14 | i | main.rs:100:21:100:30 | source(...) | main.rs:105:14:105:14 | i | $@ | main.rs:100:21:100:30 | source(...) | source(...) | +| main.rs:119:14:119:19 | ms.val | main.rs:114:38:114:47 | source(...) | main.rs:119:14:119:19 | ms.val | $@ | main.rs:114:38:114:47 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/modeled/main.rs b/rust/ql/test/library-tests/dataflow/modeled/main.rs index cb955ce32bd..ec82951affc 100644 --- a/rust/ql/test/library-tests/dataflow/modeled/main.rs +++ b/rust/ql/test/library-tests/dataflow/modeled/main.rs @@ -87,9 +87,64 @@ mod ptr { } } +use std::pin::Pin; +use std::pin::pin; + +#[derive(Clone)] +struct MyStruct { + val: i64, +} + +fn test_pin() { + { + let mut i = source(40); + let mut pin1 = Pin::new(&i); + let mut pin2 = Box::pin(i); + let mut pin3 = Box::into_pin(Box::new(i)); + let mut pin4 = pin!(i); + sink(i); // $ hasValueFlow=40 + sink(*pin1); // $ MISSING: hasValueFlow=40 + sink(*Pin::into_inner(pin1)); // $ MISSING: hasValueFlow=40 + sink(*pin2); // $ MISSING: hasValueFlow=40 + sink(*pin3); // $ MISSING: hasValueFlow=40 + sink(*pin4); // $ MISSING: hasValueFlow=40 + } + + { + let mut ms = MyStruct { val: source(41) }; + let mut pin1 = Pin::new(&ms); + let mut pin2 = Box::pin(ms.clone()); + let mut pin3 = Box::into_pin(Box::new(ms.clone())); + let mut pin4 = pin!(&ms); + sink(ms.val); // $ hasValueFlow=41 + sink(pin1.val); // $ MISSING: hasValueFlow=41 + sink(Pin::into_inner(pin1).val); // $ MISSING: hasValueFlow=41 + sink(pin2.val); // $ MISSING: hasValueFlow=41 + sink(pin3.val); // $ MISSING: hasValueFlow=41 + sink(pin4.val); // $ MISSING: hasValueFlow=41 + } + + unsafe { + let mut ms = MyStruct { val: source(42) }; + let mut pin5 = Pin::new_unchecked(&ms); + sink(pin5.val); // $ MISSING: hasValueFlow=42 + sink(Pin::into_inner_unchecked(pin5).val); // $ MISSING: hasValueFlow=40 + } + + { + let mut ms = MyStruct { val: source(43) }; + let mut ms2 = MyStruct { val: source(44) }; + let mut pin = Pin::new(&mut ms); + sink(pin.val); // $ MISSING: hasValueFlow=43 + pin.set(ms2); + sink(pin.val); // $ MISSING: hasValueFlow=44 + } +} + fn main() { option_clone(); result_clone(); i64_clone(); my_clone::wrapper_clone(); + test_pin(); } From ebd75a118b144c33c834f933e8932066e8f68f17 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 19 May 2025 17:30:06 +0100 Subject: [PATCH 15/86] Rust: Add models for std::Pin. --- .../frameworks/stdlib/lang-alloc.model.yml | 4 + .../frameworks/stdlib/lang-core.model.yml | 8 ++ .../dataflow/modeled/inline-flow.expected | 81 +++++++++++++++---- .../library-tests/dataflow/modeled/main.rs | 12 +-- 4 files changed, 83 insertions(+), 22 deletions(-) diff --git a/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-alloc.model.yml b/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-alloc.model.yml index 8d177c4e856..77c33b47b0c 100644 --- a/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-alloc.model.yml +++ b/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-alloc.model.yml @@ -29,6 +29,10 @@ extensions: pack: codeql/rust-all extensible: summaryModel data: + # Box + - ["lang:alloc", "::pin", "Argument[0]", "ReturnValue.Reference", "value", "manual"] + - ["lang:alloc", "::new", "Argument[0]", "ReturnValue.Reference", "value", "manual"] + - ["lang:alloc", "::into_pin", "Argument[0]", "ReturnValue", "value", "manual"] # Fmt - ["lang:alloc", "crate::fmt::format", "Argument[0]", "ReturnValue", "taint", "manual"] # String diff --git a/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml b/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml index 3e37ed7797b..69b2236e3ce 100644 --- a/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml +++ b/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml @@ -32,6 +32,14 @@ extensions: - ["lang:core", "::align_to", "Argument[self]", "ReturnValue.Field[crate::result::Result::Ok(0)]", "taint", "manual"] - ["lang:core", "::pad_to_align", "Argument[self]", "ReturnValue", "taint", "manual"] - ["lang:core", "::size", "Argument[self]", "ReturnValue", "taint", "manual"] + # Pin + - ["lang:core", "crate::pin::Pin", "Argument[0]", "ReturnValue", "value", "manual"] + - ["lang:core", "::new", "Argument[0]", "ReturnValue", "value", "manual"] + - ["lang:core", "::new_unchecked", "Argument[0].Reference", "ReturnValue", "value", "manual"] + - ["lang:core", "::into_inner", "Argument[0]", "ReturnValue", "value", "manual"] + - ["lang:core", "::into_inner_unchecked", "Argument[0]", "ReturnValue", "value", "manual"] + - ["lang:core", "::set", "Argument[0]", "Argument[self]", "value", "manual"] + - ["lang:core", "::into_inner", "Argument[0]", "ReturnValue", "value", "manual"] # Ptr - ["lang:core", "crate::ptr::read", "Argument[0].Reference", "ReturnValue", "value", "manual"] - ["lang:core", "crate::ptr::read_unaligned", "Argument[0].Reference", "ReturnValue", "value", "manual"] diff --git a/rust/ql/test/library-tests/dataflow/modeled/inline-flow.expected b/rust/ql/test/library-tests/dataflow/modeled/inline-flow.expected index b8d2136fcc0..d1af296044e 100644 --- a/rust/ql/test/library-tests/dataflow/modeled/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/modeled/inline-flow.expected @@ -1,32 +1,37 @@ models -| 1 | Summary: lang:core; ::clone; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue.Field[crate::option::Option::Some(0)]; value | -| 2 | Summary: lang:core; ::unwrap; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue; value | -| 3 | Summary: lang:core; ::zip; Argument[0].Field[crate::option::Option::Some(0)]; ReturnValue.Field[crate::option::Option::Some(0)].Field[1]; value | -| 4 | Summary: lang:core; ::unwrap; Argument[self].Field[crate::result::Result::Ok(0)]; ReturnValue; value | -| 5 | Summary: lang:core; ::clone; Argument[self].Reference; ReturnValue; value | -| 6 | Summary: lang:core; crate::ptr::read; Argument[0].Reference; ReturnValue; value | -| 7 | Summary: lang:core; crate::ptr::write; Argument[1]; Argument[0].Reference; value | +| 1 | Summary: lang:alloc; ::into_pin; Argument[0]; ReturnValue; value | +| 2 | Summary: lang:alloc; ::new; Argument[0]; ReturnValue.Reference; value | +| 3 | Summary: lang:alloc; ::pin; Argument[0]; ReturnValue.Reference; value | +| 4 | Summary: lang:core; ::clone; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue.Field[crate::option::Option::Some(0)]; value | +| 5 | Summary: lang:core; ::unwrap; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue; value | +| 6 | Summary: lang:core; ::zip; Argument[0].Field[crate::option::Option::Some(0)]; ReturnValue.Field[crate::option::Option::Some(0)].Field[1]; value | +| 7 | Summary: lang:core; ::into_inner; Argument[0]; ReturnValue; value | +| 8 | Summary: lang:core; ::new; Argument[0]; ReturnValue; value | +| 9 | Summary: lang:core; ::unwrap; Argument[self].Field[crate::result::Result::Ok(0)]; ReturnValue; value | +| 10 | Summary: lang:core; ::clone; Argument[self].Reference; ReturnValue; value | +| 11 | Summary: lang:core; crate::ptr::read; Argument[0].Reference; ReturnValue; value | +| 12 | Summary: lang:core; crate::ptr::write; Argument[1]; Argument[0].Reference; value | edges -| main.rs:12:9:12:9 | a [Some] | main.rs:13:10:13:19 | a.unwrap() | provenance | MaD:2 | +| main.rs:12:9:12:9 | a [Some] | main.rs:13:10:13:19 | a.unwrap() | provenance | MaD:5 | | main.rs:12:9:12:9 | a [Some] | main.rs:14:13:14:13 | a [Some] | provenance | | -| main.rs:12:9:12:9 | a [Some] | main.rs:14:13:14:21 | a.clone() [Some] | provenance | MaD:1 | +| main.rs:12:9:12:9 | a [Some] | main.rs:14:13:14:21 | a.clone() [Some] | provenance | MaD:4 | | main.rs:12:13:12:28 | Some(...) [Some] | main.rs:12:9:12:9 | a [Some] | provenance | | | main.rs:12:18:12:27 | source(...) | main.rs:12:13:12:28 | Some(...) [Some] | provenance | | -| main.rs:14:9:14:9 | b [Some] | main.rs:15:10:15:19 | b.unwrap() | provenance | MaD:2 | +| main.rs:14:9:14:9 | b [Some] | main.rs:15:10:15:19 | b.unwrap() | provenance | MaD:5 | | main.rs:14:13:14:13 | a [Some] | main.rs:14:13:14:21 | a.clone() [Some] | provenance | generated | | main.rs:14:13:14:21 | a.clone() [Some] | main.rs:14:9:14:9 | b [Some] | provenance | | -| main.rs:19:9:19:9 | a [Ok] | main.rs:20:10:20:19 | a.unwrap() | provenance | MaD:4 | +| main.rs:19:9:19:9 | a [Ok] | main.rs:20:10:20:19 | a.unwrap() | provenance | MaD:9 | | main.rs:19:9:19:9 | a [Ok] | main.rs:21:13:21:13 | a [Ok] | provenance | | | main.rs:19:31:19:44 | Ok(...) [Ok] | main.rs:19:9:19:9 | a [Ok] | provenance | | | main.rs:19:34:19:43 | source(...) | main.rs:19:31:19:44 | Ok(...) [Ok] | provenance | | -| main.rs:21:9:21:9 | b [Ok] | main.rs:22:10:22:19 | b.unwrap() | provenance | MaD:4 | +| main.rs:21:9:21:9 | b [Ok] | main.rs:22:10:22:19 | b.unwrap() | provenance | MaD:9 | | main.rs:21:13:21:13 | a [Ok] | main.rs:21:13:21:21 | a.clone() [Ok] | provenance | generated | | main.rs:21:13:21:21 | a.clone() [Ok] | main.rs:21:9:21:9 | b [Ok] | provenance | | | main.rs:26:9:26:9 | a | main.rs:27:10:27:10 | a | provenance | | | main.rs:26:9:26:9 | a | main.rs:28:13:28:13 | a | provenance | | | main.rs:26:13:26:22 | source(...) | main.rs:26:9:26:9 | a | provenance | | | main.rs:28:9:28:9 | b | main.rs:29:10:29:10 | b | provenance | | -| main.rs:28:13:28:13 | a | main.rs:28:13:28:21 | a.clone() | provenance | MaD:5 | +| main.rs:28:13:28:13 | a | main.rs:28:13:28:21 | a.clone() | provenance | MaD:10 | | main.rs:28:13:28:13 | a | main.rs:28:13:28:21 | a.clone() | provenance | generated | | main.rs:28:13:28:21 | a.clone() | main.rs:28:9:28:9 | b | provenance | | | main.rs:41:13:41:13 | w [Wrapper] | main.rs:42:15:42:15 | w [Wrapper] | provenance | | @@ -47,16 +52,36 @@ edges | main.rs:58:22:58:31 | source(...) | main.rs:58:17:58:32 | Some(...) [Some] | provenance | | | main.rs:59:13:59:13 | z [Some, tuple.1] | main.rs:60:15:60:15 | z [Some, tuple.1] | provenance | | | main.rs:59:17:59:24 | a.zip(...) [Some, tuple.1] | main.rs:59:13:59:13 | z [Some, tuple.1] | provenance | | -| main.rs:59:23:59:23 | b [Some] | main.rs:59:17:59:24 | a.zip(...) [Some, tuple.1] | provenance | MaD:3 | +| main.rs:59:23:59:23 | b [Some] | main.rs:59:17:59:24 | a.zip(...) [Some, tuple.1] | provenance | MaD:6 | | main.rs:60:15:60:15 | z [Some, tuple.1] | main.rs:61:13:61:24 | Some(...) [Some, tuple.1] | provenance | | | main.rs:61:13:61:24 | Some(...) [Some, tuple.1] | main.rs:61:18:61:23 | TuplePat [tuple.1] | provenance | | | main.rs:61:18:61:23 | TuplePat [tuple.1] | main.rs:61:22:61:22 | m | provenance | | | main.rs:61:22:61:22 | m | main.rs:63:22:63:22 | m | provenance | | | main.rs:84:29:84:29 | [post] y [&ref] | main.rs:85:33:85:33 | y [&ref] | provenance | | -| main.rs:84:32:84:41 | source(...) | main.rs:84:29:84:29 | [post] y [&ref] | provenance | MaD:7 | -| main.rs:85:33:85:33 | y [&ref] | main.rs:85:18:85:34 | ...::read(...) | provenance | MaD:6 | +| main.rs:84:32:84:41 | source(...) | main.rs:84:29:84:29 | [post] y [&ref] | provenance | MaD:12 | +| main.rs:85:33:85:33 | y [&ref] | main.rs:85:18:85:34 | ...::read(...) | provenance | MaD:11 | +| main.rs:100:13:100:17 | mut i | main.rs:101:34:101:34 | i | provenance | | +| main.rs:100:13:100:17 | mut i | main.rs:102:33:102:33 | i | provenance | | +| main.rs:100:13:100:17 | mut i | main.rs:103:47:103:47 | i | provenance | | | main.rs:100:13:100:17 | mut i | main.rs:105:14:105:14 | i | provenance | | | main.rs:100:21:100:30 | source(...) | main.rs:100:13:100:17 | mut i | provenance | | +| main.rs:101:13:101:20 | mut pin1 [&ref] | main.rs:106:15:106:18 | pin1 [&ref] | provenance | | +| main.rs:101:13:101:20 | mut pin1 [&ref] | main.rs:107:31:107:34 | pin1 [&ref] | provenance | | +| main.rs:101:24:101:35 | ...::new(...) [&ref] | main.rs:101:13:101:20 | mut pin1 [&ref] | provenance | | +| main.rs:101:33:101:34 | &i [&ref] | main.rs:101:24:101:35 | ...::new(...) [&ref] | provenance | MaD:8 | +| main.rs:101:34:101:34 | i | main.rs:101:33:101:34 | &i [&ref] | provenance | | +| main.rs:102:13:102:20 | mut pin2 [&ref] | main.rs:108:15:108:18 | pin2 [&ref] | provenance | | +| main.rs:102:24:102:34 | ...::pin(...) [&ref] | main.rs:102:13:102:20 | mut pin2 [&ref] | provenance | | +| main.rs:102:33:102:33 | i | main.rs:102:24:102:34 | ...::pin(...) [&ref] | provenance | MaD:3 | +| main.rs:103:13:103:20 | mut pin3 [&ref] | main.rs:109:15:109:18 | pin3 [&ref] | provenance | | +| main.rs:103:24:103:49 | ...::into_pin(...) [&ref] | main.rs:103:13:103:20 | mut pin3 [&ref] | provenance | | +| main.rs:103:38:103:48 | ...::new(...) [&ref] | main.rs:103:24:103:49 | ...::into_pin(...) [&ref] | provenance | MaD:1 | +| main.rs:103:47:103:47 | i | main.rs:103:38:103:48 | ...::new(...) [&ref] | provenance | MaD:2 | +| main.rs:106:15:106:18 | pin1 [&ref] | main.rs:106:14:106:18 | * ... | provenance | | +| main.rs:107:15:107:35 | ...::into_inner(...) [&ref] | main.rs:107:14:107:35 | * ... | provenance | | +| main.rs:107:31:107:34 | pin1 [&ref] | main.rs:107:15:107:35 | ...::into_inner(...) [&ref] | provenance | MaD:7 | +| main.rs:108:15:108:18 | pin2 [&ref] | main.rs:108:14:108:18 | * ... | provenance | | +| main.rs:109:15:109:18 | pin3 [&ref] | main.rs:109:14:109:18 | * ... | provenance | | | main.rs:114:13:114:18 | mut ms [MyStruct] | main.rs:119:14:119:15 | ms [MyStruct] | provenance | | | main.rs:114:22:114:49 | MyStruct {...} [MyStruct] | main.rs:114:13:114:18 | mut ms [MyStruct] | provenance | | | main.rs:114:38:114:47 | source(...) | main.rs:114:22:114:49 | MyStruct {...} [MyStruct] | provenance | | @@ -116,7 +141,27 @@ nodes | main.rs:85:33:85:33 | y [&ref] | semmle.label | y [&ref] | | main.rs:100:13:100:17 | mut i | semmle.label | mut i | | main.rs:100:21:100:30 | source(...) | semmle.label | source(...) | +| main.rs:101:13:101:20 | mut pin1 [&ref] | semmle.label | mut pin1 [&ref] | +| main.rs:101:24:101:35 | ...::new(...) [&ref] | semmle.label | ...::new(...) [&ref] | +| main.rs:101:33:101:34 | &i [&ref] | semmle.label | &i [&ref] | +| main.rs:101:34:101:34 | i | semmle.label | i | +| main.rs:102:13:102:20 | mut pin2 [&ref] | semmle.label | mut pin2 [&ref] | +| main.rs:102:24:102:34 | ...::pin(...) [&ref] | semmle.label | ...::pin(...) [&ref] | +| main.rs:102:33:102:33 | i | semmle.label | i | +| main.rs:103:13:103:20 | mut pin3 [&ref] | semmle.label | mut pin3 [&ref] | +| main.rs:103:24:103:49 | ...::into_pin(...) [&ref] | semmle.label | ...::into_pin(...) [&ref] | +| main.rs:103:38:103:48 | ...::new(...) [&ref] | semmle.label | ...::new(...) [&ref] | +| main.rs:103:47:103:47 | i | semmle.label | i | | main.rs:105:14:105:14 | i | semmle.label | i | +| main.rs:106:14:106:18 | * ... | semmle.label | * ... | +| main.rs:106:15:106:18 | pin1 [&ref] | semmle.label | pin1 [&ref] | +| main.rs:107:14:107:35 | * ... | semmle.label | * ... | +| main.rs:107:15:107:35 | ...::into_inner(...) [&ref] | semmle.label | ...::into_inner(...) [&ref] | +| main.rs:107:31:107:34 | pin1 [&ref] | semmle.label | pin1 [&ref] | +| main.rs:108:14:108:18 | * ... | semmle.label | * ... | +| main.rs:108:15:108:18 | pin2 [&ref] | semmle.label | pin2 [&ref] | +| main.rs:109:14:109:18 | * ... | semmle.label | * ... | +| main.rs:109:15:109:18 | pin3 [&ref] | semmle.label | pin3 [&ref] | | main.rs:114:13:114:18 | mut ms [MyStruct] | semmle.label | mut ms [MyStruct] | | main.rs:114:22:114:49 | MyStruct {...} [MyStruct] | semmle.label | MyStruct {...} [MyStruct] | | main.rs:114:38:114:47 | source(...) | semmle.label | source(...) | @@ -136,4 +181,8 @@ testFailures | main.rs:63:22:63:22 | m | main.rs:58:22:58:31 | source(...) | main.rs:63:22:63:22 | m | $@ | main.rs:58:22:58:31 | source(...) | source(...) | | main.rs:85:18:85:34 | ...::read(...) | main.rs:84:32:84:41 | source(...) | main.rs:85:18:85:34 | ...::read(...) | $@ | main.rs:84:32:84:41 | source(...) | source(...) | | main.rs:105:14:105:14 | i | main.rs:100:21:100:30 | source(...) | main.rs:105:14:105:14 | i | $@ | main.rs:100:21:100:30 | source(...) | source(...) | +| main.rs:106:14:106:18 | * ... | main.rs:100:21:100:30 | source(...) | main.rs:106:14:106:18 | * ... | $@ | main.rs:100:21:100:30 | source(...) | source(...) | +| main.rs:107:14:107:35 | * ... | main.rs:100:21:100:30 | source(...) | main.rs:107:14:107:35 | * ... | $@ | main.rs:100:21:100:30 | source(...) | source(...) | +| main.rs:108:14:108:18 | * ... | main.rs:100:21:100:30 | source(...) | main.rs:108:14:108:18 | * ... | $@ | main.rs:100:21:100:30 | source(...) | source(...) | +| main.rs:109:14:109:18 | * ... | main.rs:100:21:100:30 | source(...) | main.rs:109:14:109:18 | * ... | $@ | main.rs:100:21:100:30 | source(...) | source(...) | | main.rs:119:14:119:19 | ms.val | main.rs:114:38:114:47 | source(...) | main.rs:119:14:119:19 | ms.val | $@ | main.rs:114:38:114:47 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/modeled/main.rs b/rust/ql/test/library-tests/dataflow/modeled/main.rs index ec82951affc..440f3bfd7ee 100644 --- a/rust/ql/test/library-tests/dataflow/modeled/main.rs +++ b/rust/ql/test/library-tests/dataflow/modeled/main.rs @@ -102,11 +102,11 @@ fn test_pin() { let mut pin2 = Box::pin(i); let mut pin3 = Box::into_pin(Box::new(i)); let mut pin4 = pin!(i); - sink(i); // $ hasValueFlow=40 - sink(*pin1); // $ MISSING: hasValueFlow=40 - sink(*Pin::into_inner(pin1)); // $ MISSING: hasValueFlow=40 - sink(*pin2); // $ MISSING: hasValueFlow=40 - sink(*pin3); // $ MISSING: hasValueFlow=40 + sink(i); // $ hasValueFlow=40 + sink(*pin1); // $ hasValueFlow=40 + sink(*Pin::into_inner(pin1)); // $ hasValueFlow=40 + sink(*pin2); // $ hasValueFlow=40 + sink(*pin3); // $ hasValueFlow=40 sink(*pin4); // $ MISSING: hasValueFlow=40 } @@ -116,7 +116,7 @@ fn test_pin() { let mut pin2 = Box::pin(ms.clone()); let mut pin3 = Box::into_pin(Box::new(ms.clone())); let mut pin4 = pin!(&ms); - sink(ms.val); // $ hasValueFlow=41 + sink(ms.val); // $ hasValueFlow=41 sink(pin1.val); // $ MISSING: hasValueFlow=41 sink(Pin::into_inner(pin1).val); // $ MISSING: hasValueFlow=41 sink(pin2.val); // $ MISSING: hasValueFlow=41 From 94b57ac9a984f22f2994451ce4a3ff216088ec35 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 19 May 2025 21:49:02 +0100 Subject: [PATCH 16/86] Update rust/ql/test/library-tests/dataflow/modeled/main.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- rust/ql/test/library-tests/dataflow/modeled/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/test/library-tests/dataflow/modeled/main.rs b/rust/ql/test/library-tests/dataflow/modeled/main.rs index 440f3bfd7ee..b3044336669 100644 --- a/rust/ql/test/library-tests/dataflow/modeled/main.rs +++ b/rust/ql/test/library-tests/dataflow/modeled/main.rs @@ -128,7 +128,7 @@ fn test_pin() { let mut ms = MyStruct { val: source(42) }; let mut pin5 = Pin::new_unchecked(&ms); sink(pin5.val); // $ MISSING: hasValueFlow=42 - sink(Pin::into_inner_unchecked(pin5).val); // $ MISSING: hasValueFlow=40 + sink(Pin::into_inner_unchecked(pin5).val); // $ MISSING: hasValueFlow=42 } { From f6f6a5ccc6027bf04d30c1fe32a7dc4d16072504 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 20 May 2025 02:11:05 +0100 Subject: [PATCH 17/86] Only list type params in test files This will make the test results not depend on the version of the standard library being used, which means we don't have to update it with each new release. --- .../semmle/go/Function/TypeParamType.expected | 206 ------------------ .../semmle/go/Function/TypeParamType.ql | 6 +- 2 files changed, 5 insertions(+), 207 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/Function/TypeParamType.expected b/go/ql/test/library-tests/semmle/go/Function/TypeParamType.expected index 27a0d5171de..bda7c151797 100644 --- a/go/ql/test/library-tests/semmle/go/Function/TypeParamType.expected +++ b/go/ql/test/library-tests/semmle/go/Function/TypeParamType.expected @@ -20,10 +20,6 @@ numberOfTypeParameters | genericFunctions.go:152:6:152:36 | multipleAnonymousTypeParamsType | 3 | | genericFunctions.go:154:51:154:51 | f | 3 | #select -| cmp.Compare | 0 | T | Ordered | -| cmp.Less | 0 | T | Ordered | -| cmp.Or | 0 | T | comparable | -| cmp.isNaN | 0 | T | Ordered | | codeql-go-tests/function.EdgeConstraint | 0 | Node | interface { } | | codeql-go-tests/function.Element | 0 | S | interface { } | | codeql-go-tests/function.GenericFunctionInAnotherFile | 0 | T | interface { } | @@ -57,205 +53,3 @@ numberOfTypeParameters | codeql-go-tests/function.multipleAnonymousTypeParamsType.f | 0 | _ | interface { } | | codeql-go-tests/function.multipleAnonymousTypeParamsType.f | 1 | _ | interface { string } | | codeql-go-tests/function.multipleAnonymousTypeParamsType.f | 2 | _ | interface { } | -| github.com/anotherpkg.GenericFunctionInAnotherPackage | 0 | T | interface { } | -| internal/abi.Escape | 0 | T | interface { } | -| internal/bytealg.HashStr | 0 | T | interface { string \| []uint8 } | -| internal/bytealg.HashStrRev | 0 | T | interface { string \| []uint8 } | -| internal/bytealg.IndexRabinKarp | 0 | T | interface { string \| []uint8 } | -| internal/bytealg.LastIndexRabinKarp | 0 | T | interface { string \| []uint8 } | -| internal/poll.ignoringEINTR2 | 0 | T | interface { } | -| internal/runtime/atomic.Pointer.CompareAndSwap | 0 | T | interface { } | -| internal/runtime/atomic.Pointer.CompareAndSwapNoWB | 0 | T | interface { } | -| internal/runtime/atomic.Pointer.Load | 0 | T | interface { } | -| internal/runtime/atomic.Pointer.Store | 0 | T | interface { } | -| internal/runtime/atomic.Pointer.StoreNoWB | 0 | T | interface { } | -| internal/sync.HashTrieMap.All | 0 | K | comparable | -| internal/sync.HashTrieMap.All | 1 | V | interface { } | -| internal/sync.HashTrieMap.CompareAndDelete | 0 | K | comparable | -| internal/sync.HashTrieMap.CompareAndDelete | 1 | V | interface { } | -| internal/sync.HashTrieMap.CompareAndSwap | 0 | K | comparable | -| internal/sync.HashTrieMap.CompareAndSwap | 1 | V | interface { } | -| internal/sync.HashTrieMap.Delete | 0 | K | comparable | -| internal/sync.HashTrieMap.Load | 0 | K | comparable | -| internal/sync.HashTrieMap.Load | 1 | V | interface { } | -| internal/sync.HashTrieMap.LoadAndDelete | 0 | K | comparable | -| internal/sync.HashTrieMap.LoadAndDelete | 1 | V | interface { } | -| internal/sync.HashTrieMap.LoadOrStore | 0 | K | comparable | -| internal/sync.HashTrieMap.LoadOrStore | 1 | V | interface { } | -| internal/sync.HashTrieMap.Range | 0 | K | comparable | -| internal/sync.HashTrieMap.Range | 1 | V | interface { } | -| internal/sync.HashTrieMap.Store | 0 | K | comparable | -| internal/sync.HashTrieMap.Store | 1 | V | interface { } | -| internal/sync.HashTrieMap.Swap | 0 | K | comparable | -| internal/sync.HashTrieMap.Swap | 1 | V | interface { } | -| internal/sync.HashTrieMap.find | 0 | K | comparable | -| internal/sync.HashTrieMap.find | 1 | V | interface { } | -| internal/sync.HashTrieMap.iter | 0 | K | comparable | -| internal/sync.HashTrieMap.iter | 1 | V | interface { } | -| internal/sync.entry | 0 | K | comparable | -| internal/sync.entry | 1 | V | interface { } | -| internal/sync.entry.compareAndDelete | 0 | K | comparable | -| internal/sync.entry.compareAndDelete | 1 | V | interface { } | -| internal/sync.entry.compareAndSwap | 0 | K | comparable | -| internal/sync.entry.compareAndSwap | 1 | V | interface { } | -| internal/sync.entry.loadAndDelete | 0 | K | comparable | -| internal/sync.entry.loadAndDelete | 1 | V | interface { } | -| internal/sync.entry.lookup | 0 | K | comparable | -| internal/sync.entry.lookup | 1 | V | interface { } | -| internal/sync.entry.lookupWithValue | 0 | K | comparable | -| internal/sync.entry.lookupWithValue | 1 | V | interface { } | -| internal/sync.entry.swap | 0 | K | comparable | -| internal/sync.entry.swap | 1 | V | interface { } | -| internal/sync.newEntryNode | 0 | K | comparable | -| internal/sync.newEntryNode | 1 | V | interface { } | -| iter.Pull | 0 | V | interface { } | -| iter.Pull2 | 0 | K | interface { } | -| iter.Pull2 | 1 | V | interface { } | -| iter.Seq | 0 | V | interface { } | -| iter.Seq2 | 0 | K | interface { } | -| iter.Seq2 | 1 | V | interface { } | -| os.doInRoot | 0 | T | interface { } | -| os.ignoringEINTR2 | 0 | T | interface { } | -| reflect.rangeNum | 1 | N | interface { int64 \| uint64 } | -| runtime.AddCleanup | 0 | T | interface { } | -| runtime.AddCleanup | 1 | S | interface { } | -| runtime.fandbits | 0 | F | floaty | -| runtime.fmax | 0 | F | floaty | -| runtime.fmin | 0 | F | floaty | -| runtime.forbits | 0 | F | floaty | -| runtime.noEscapePtr | 0 | T | interface { } | -| slices.All | 0 | Slice | interface { ~[]E } | -| slices.All | 1 | E | interface { } | -| slices.AppendSeq | 0 | Slice | interface { ~[]E } | -| slices.AppendSeq | 1 | E | interface { } | -| slices.Backward | 0 | Slice | interface { ~[]E } | -| slices.Backward | 1 | E | interface { } | -| slices.BinarySearch | 0 | S | interface { ~[]E } | -| slices.BinarySearch | 1 | E | Ordered | -| slices.BinarySearchFunc | 0 | S | interface { ~[]E } | -| slices.BinarySearchFunc | 1 | E | interface { } | -| slices.BinarySearchFunc | 2 | T | interface { } | -| slices.Chunk | 0 | Slice | interface { ~[]E } | -| slices.Chunk | 1 | E | interface { } | -| slices.Clip | 0 | S | interface { ~[]E } | -| slices.Clip | 1 | E | interface { } | -| slices.Clone | 0 | S | interface { ~[]E } | -| slices.Clone | 1 | E | interface { } | -| slices.Collect | 0 | E | interface { } | -| slices.Compact | 0 | S | interface { ~[]E } | -| slices.Compact | 1 | E | comparable | -| slices.CompactFunc | 0 | S | interface { ~[]E } | -| slices.CompactFunc | 1 | E | interface { } | -| slices.Compare | 0 | S | interface { ~[]E } | -| slices.Compare | 1 | E | Ordered | -| slices.CompareFunc | 0 | S1 | interface { ~[]E1 } | -| slices.CompareFunc | 1 | S2 | interface { ~[]E2 } | -| slices.CompareFunc | 2 | E1 | interface { } | -| slices.CompareFunc | 3 | E2 | interface { } | -| slices.Concat | 0 | S | interface { ~[]E } | -| slices.Concat | 1 | E | interface { } | -| slices.Contains | 0 | S | interface { ~[]E } | -| slices.Contains | 1 | E | comparable | -| slices.ContainsFunc | 0 | S | interface { ~[]E } | -| slices.ContainsFunc | 1 | E | interface { } | -| slices.Delete | 0 | S | interface { ~[]E } | -| slices.Delete | 1 | E | interface { } | -| slices.DeleteFunc | 0 | S | interface { ~[]E } | -| slices.DeleteFunc | 1 | E | interface { } | -| slices.Equal | 0 | S | interface { ~[]E } | -| slices.Equal | 1 | E | comparable | -| slices.EqualFunc | 0 | S1 | interface { ~[]E1 } | -| slices.EqualFunc | 1 | S2 | interface { ~[]E2 } | -| slices.EqualFunc | 2 | E1 | interface { } | -| slices.EqualFunc | 3 | E2 | interface { } | -| slices.Grow | 0 | S | interface { ~[]E } | -| slices.Grow | 1 | E | interface { } | -| slices.Index | 0 | S | interface { ~[]E } | -| slices.Index | 1 | E | comparable | -| slices.IndexFunc | 0 | S | interface { ~[]E } | -| slices.IndexFunc | 1 | E | interface { } | -| slices.Insert | 0 | S | interface { ~[]E } | -| slices.Insert | 1 | E | interface { } | -| slices.IsSorted | 0 | S | interface { ~[]E } | -| slices.IsSorted | 1 | E | Ordered | -| slices.IsSortedFunc | 0 | S | interface { ~[]E } | -| slices.IsSortedFunc | 1 | E | interface { } | -| slices.Max | 0 | S | interface { ~[]E } | -| slices.Max | 1 | E | Ordered | -| slices.MaxFunc | 0 | S | interface { ~[]E } | -| slices.MaxFunc | 1 | E | interface { } | -| slices.Min | 0 | S | interface { ~[]E } | -| slices.Min | 1 | E | Ordered | -| slices.MinFunc | 0 | S | interface { ~[]E } | -| slices.MinFunc | 1 | E | interface { } | -| slices.Repeat | 0 | S | interface { ~[]E } | -| slices.Repeat | 1 | E | interface { } | -| slices.Replace | 0 | S | interface { ~[]E } | -| slices.Replace | 1 | E | interface { } | -| slices.Reverse | 0 | S | interface { ~[]E } | -| slices.Reverse | 1 | E | interface { } | -| slices.Sort | 0 | S | interface { ~[]E } | -| slices.Sort | 1 | E | Ordered | -| slices.SortFunc | 0 | S | interface { ~[]E } | -| slices.SortFunc | 1 | E | interface { } | -| slices.SortStableFunc | 0 | S | interface { ~[]E } | -| slices.SortStableFunc | 1 | E | interface { } | -| slices.Sorted | 0 | E | Ordered | -| slices.SortedFunc | 0 | E | interface { } | -| slices.SortedStableFunc | 0 | E | interface { } | -| slices.Values | 0 | Slice | interface { ~[]E } | -| slices.Values | 1 | E | interface { } | -| slices.breakPatternsCmpFunc | 0 | E | interface { } | -| slices.breakPatternsOrdered | 0 | E | Ordered | -| slices.choosePivotCmpFunc | 0 | E | interface { } | -| slices.choosePivotOrdered | 0 | E | Ordered | -| slices.heapSortCmpFunc | 0 | E | interface { } | -| slices.heapSortOrdered | 0 | E | Ordered | -| slices.insertionSortCmpFunc | 0 | E | interface { } | -| slices.insertionSortOrdered | 0 | E | Ordered | -| slices.isNaN | 0 | T | Ordered | -| slices.medianAdjacentCmpFunc | 0 | E | interface { } | -| slices.medianAdjacentOrdered | 0 | E | Ordered | -| slices.medianCmpFunc | 0 | E | interface { } | -| slices.medianOrdered | 0 | E | Ordered | -| slices.order2CmpFunc | 0 | E | interface { } | -| slices.order2Ordered | 0 | E | Ordered | -| slices.overlaps | 0 | E | interface { } | -| slices.partialInsertionSortCmpFunc | 0 | E | interface { } | -| slices.partialInsertionSortOrdered | 0 | E | Ordered | -| slices.partitionCmpFunc | 0 | E | interface { } | -| slices.partitionEqualCmpFunc | 0 | E | interface { } | -| slices.partitionEqualOrdered | 0 | E | Ordered | -| slices.partitionOrdered | 0 | E | Ordered | -| slices.pdqsortCmpFunc | 0 | E | interface { } | -| slices.pdqsortOrdered | 0 | E | Ordered | -| slices.reverseRangeCmpFunc | 0 | E | interface { } | -| slices.reverseRangeOrdered | 0 | E | Ordered | -| slices.rotateCmpFunc | 0 | E | interface { } | -| slices.rotateLeft | 0 | E | interface { } | -| slices.rotateOrdered | 0 | E | Ordered | -| slices.rotateRight | 0 | E | interface { } | -| slices.siftDownCmpFunc | 0 | E | interface { } | -| slices.siftDownOrdered | 0 | E | Ordered | -| slices.stableCmpFunc | 0 | E | interface { } | -| slices.stableOrdered | 0 | E | Ordered | -| slices.startIdx | 0 | E | interface { } | -| slices.swapRangeCmpFunc | 0 | E | interface { } | -| slices.swapRangeOrdered | 0 | E | Ordered | -| slices.symMergeCmpFunc | 0 | E | interface { } | -| slices.symMergeOrdered | 0 | E | Ordered | -| strconv.bsearch | 0 | S | interface { ~[]E } | -| strconv.bsearch | 1 | E | interface { ~uint16 \| ~uint32 } | -| sync.OnceValue | 0 | T | interface { } | -| sync.OnceValues | 0 | T1 | interface { } | -| sync.OnceValues | 1 | T2 | interface { } | -| sync/atomic.Pointer | 0 | T | interface { } | -| sync/atomic.Pointer.CompareAndSwap | 0 | T | interface { } | -| sync/atomic.Pointer.Load | 0 | T | interface { } | -| sync/atomic.Pointer.Store | 0 | T | interface { } | -| sync/atomic.Pointer.Swap | 0 | T | interface { } | -| time.atoi | 0 | bytes | interface { []uint8 \| string } | -| time.isDigit | 0 | bytes | interface { []uint8 \| string } | -| time.leadingInt | 0 | bytes | interface { []uint8 \| string } | -| time.parseNanoseconds | 0 | bytes | interface { []uint8 \| string } | -| time.parseRFC3339 | 0 | bytes | interface { []uint8 \| string } | diff --git a/go/ql/test/library-tests/semmle/go/Function/TypeParamType.ql b/go/ql/test/library-tests/semmle/go/Function/TypeParamType.ql index 202a437d6a0..02dec23d2a8 100644 --- a/go/ql/test/library-tests/semmle/go/Function/TypeParamType.ql +++ b/go/ql/test/library-tests/semmle/go/Function/TypeParamType.ql @@ -6,5 +6,9 @@ query predicate numberOfTypeParameters(TypeParamParentEntity parent, int n) { } from TypeParamType tpt, TypeParamParentEntity ty -where ty = tpt.getParent() +where + ty = tpt.getParent() and + // Note that we cannot use the location of `tpt` itself as we currently fail + // to extract an object for type parameters for methods on generic structs. + exists(ty.getLocation()) select ty.getQualifiedName(), tpt.getIndex(), tpt.getParamName(), tpt.getConstraint().pp() From bfb15cd88f8f3cf463efbbc58ee6fc54fbfdb853 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 20 May 2025 11:07:06 +0100 Subject: [PATCH 18/86] Rust: Accept changes to other tests. --- .../dataflow/local/DataFlowStep.expected | 3 + .../dataflow/local/inline-flow.expected | 55 +++++++++++-------- .../test/library-tests/dataflow/local/main.rs | 2 +- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index 98a2634346e..95ec1685202 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -1167,6 +1167,8 @@ storeStep | file://:0:0:0:0 | [summary] to write: ReturnValue.Reference in lang:alloc::_::::allocator | &ref | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::allocator | | file://:0:0:0:0 | [summary] to write: ReturnValue.Reference in lang:alloc::_::::as_mut_ptr | &ref | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::as_mut_ptr | | file://:0:0:0:0 | [summary] to write: ReturnValue.Reference in lang:alloc::_::::as_ptr | &ref | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::as_ptr | +| file://:0:0:0:0 | [summary] to write: ReturnValue.Reference in lang:alloc::_::::new | &ref | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::new | +| file://:0:0:0:0 | [summary] to write: ReturnValue.Reference in lang:alloc::_::::pin | &ref | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::pin | | file://:0:0:0:0 | [summary] to write: ReturnValue.Reference in lang:alloc::_::::borrow | &ref | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::borrow | | file://:0:0:0:0 | [summary] to write: ReturnValue.Reference in lang:alloc::_::::borrow_mut | &ref | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::borrow_mut | | file://:0:0:0:0 | [summary] to write: ReturnValue.Reference in lang:alloc::_::::as_mut | &ref | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::as_mut | @@ -1367,6 +1369,7 @@ readStep | file://:0:0:0:0 | [summary param] 0 in lang:core::_::::unwrap_or_else | function return | file://:0:0:0:0 | [summary] read: Argument[0].ReturnValue in lang:core::_::::unwrap_or_else | | file://:0:0:0:0 | [summary param] 0 in lang:core::_::::zip | Some | file://:0:0:0:0 | [summary] read: Argument[0].Field[crate::option::Option::Some(0)] in lang:core::_::::zip | | file://:0:0:0:0 | [summary param] 0 in lang:core::_::::zip_with | Some | file://:0:0:0:0 | [summary] read: Argument[0].Field[crate::option::Option::Some(0)] in lang:core::_::::zip_with | +| file://:0:0:0:0 | [summary param] 0 in lang:core::_::::new_unchecked | &ref | file://:0:0:0:0 | [summary] read: Argument[0].Reference in lang:core::_::::new_unchecked | | file://:0:0:0:0 | [summary param] 0 in lang:core::_::::is_err_and | function return | file://:0:0:0:0 | [summary] read: Argument[0].ReturnValue in lang:core::_::::is_err_and | | file://:0:0:0:0 | [summary param] 0 in lang:core::_::::is_ok_and | function return | file://:0:0:0:0 | [summary] read: Argument[0].ReturnValue in lang:core::_::::is_ok_and | | file://:0:0:0:0 | [summary param] 0 in lang:core::_::::map | function return | file://:0:0:0:0 | [summary] read: Argument[0].ReturnValue in lang:core::_::::map | diff --git a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected index 80469e0b399..cf3fd262c65 100644 --- a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected @@ -1,14 +1,15 @@ models -| 1 | Summary: lang:core; <_ as crate::convert::From>::from; Argument[0]; ReturnValue; value | -| 2 | Summary: lang:core; ::unwrap; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue; value | -| 3 | Summary: lang:core; ::unwrap_or; Argument[0]; ReturnValue; value | -| 4 | Summary: lang:core; ::unwrap_or; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue; value | -| 5 | Summary: lang:core; ::unwrap_or_else; Argument[0].ReturnValue; ReturnValue; value | -| 6 | Summary: lang:core; ::unwrap_or_else; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue; value | -| 7 | Summary: lang:core; ::err; Argument[self].Field[crate::result::Result::Err(0)]; ReturnValue.Field[crate::option::Option::Some(0)]; value | -| 8 | Summary: lang:core; ::expect; Argument[self].Field[crate::result::Result::Ok(0)]; ReturnValue; value | -| 9 | Summary: lang:core; ::expect_err; Argument[self].Field[crate::result::Result::Err(0)]; ReturnValue; value | -| 10 | Summary: lang:core; ::ok; Argument[self].Field[crate::result::Result::Ok(0)]; ReturnValue.Field[crate::option::Option::Some(0)]; value | +| 1 | Summary: lang:alloc; ::new; Argument[0]; ReturnValue.Reference; value | +| 2 | Summary: lang:core; <_ as crate::convert::From>::from; Argument[0]; ReturnValue; value | +| 3 | Summary: lang:core; ::unwrap; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue; value | +| 4 | Summary: lang:core; ::unwrap_or; Argument[0]; ReturnValue; value | +| 5 | Summary: lang:core; ::unwrap_or; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue; value | +| 6 | Summary: lang:core; ::unwrap_or_else; Argument[0].ReturnValue; ReturnValue; value | +| 7 | Summary: lang:core; ::unwrap_or_else; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue; value | +| 8 | Summary: lang:core; ::err; Argument[self].Field[crate::result::Result::Err(0)]; ReturnValue.Field[crate::option::Option::Some(0)]; value | +| 9 | Summary: lang:core; ::expect; Argument[self].Field[crate::result::Result::Ok(0)]; ReturnValue; value | +| 10 | Summary: lang:core; ::expect_err; Argument[self].Field[crate::result::Result::Err(0)]; ReturnValue; value | +| 11 | Summary: lang:core; ::ok; Argument[self].Field[crate::result::Result::Ok(0)]; ReturnValue.Field[crate::option::Option::Some(0)]; value | edges | main.rs:22:9:22:9 | s | main.rs:23:10:23:10 | s | provenance | | | main.rs:22:13:22:21 | source(...) | main.rs:22:9:22:9 | s | provenance | | @@ -22,6 +23,10 @@ edges | main.rs:48:15:48:23 | source(...) | main.rs:47:9:47:9 | b | provenance | | | main.rs:56:5:56:5 | i | main.rs:57:10:57:10 | i | provenance | | | main.rs:56:9:56:17 | source(...) | main.rs:56:5:56:5 | i | provenance | | +| main.rs:89:9:89:9 | i [&ref] | main.rs:90:11:90:11 | i [&ref] | provenance | | +| main.rs:89:13:89:31 | ...::new(...) [&ref] | main.rs:89:9:89:9 | i [&ref] | provenance | | +| main.rs:89:22:89:30 | source(...) | main.rs:89:13:89:31 | ...::new(...) [&ref] | provenance | MaD:1 | +| main.rs:90:11:90:11 | i [&ref] | main.rs:90:10:90:11 | * ... | provenance | | | main.rs:97:9:97:9 | a [tuple.0] | main.rs:98:10:98:10 | a [tuple.0] | provenance | | | main.rs:97:13:97:26 | TupleExpr [tuple.0] | main.rs:97:9:97:9 | a [tuple.0] | provenance | | | main.rs:97:14:97:22 | source(...) | main.rs:97:13:97:26 | TupleExpr [tuple.0] | provenance | | @@ -95,32 +100,32 @@ edges | main.rs:229:11:229:12 | s1 [Some] | main.rs:230:9:230:15 | Some(...) [Some] | provenance | | | main.rs:230:9:230:15 | Some(...) [Some] | main.rs:230:14:230:14 | n | provenance | | | main.rs:230:14:230:14 | n | main.rs:230:25:230:25 | n | provenance | | -| main.rs:240:9:240:10 | s1 [Some] | main.rs:241:10:241:20 | s1.unwrap() | provenance | MaD:2 | +| main.rs:240:9:240:10 | s1 [Some] | main.rs:241:10:241:20 | s1.unwrap() | provenance | MaD:3 | | main.rs:240:14:240:29 | Some(...) [Some] | main.rs:240:9:240:10 | s1 [Some] | provenance | | | main.rs:240:19:240:28 | source(...) | main.rs:240:14:240:29 | Some(...) [Some] | provenance | | -| main.rs:245:9:245:10 | s1 [Some] | main.rs:246:10:246:24 | s1.unwrap_or(...) | provenance | MaD:4 | +| main.rs:245:9:245:10 | s1 [Some] | main.rs:246:10:246:24 | s1.unwrap_or(...) | provenance | MaD:5 | | main.rs:245:14:245:29 | Some(...) [Some] | main.rs:245:9:245:10 | s1 [Some] | provenance | | | main.rs:245:19:245:28 | source(...) | main.rs:245:14:245:29 | Some(...) [Some] | provenance | | -| main.rs:249:23:249:32 | source(...) | main.rs:249:10:249:33 | s2.unwrap_or(...) | provenance | MaD:3 | -| main.rs:253:9:253:10 | s1 [Some] | main.rs:254:10:254:32 | s1.unwrap_or_else(...) | provenance | MaD:6 | +| main.rs:249:23:249:32 | source(...) | main.rs:249:10:249:33 | s2.unwrap_or(...) | provenance | MaD:4 | +| main.rs:253:9:253:10 | s1 [Some] | main.rs:254:10:254:32 | s1.unwrap_or_else(...) | provenance | MaD:7 | | main.rs:253:14:253:29 | Some(...) [Some] | main.rs:253:9:253:10 | s1 [Some] | provenance | | | main.rs:253:19:253:28 | source(...) | main.rs:253:14:253:29 | Some(...) [Some] | provenance | | -| main.rs:257:31:257:40 | source(...) | main.rs:257:10:257:41 | s2.unwrap_or_else(...) | provenance | MaD:5 | +| main.rs:257:31:257:40 | source(...) | main.rs:257:10:257:41 | s2.unwrap_or_else(...) | provenance | MaD:6 | | main.rs:261:9:261:10 | s1 [Some] | main.rs:263:14:263:15 | s1 [Some] | provenance | | | main.rs:261:14:261:29 | Some(...) [Some] | main.rs:261:9:261:10 | s1 [Some] | provenance | | | main.rs:261:19:261:28 | source(...) | main.rs:261:14:261:29 | Some(...) [Some] | provenance | | | main.rs:263:9:263:10 | i1 | main.rs:264:10:264:11 | i1 | provenance | | | main.rs:263:14:263:15 | s1 [Some] | main.rs:263:14:263:16 | TryExpr | provenance | | | main.rs:263:14:263:16 | TryExpr | main.rs:263:9:263:10 | i1 | provenance | | -| main.rs:270:9:270:10 | r1 [Ok] | main.rs:271:29:271:35 | r1.ok() [Some] | provenance | MaD:10 | +| main.rs:270:9:270:10 | r1 [Ok] | main.rs:271:29:271:35 | r1.ok() [Some] | provenance | MaD:11 | | main.rs:270:33:270:46 | Ok(...) [Ok] | main.rs:270:9:270:10 | r1 [Ok] | provenance | | | main.rs:270:36:270:45 | source(...) | main.rs:270:33:270:46 | Ok(...) [Ok] | provenance | | -| main.rs:271:9:271:11 | o1a [Some] | main.rs:273:10:273:21 | o1a.unwrap() | provenance | MaD:2 | +| main.rs:271:9:271:11 | o1a [Some] | main.rs:273:10:273:21 | o1a.unwrap() | provenance | MaD:3 | | main.rs:271:29:271:35 | r1.ok() [Some] | main.rs:271:9:271:11 | o1a [Some] | provenance | | -| main.rs:276:9:276:10 | r2 [Err] | main.rs:278:29:278:36 | r2.err() [Some] | provenance | MaD:7 | +| main.rs:276:9:276:10 | r2 [Err] | main.rs:278:29:278:36 | r2.err() [Some] | provenance | MaD:8 | | main.rs:276:33:276:47 | Err(...) [Err] | main.rs:276:9:276:10 | r2 [Err] | provenance | | | main.rs:276:37:276:46 | source(...) | main.rs:276:33:276:47 | Err(...) [Err] | provenance | | -| main.rs:278:9:278:11 | o2b [Some] | main.rs:280:10:280:21 | o2b.unwrap() | provenance | MaD:2 | +| main.rs:278:9:278:11 | o2b [Some] | main.rs:280:10:280:21 | o2b.unwrap() | provenance | MaD:3 | | main.rs:278:29:278:36 | r2.err() [Some] | main.rs:278:9:278:11 | o2b [Some] | provenance | | | main.rs:284:9:284:10 | s1 [Ok] | main.rs:287:14:287:15 | s1 [Ok] | provenance | | | main.rs:284:32:284:45 | Ok(...) [Ok] | main.rs:284:9:284:10 | s1 [Ok] | provenance | | @@ -128,10 +133,10 @@ edges | main.rs:287:9:287:10 | i1 | main.rs:289:10:289:11 | i1 | provenance | | | main.rs:287:14:287:15 | s1 [Ok] | main.rs:287:14:287:16 | TryExpr | provenance | | | main.rs:287:14:287:16 | TryExpr | main.rs:287:9:287:10 | i1 | provenance | | -| main.rs:297:9:297:10 | s1 [Ok] | main.rs:298:10:298:22 | s1.expect(...) | provenance | MaD:8 | +| main.rs:297:9:297:10 | s1 [Ok] | main.rs:298:10:298:22 | s1.expect(...) | provenance | MaD:9 | | main.rs:297:32:297:45 | Ok(...) [Ok] | main.rs:297:9:297:10 | s1 [Ok] | provenance | | | main.rs:297:35:297:44 | source(...) | main.rs:297:32:297:45 | Ok(...) [Ok] | provenance | | -| main.rs:301:9:301:10 | s2 [Err] | main.rs:303:10:303:26 | s2.expect_err(...) | provenance | MaD:9 | +| main.rs:301:9:301:10 | s2 [Err] | main.rs:303:10:303:26 | s2.expect_err(...) | provenance | MaD:10 | | main.rs:301:32:301:46 | Err(...) [Err] | main.rs:301:9:301:10 | s2 [Err] | provenance | | | main.rs:301:36:301:45 | source(...) | main.rs:301:32:301:46 | Err(...) [Err] | provenance | | | main.rs:312:9:312:10 | s1 [A] | main.rs:314:11:314:12 | s1 [A] | provenance | | @@ -233,7 +238,7 @@ edges | main.rs:524:11:524:15 | c_ref [&ref] | main.rs:524:10:524:15 | * ... | provenance | | | main.rs:528:9:528:9 | a | main.rs:532:20:532:20 | a | provenance | | | main.rs:528:18:528:27 | source(...) | main.rs:528:9:528:9 | a | provenance | | -| main.rs:532:20:532:20 | a | main.rs:532:10:532:21 | ...::from(...) | provenance | MaD:1 | +| main.rs:532:20:532:20 | a | main.rs:532:10:532:21 | ...::from(...) | provenance | MaD:2 | nodes | main.rs:18:10:18:18 | source(...) | semmle.label | source(...) | | main.rs:22:9:22:9 | s | semmle.label | s | @@ -253,6 +258,11 @@ nodes | main.rs:56:5:56:5 | i | semmle.label | i | | main.rs:56:9:56:17 | source(...) | semmle.label | source(...) | | main.rs:57:10:57:10 | i | semmle.label | i | +| main.rs:89:9:89:9 | i [&ref] | semmle.label | i [&ref] | +| main.rs:89:13:89:31 | ...::new(...) [&ref] | semmle.label | ...::new(...) [&ref] | +| main.rs:89:22:89:30 | source(...) | semmle.label | source(...) | +| main.rs:90:10:90:11 | * ... | semmle.label | * ... | +| main.rs:90:11:90:11 | i [&ref] | semmle.label | i [&ref] | | main.rs:97:9:97:9 | a [tuple.0] | semmle.label | a [tuple.0] | | main.rs:97:13:97:26 | TupleExpr [tuple.0] | semmle.label | TupleExpr [tuple.0] | | main.rs:97:14:97:22 | source(...) | semmle.label | source(...) | @@ -514,6 +524,7 @@ testFailures | main.rs:39:10:39:10 | b | main.rs:34:13:34:21 | source(...) | main.rs:39:10:39:10 | b | $@ | main.rs:34:13:34:21 | source(...) | source(...) | | main.rs:50:10:50:10 | b | main.rs:48:15:48:23 | source(...) | main.rs:50:10:50:10 | b | $@ | main.rs:48:15:48:23 | source(...) | source(...) | | main.rs:57:10:57:10 | i | main.rs:56:9:56:17 | source(...) | main.rs:57:10:57:10 | i | $@ | main.rs:56:9:56:17 | source(...) | source(...) | +| main.rs:90:10:90:11 | * ... | main.rs:89:22:89:30 | source(...) | main.rs:90:10:90:11 | * ... | $@ | main.rs:89:22:89:30 | source(...) | source(...) | | main.rs:98:10:98:12 | a.0 | main.rs:97:14:97:22 | source(...) | main.rs:98:10:98:12 | a.0 | $@ | main.rs:97:14:97:22 | source(...) | source(...) | | main.rs:106:10:106:11 | a1 | main.rs:103:17:103:26 | source(...) | main.rs:106:10:106:11 | a1 | $@ | main.rs:103:17:103:26 | source(...) | source(...) | | main.rs:113:10:113:12 | a.1 | main.rs:111:21:111:30 | source(...) | main.rs:113:10:113:12 | a.1 | $@ | main.rs:111:21:111:30 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/local/main.rs b/rust/ql/test/library-tests/dataflow/local/main.rs index 1d91135a31d..4323f58c880 100644 --- a/rust/ql/test/library-tests/dataflow/local/main.rs +++ b/rust/ql/test/library-tests/dataflow/local/main.rs @@ -87,7 +87,7 @@ fn block_expression3(b: bool) -> i64 { fn box_deref() { let i = Box::new(source(7)); - sink(*i); // $ MISSING: hasValueFlow=7 + sink(*i); // $ hasValueFlow=7 } // ----------------------------------------------------------------------------- From 14af9218b20cded64daf6eaff57f11af1d2abf9f Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 14 May 2025 11:00:50 +0100 Subject: [PATCH 19/86] Check more things while running tests --- go/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/Makefile b/go/Makefile index 5bf6d70e0e6..44e943e76db 100644 --- a/go/Makefile +++ b/go/Makefile @@ -54,7 +54,7 @@ ql/lib/go.dbscheme.stats: ql/lib/go.dbscheme build/stats/src.stamp extractor codeql dataset measure -o $@ build/stats/database/db-go test: all build/testdb/check-upgrade-path - codeql test run -j0 ql/test --search-path .. --consistency-queries ql/test/consistency --compilation-cache=$(cache) --dynamic-join-order-mode=$(rtjo) + codeql test run -j0 ql/test --search-path .. --consistency-queries ql/test/consistency --compilation-cache=$(cache) --dynamic-join-order-mode=$(rtjo) --check-databases --fail-on-trap-errors --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition # use GOOS=linux because GOOS=darwin GOARCH=386 is no longer supported env GOOS=linux GOARCH=386 codeql$(EXE) test run -j0 ql/test/query-tests/Security/CWE-681 --search-path .. --consistency-queries ql/test/consistency --compilation-cache=$(cache) --dynamic-join-order-mode=$(rtjo) cd extractor; $(BAZEL) test ... From d39e7c2066eaa62dcff6657bee4632261e03ff63 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 15 May 2025 11:26:47 +0100 Subject: [PATCH 20/86] Added named import to definitions test This makes the test slightly more thorough. --- go/ql/test/query-tests/definitions/definitions.expected | 1 + go/ql/test/query-tests/definitions/greet.go | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/go/ql/test/query-tests/definitions/definitions.expected b/go/ql/test/query-tests/definitions/definitions.expected index 3c10cc9afbc..a06fb63ff39 100644 --- a/go/ql/test/query-tests/definitions/definitions.expected +++ b/go/ql/test/query-tests/definitions/definitions.expected @@ -1,3 +1,4 @@ +| greet.go:6:2:6:6 | myfmt | greet.go:3:8:3:12 | myfmt | V | | main.go:6:26:6:28 | who | main.go:5:12:5:14 | who | V | | main.go:11:2:11:6 | greet | main.go:5:6:5:10 | greet | V | | main.go:11:8:11:12 | world | main.go:10:2:10:6 | world | V | diff --git a/go/ql/test/query-tests/definitions/greet.go b/go/ql/test/query-tests/definitions/greet.go index 064e43a2ca9..4067a5896be 100644 --- a/go/ql/test/query-tests/definitions/greet.go +++ b/go/ql/test/query-tests/definitions/greet.go @@ -1,7 +1,7 @@ package main -import "fmt" +import myfmt "fmt" func greet2() { - fmt.Println("Hello world!") + myfmt.Println("Hello world!") } From 401c60654eabc92262119847e4b3bc88786f2f34 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 15 May 2025 13:40:57 +0100 Subject: [PATCH 21/86] Fix nil checks to stop creating unused labels In go, an interface with value nil does not compare equal to nil. This is known as "typed nils". So our existing nil checks weren't working, which shows why we needed more nil checks inside the type switches. The solution is to explicitly check for each type we care about. --- go/extractor/extractor.go | 147 ++++++-------------------------------- 1 file changed, 22 insertions(+), 125 deletions(-) diff --git a/go/extractor/extractor.go b/go/extractor/extractor.go index c4544390753..1456dd3a899 100644 --- a/go/extractor/extractor.go +++ b/go/extractor/extractor.go @@ -936,7 +936,16 @@ func emitScopeNodeInfo(tw *trap.Writer, nd ast.Node, lbl trap.Label) { // extractExpr extracts AST information for the given expression and all its subexpressions func extractExpr(tw *trap.Writer, expr ast.Expr, parent trap.Label, idx int, skipExtractingValue bool) { - if expr == nil { + if expr == nil || expr == (*ast.Ident)(nil) || expr == (*ast.BasicLit)(nil) || + expr == (*ast.Ellipsis)(nil) || expr == (*ast.FuncLit)(nil) || + expr == (*ast.CompositeLit)(nil) || expr == (*ast.SelectorExpr)(nil) || + expr == (*ast.IndexListExpr)(nil) || expr == (*ast.SliceExpr)(nil) || + expr == (*ast.TypeAssertExpr)(nil) || expr == (*ast.CallExpr)(nil) || + expr == (*ast.StarExpr)(nil) || expr == (*ast.KeyValueExpr)(nil) || + expr == (*ast.UnaryExpr)(nil) || expr == (*ast.BinaryExpr)(nil) || + expr == (*ast.ArrayType)(nil) || expr == (*ast.StructType)(nil) || + expr == (*ast.FuncType)(nil) || expr == (*ast.InterfaceType)(nil) || + expr == (*ast.MapType)(nil) || expr == (*ast.ChanType)(nil) { return } @@ -948,9 +957,6 @@ func extractExpr(tw *trap.Writer, expr ast.Expr, parent trap.Label, idx int, ski case *ast.BadExpr: kind = dbscheme.BadExpr.Index() case *ast.Ident: - if expr == nil { - return - } kind = dbscheme.IdentExpr.Index() dbscheme.LiteralsTable.Emit(tw, lbl, expr.Name, expr.Name) def := tw.Package.TypesInfo.Defs[expr] @@ -984,15 +990,9 @@ func extractExpr(tw *trap.Writer, expr ast.Expr, parent trap.Label, idx int, ski } } case *ast.Ellipsis: - if expr == nil { - return - } kind = dbscheme.EllipsisExpr.Index() extractExpr(tw, expr.Elt, lbl, 0, false) case *ast.BasicLit: - if expr == nil { - return - } value := "" switch expr.Kind { case token.INT: @@ -1016,36 +1016,21 @@ func extractExpr(tw *trap.Writer, expr ast.Expr, parent trap.Label, idx int, ski } dbscheme.LiteralsTable.Emit(tw, lbl, value, expr.Value) case *ast.FuncLit: - if expr == nil { - return - } kind = dbscheme.FuncLitExpr.Index() extractExpr(tw, expr.Type, lbl, 0, false) extractStmt(tw, expr.Body, lbl, 1) case *ast.CompositeLit: - if expr == nil { - return - } kind = dbscheme.CompositeLitExpr.Index() extractExpr(tw, expr.Type, lbl, 0, false) extractExprs(tw, expr.Elts, lbl, 1, 1) case *ast.ParenExpr: - if expr == nil { - return - } kind = dbscheme.ParenExpr.Index() extractExpr(tw, expr.X, lbl, 0, false) case *ast.SelectorExpr: - if expr == nil { - return - } kind = dbscheme.SelectorExpr.Index() extractExpr(tw, expr.X, lbl, 0, false) extractExpr(tw, expr.Sel, lbl, 1, false) case *ast.IndexExpr: - if expr == nil { - return - } typeofx := typeOf(tw, expr.X) if typeofx == nil { // We are missing type information for `expr.X`, so we cannot @@ -1065,9 +1050,6 @@ func extractExpr(tw *trap.Writer, expr ast.Expr, parent trap.Label, idx int, ski extractExpr(tw, expr.X, lbl, 0, false) extractExpr(tw, expr.Index, lbl, 1, false) case *ast.IndexListExpr: - if expr == nil { - return - } typeofx := typeOf(tw, expr.X) if typeofx == nil { // We are missing type information for `expr.X`, so we cannot @@ -1084,18 +1066,12 @@ func extractExpr(tw *trap.Writer, expr ast.Expr, parent trap.Label, idx int, ski extractExpr(tw, expr.X, lbl, 0, false) extractExprs(tw, expr.Indices, lbl, 1, 1) case *ast.SliceExpr: - if expr == nil { - return - } kind = dbscheme.SliceExpr.Index() extractExpr(tw, expr.X, lbl, 0, false) extractExpr(tw, expr.Low, lbl, 1, false) extractExpr(tw, expr.High, lbl, 2, false) extractExpr(tw, expr.Max, lbl, 3, false) case *ast.TypeAssertExpr: - if expr == nil { - return - } kind = dbscheme.TypeAssertExpr.Index() extractExpr(tw, expr.X, lbl, 0, false) // expr.Type can be `nil` if this is the `x.(type)` in a type switch. @@ -1103,9 +1079,6 @@ func extractExpr(tw *trap.Writer, expr ast.Expr, parent trap.Label, idx int, ski extractExpr(tw, expr.Type, lbl, 1, false) } case *ast.CallExpr: - if expr == nil { - return - } kind = dbscheme.CallOrConversionExpr.Index() extractExpr(tw, expr.Fun, lbl, 0, false) extractExprs(tw, expr.Args, lbl, 1, 1) @@ -1113,22 +1086,13 @@ func extractExpr(tw *trap.Writer, expr ast.Expr, parent trap.Label, idx int, ski dbscheme.HasEllipsisTable.Emit(tw, lbl) } case *ast.StarExpr: - if expr == nil { - return - } kind = dbscheme.StarExpr.Index() extractExpr(tw, expr.X, lbl, 0, false) case *ast.KeyValueExpr: - if expr == nil { - return - } kind = dbscheme.KeyValueExpr.Index() extractExpr(tw, expr.Key, lbl, 0, false) extractExpr(tw, expr.Value, lbl, 1, false) case *ast.UnaryExpr: - if expr == nil { - return - } if expr.Op == token.TILDE { kind = dbscheme.TypeSetLiteralExpr.Index() } else { @@ -1140,9 +1104,6 @@ func extractExpr(tw *trap.Writer, expr ast.Expr, parent trap.Label, idx int, ski } extractExpr(tw, expr.X, lbl, 0, false) case *ast.BinaryExpr: - if expr == nil { - return - } _, isUnionType := typeOf(tw, expr).(*types.Union) if expr.Op == token.OR && isUnionType { kind = dbscheme.TypeSetLiteralExpr.Index() @@ -1158,46 +1119,28 @@ func extractExpr(tw *trap.Writer, expr ast.Expr, parent trap.Label, idx int, ski extractExpr(tw, expr.Y, lbl, 1, false) } case *ast.ArrayType: - if expr == nil { - return - } kind = dbscheme.ArrayTypeExpr.Index() extractExpr(tw, expr.Len, lbl, 0, false) extractExpr(tw, expr.Elt, lbl, 1, false) case *ast.StructType: - if expr == nil { - return - } kind = dbscheme.StructTypeExpr.Index() extractFields(tw, expr.Fields, lbl, 0, 1) case *ast.FuncType: - if expr == nil { - return - } kind = dbscheme.FuncTypeExpr.Index() extractFields(tw, expr.Params, lbl, 0, 1) extractFields(tw, expr.Results, lbl, -1, -1) emitScopeNodeInfo(tw, expr, lbl) case *ast.InterfaceType: - if expr == nil { - return - } kind = dbscheme.InterfaceTypeExpr.Index() // expr.Methods contains methods, embedded interfaces and type set // literals. makeTypeSetLiteralsUnionTyped(tw, expr.Methods) extractFields(tw, expr.Methods, lbl, 0, 1) case *ast.MapType: - if expr == nil { - return - } kind = dbscheme.MapTypeExpr.Index() extractExpr(tw, expr.Key, lbl, 0, false) extractExpr(tw, expr.Value, lbl, 1, false) case *ast.ChanType: - if expr == nil { - return - } tp := dbscheme.ChanTypeExprs[expr.Dir] if tp == nil { log.Fatalf("unsupported channel direction %v", expr.Dir) @@ -1299,7 +1242,15 @@ func extractFields(tw *trap.Writer, fields *ast.FieldList, parent trap.Label, id // extractStmt extracts AST information for a given statement and all other statements or expressions // nested inside it func extractStmt(tw *trap.Writer, stmt ast.Stmt, parent trap.Label, idx int) { - if stmt == nil { + if stmt == nil || stmt == (*ast.DeclStmt)(nil) || + stmt == (*ast.LabeledStmt)(nil) || stmt == (*ast.ExprStmt)(nil) || + stmt == (*ast.SendStmt)(nil) || stmt == (*ast.IncDecStmt)(nil) || + stmt == (*ast.AssignStmt)(nil) || stmt == (*ast.GoStmt)(nil) || + stmt == (*ast.DeferStmt)(nil) || stmt == (*ast.BranchStmt)(nil) || + stmt == (*ast.BlockStmt)(nil) || stmt == (*ast.IfStmt)(nil) || + stmt == (*ast.CaseClause)(nil) || stmt == (*ast.SwitchStmt)(nil) || + stmt == (*ast.TypeSwitchStmt)(nil) || stmt == (*ast.CommClause)(nil) || + stmt == (*ast.ForStmt)(nil) || stmt == (*ast.RangeStmt)(nil) { return } @@ -1309,37 +1260,22 @@ func extractStmt(tw *trap.Writer, stmt ast.Stmt, parent trap.Label, idx int) { case *ast.BadStmt: kind = dbscheme.BadStmtType.Index() case *ast.DeclStmt: - if stmt == nil { - return - } kind = dbscheme.DeclStmtType.Index() extractDecl(tw, stmt.Decl, lbl, 0) case *ast.EmptyStmt: kind = dbscheme.EmptyStmtType.Index() case *ast.LabeledStmt: - if stmt == nil { - return - } kind = dbscheme.LabeledStmtType.Index() extractExpr(tw, stmt.Label, lbl, 0, false) extractStmt(tw, stmt.Stmt, lbl, 1) case *ast.ExprStmt: - if stmt == nil { - return - } kind = dbscheme.ExprStmtType.Index() extractExpr(tw, stmt.X, lbl, 0, false) case *ast.SendStmt: - if stmt == nil { - return - } kind = dbscheme.SendStmtType.Index() extractExpr(tw, stmt.Chan, lbl, 0, false) extractExpr(tw, stmt.Value, lbl, 1, false) case *ast.IncDecStmt: - if stmt == nil { - return - } if stmt.Tok == token.INC { kind = dbscheme.IncStmtType.Index() } else if stmt.Tok == token.DEC { @@ -1349,9 +1285,6 @@ func extractStmt(tw *trap.Writer, stmt ast.Stmt, parent trap.Label, idx int) { } extractExpr(tw, stmt.X, lbl, 0, false) case *ast.AssignStmt: - if stmt == nil { - return - } tp := dbscheme.AssignStmtTypes[stmt.Tok] if tp == nil { log.Fatalf("unsupported assignment statement with operator %v", stmt.Tok) @@ -1360,24 +1293,15 @@ func extractStmt(tw *trap.Writer, stmt ast.Stmt, parent trap.Label, idx int) { extractExprs(tw, stmt.Lhs, lbl, -1, -1) extractExprs(tw, stmt.Rhs, lbl, 1, 1) case *ast.GoStmt: - if stmt == nil { - return - } kind = dbscheme.GoStmtType.Index() extractExpr(tw, stmt.Call, lbl, 0, false) case *ast.DeferStmt: - if stmt == nil { - return - } kind = dbscheme.DeferStmtType.Index() extractExpr(tw, stmt.Call, lbl, 0, false) case *ast.ReturnStmt: kind = dbscheme.ReturnStmtType.Index() extractExprs(tw, stmt.Results, lbl, 0, 1) case *ast.BranchStmt: - if stmt == nil { - return - } switch stmt.Tok { case token.BREAK: kind = dbscheme.BreakStmtType.Index() @@ -1392,16 +1316,10 @@ func extractStmt(tw *trap.Writer, stmt ast.Stmt, parent trap.Label, idx int) { } extractExpr(tw, stmt.Label, lbl, 0, false) case *ast.BlockStmt: - if stmt == nil { - return - } kind = dbscheme.BlockStmtType.Index() extractStmts(tw, stmt.List, lbl, 0, 1) emitScopeNodeInfo(tw, stmt, lbl) case *ast.IfStmt: - if stmt == nil { - return - } kind = dbscheme.IfStmtType.Index() extractStmt(tw, stmt.Init, lbl, 0) extractExpr(tw, stmt.Cond, lbl, 1, false) @@ -1409,35 +1327,23 @@ func extractStmt(tw *trap.Writer, stmt ast.Stmt, parent trap.Label, idx int) { extractStmt(tw, stmt.Else, lbl, 3) emitScopeNodeInfo(tw, stmt, lbl) case *ast.CaseClause: - if stmt == nil { - return - } kind = dbscheme.CaseClauseType.Index() extractExprs(tw, stmt.List, lbl, -1, -1) extractStmts(tw, stmt.Body, lbl, 0, 1) emitScopeNodeInfo(tw, stmt, lbl) case *ast.SwitchStmt: - if stmt == nil { - return - } kind = dbscheme.ExprSwitchStmtType.Index() extractStmt(tw, stmt.Init, lbl, 0) extractExpr(tw, stmt.Tag, lbl, 1, false) extractStmt(tw, stmt.Body, lbl, 2) emitScopeNodeInfo(tw, stmt, lbl) case *ast.TypeSwitchStmt: - if stmt == nil { - return - } kind = dbscheme.TypeSwitchStmtType.Index() extractStmt(tw, stmt.Init, lbl, 0) extractStmt(tw, stmt.Assign, lbl, 1) extractStmt(tw, stmt.Body, lbl, 2) emitScopeNodeInfo(tw, stmt, lbl) case *ast.CommClause: - if stmt == nil { - return - } kind = dbscheme.CommClauseType.Index() extractStmt(tw, stmt.Comm, lbl, 0) extractStmts(tw, stmt.Body, lbl, 1, 1) @@ -1446,9 +1352,6 @@ func extractStmt(tw *trap.Writer, stmt ast.Stmt, parent trap.Label, idx int) { kind = dbscheme.SelectStmtType.Index() extractStmt(tw, stmt.Body, lbl, 0) case *ast.ForStmt: - if stmt == nil { - return - } kind = dbscheme.ForStmtType.Index() extractStmt(tw, stmt.Init, lbl, 0) extractExpr(tw, stmt.Cond, lbl, 1, false) @@ -1456,9 +1359,6 @@ func extractStmt(tw *trap.Writer, stmt ast.Stmt, parent trap.Label, idx int) { extractStmt(tw, stmt.Body, lbl, 3) emitScopeNodeInfo(tw, stmt, lbl) case *ast.RangeStmt: - if stmt == nil { - return - } kind = dbscheme.RangeStmtType.Index() extractExpr(tw, stmt.Key, lbl, 0, false) extractExpr(tw, stmt.Value, lbl, 1, false) @@ -1486,15 +1386,15 @@ func extractStmts(tw *trap.Writer, stmts []ast.Stmt, parent trap.Label, idx int, // extractDecl extracts AST information for the given declaration func extractDecl(tw *trap.Writer, decl ast.Decl, parent trap.Label, idx int) { + if decl == (*ast.FuncDecl)(nil) || decl == (*ast.GenDecl)(nil) { + return + } lbl := tw.Labeler.LocalID(decl) var kind int switch decl := decl.(type) { case *ast.BadDecl: kind = dbscheme.BadDeclType.Index() case *ast.GenDecl: - if decl == nil { - return - } switch decl.Tok { case token.IMPORT: kind = dbscheme.ImportDeclType.Index() @@ -1512,9 +1412,6 @@ func extractDecl(tw *trap.Writer, decl ast.Decl, parent trap.Label, idx int) { } extractDoc(tw, decl.Doc, lbl) case *ast.FuncDecl: - if decl == nil { - return - } kind = dbscheme.FuncDeclType.Index() extractFields(tw, decl.Recv, lbl, -1, -1) extractExpr(tw, decl.Name, lbl, 0, false) From d5044fd07276ffee8df483916a9efa796eb9eab8 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 15 May 2025 14:19:58 +0100 Subject: [PATCH 22/86] Deal better with Windows paths --- go/extractor/extractor.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/go/extractor/extractor.go b/go/extractor/extractor.go index 1456dd3a899..d90d572a67a 100644 --- a/go/extractor/extractor.go +++ b/go/extractor/extractor.go @@ -773,9 +773,15 @@ func (extraction *Extraction) extractFileInfo(tw *trap.Writer, file string, isDu var parentLbl trap.Label for i, component := range components { + isRoot := false if i == 0 { if component == "" { path = "/" + isRoot = true + } else if regexp.MustCompile(`^[A-Za-z]:$`).MatchString(component) { + // Handle Windows drive letters by appending "/" + path = component + "/" + isRoot = true } else { path = component } @@ -800,7 +806,7 @@ func (extraction *Extraction) extractFileInfo(tw *trap.Writer, file string, isDu if i > 0 { dbscheme.ContainerParentTable.Emit(tw, parentLbl, lbl) } - if path != "/" { + if !isRoot { parentPath = path } parentLbl = lbl From 47dac643016624181231a75ba00bbc5a3df5d40f Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 20 May 2025 03:03:36 +0100 Subject: [PATCH 23/86] fix previous commit --- go/extractor/extractor.go | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/go/extractor/extractor.go b/go/extractor/extractor.go index d90d572a67a..ff58df73a91 100644 --- a/go/extractor/extractor.go +++ b/go/extractor/extractor.go @@ -773,24 +773,22 @@ func (extraction *Extraction) extractFileInfo(tw *trap.Writer, file string, isDu var parentLbl trap.Label for i, component := range components { - isRoot := false + var rawPath, canonicalPath string if i == 0 { - if component == "" { - path = "/" - isRoot = true - } else if regexp.MustCompile(`^[A-Za-z]:$`).MatchString(component) { - // Handle Windows drive letters by appending "/" - path = component + "/" - isRoot = true + rawPath = component + if component == "" || regexp.MustCompile(`^[A-Za-z]:$`).MatchString(component) { + // Handle linux root and Windows drive letters by appending "/" + canonicalPath = rawPath + "/" } else { - path = component + canonicalPath = rawPath } } else { - path = parentPath + "/" + component + rawPath = parentPath + "/" + component + canonicalPath = rawPath } if i == len(components)-1 { lbl := tw.Labeler.FileLabelFor(file) - dbscheme.FilesTable.Emit(tw, lbl, path) + dbscheme.FilesTable.Emit(tw, lbl, canonicalPath) dbscheme.ContainerParentTable.Emit(tw, parentLbl, lbl) dbscheme.HasLocationTable.Emit(tw, lbl, emitLocation(tw, lbl, 0, 0, 0, 0)) extraction.Lock.Lock() @@ -801,14 +799,12 @@ func (extraction *Extraction) extractFileInfo(tw *trap.Writer, file string, isDu extraction.Lock.Unlock() break } - lbl := tw.Labeler.GlobalID(util.EscapeTrapSpecialChars(path) + ";folder") - dbscheme.FoldersTable.Emit(tw, lbl, path) + lbl := tw.Labeler.GlobalID(util.EscapeTrapSpecialChars(canonicalPath) + ";folder") + dbscheme.FoldersTable.Emit(tw, lbl, canonicalPath) if i > 0 { dbscheme.ContainerParentTable.Emit(tw, parentLbl, lbl) } - if !isRoot { - parentPath = path - } + parentPath = rawPath parentLbl = lbl } } From 83cd349531e8ac2fb03ac371123bf986ac83556d Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 20 May 2025 13:13:03 +0100 Subject: [PATCH 24/86] Change variable name and add comment --- go/extractor/extractor.go | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/go/extractor/extractor.go b/go/extractor/extractor.go index ff58df73a91..42ea0527ce8 100644 --- a/go/extractor/extractor.go +++ b/go/extractor/extractor.go @@ -773,22 +773,25 @@ func (extraction *Extraction) extractFileInfo(tw *trap.Writer, file string, isDu var parentLbl trap.Label for i, component := range components { - var rawPath, canonicalPath string + // displayPath is the same as rawPath except for root directories: if + // rawPath is "" then displayPath is "/"; if rawPath is "C:" then + // displayPath is "C:/". + var rawPath, displayPath string if i == 0 { rawPath = component if component == "" || regexp.MustCompile(`^[A-Za-z]:$`).MatchString(component) { // Handle linux root and Windows drive letters by appending "/" - canonicalPath = rawPath + "/" + displayPath = rawPath + "/" } else { - canonicalPath = rawPath + displayPath = rawPath } } else { rawPath = parentPath + "/" + component - canonicalPath = rawPath + displayPath = rawPath } if i == len(components)-1 { lbl := tw.Labeler.FileLabelFor(file) - dbscheme.FilesTable.Emit(tw, lbl, canonicalPath) + dbscheme.FilesTable.Emit(tw, lbl, displayPath) dbscheme.ContainerParentTable.Emit(tw, parentLbl, lbl) dbscheme.HasLocationTable.Emit(tw, lbl, emitLocation(tw, lbl, 0, 0, 0, 0)) extraction.Lock.Lock() @@ -799,8 +802,8 @@ func (extraction *Extraction) extractFileInfo(tw *trap.Writer, file string, isDu extraction.Lock.Unlock() break } - lbl := tw.Labeler.GlobalID(util.EscapeTrapSpecialChars(canonicalPath) + ";folder") - dbscheme.FoldersTable.Emit(tw, lbl, canonicalPath) + lbl := tw.Labeler.GlobalID(util.EscapeTrapSpecialChars(displayPath) + ";folder") + dbscheme.FoldersTable.Emit(tw, lbl, displayPath) if i > 0 { dbscheme.ContainerParentTable.Emit(tw, parentLbl, lbl) } From 5941b3081c3a48084c21675fb961f8acabd89c0e Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 19 May 2025 13:44:09 +0200 Subject: [PATCH 25/86] C#: Convert tests for cs/missed-readonly-modifier to inline expectatations. --- .../MissedReadonlyOpportunity/MissedReadonlyOpportunity.cs | 4 ++-- .../MissedReadonlyOpportunity/MissedReadonlyOpportunity.qlref | 3 ++- .../MissedReadonlyOpportunity/MissedReadonlyOpportunityBad.cs | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.cs b/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.cs index 0ecb33abadc..bfe6b3243d4 100644 --- a/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.cs +++ b/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.cs @@ -1,7 +1,7 @@ class MissedReadonlyOpportunity { - public int Bad1; - public T Bad2; + public int Bad1; // $ Alert + public T Bad2; // $ Alert public readonly int Good1; public readonly int Good2 = 0; public const int Good3 = 0; diff --git a/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.qlref b/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.qlref index 28237dce311..eb2e98d639d 100644 --- a/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.qlref +++ b/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.qlref @@ -1 +1,2 @@ -Language Abuse/MissedReadonlyOpportunity.ql +query: Language Abuse/MissedReadonlyOpportunity.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunityBad.cs b/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunityBad.cs index 7bd3d8d31cd..912141bb862 100644 --- a/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunityBad.cs +++ b/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunityBad.cs @@ -1,6 +1,6 @@ class Bad { - int Field; + int Field; // $ Alert public Bad(int i) { From 3a1cd3f734959ac38db20c97d4e1789c0ceed1a3 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 19 May 2025 13:56:35 +0200 Subject: [PATCH 26/86] C#: Add cs/missed-readonly-modifier to the code-quality suite. --- .../posix/query-suite/csharp-code-quality.qls.expected | 1 + csharp/ql/src/Language Abuse/MissedReadonlyOpportunity.ql | 1 + 2 files changed, 2 insertions(+) diff --git a/csharp/ql/integration-tests/posix/query-suite/csharp-code-quality.qls.expected b/csharp/ql/integration-tests/posix/query-suite/csharp-code-quality.qls.expected index d1b40bd013e..14934899e0d 100644 --- a/csharp/ql/integration-tests/posix/query-suite/csharp-code-quality.qls.expected +++ b/csharp/ql/integration-tests/posix/query-suite/csharp-code-quality.qls.expected @@ -3,6 +3,7 @@ ql/csharp/ql/src/API Abuse/FormatInvalid.ql ql/csharp/ql/src/API Abuse/NoDisposeCallOnLocalIDisposable.ql ql/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql ql/csharp/ql/src/Dead Code/DeadStoreOfLocal.ql +ql/csharp/ql/src/Language Abuse/MissedReadonlyOpportunity.ql ql/csharp/ql/src/Likely Bugs/Collections/ContainerLengthCmpOffByOne.ql ql/csharp/ql/src/Likely Bugs/Collections/ContainerSizeCmpZero.ql ql/csharp/ql/src/Likely Bugs/DangerousNonShortCircuitLogic.ql diff --git a/csharp/ql/src/Language Abuse/MissedReadonlyOpportunity.ql b/csharp/ql/src/Language Abuse/MissedReadonlyOpportunity.ql index b794700e79b..a71876e8c7d 100644 --- a/csharp/ql/src/Language Abuse/MissedReadonlyOpportunity.ql +++ b/csharp/ql/src/Language Abuse/MissedReadonlyOpportunity.ql @@ -8,6 +8,7 @@ * @id cs/missed-readonly-modifier * @tags maintainability * language-features + * quality */ import csharp From 28cd8a827a772bc9ce9eab91033852fa99bc6d78 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 19 May 2025 14:12:29 +0200 Subject: [PATCH 27/86] C#: Add more test examples for cs/missing-readonly-modifier. --- .../MissedReadonlyOpportunity.cs | 55 +++++++++++++++++++ .../MissedReadonlyOpportunity.expected | 11 ++++ 2 files changed, 66 insertions(+) diff --git a/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.cs b/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.cs index bfe6b3243d4..a365feec5e3 100644 --- a/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.cs +++ b/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.cs @@ -2,22 +2,26 @@ class MissedReadonlyOpportunity { public int Bad1; // $ Alert public T Bad2; // $ Alert + public Immutable Bad3; // $ Alert public readonly int Good1; public readonly int Good2 = 0; public const int Good3 = 0; public int Good4; public readonly T Good5; public T Good6; + public Mutable Good7; public MissedReadonlyOpportunity(int i, T t) { Bad1 = i; Bad2 = t; + Bad3 = new Immutable(); Good1 = i; Good2 = i; Good4 = i; Good5 = t; Good6 = t; + Good7 = new Mutable(); } public void M(int i) @@ -27,3 +31,54 @@ class MissedReadonlyOpportunity x.Good6 = false; } } + +struct Mutable +{ + private int x; + public int Mutate() + { + x = x + 1; + return x; + } +} + +readonly struct Immutable { } + +class Tree +{ + private Tree? Parent; + private Tree? Left; // $ Alert + private readonly Tree? Right; + + public Tree(Tree left, Tree right) + { + this.Left = left; + this.Right = right; + left.Parent = this; + right.Parent = this; + } + + public Tree() + { + Left = null; + Right = null; + } +} + +class StaticFields +{ + static int X; // $ Alert + static int Y; + + // Static constructor + static StaticFields() + { + X = 0; + } + + // Instance constructor + public StaticFields(int y) + { + Y = y; + } +} diff --git a/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.expected b/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.expected index 680a571e775..620b6b2dd11 100644 --- a/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.expected +++ b/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.expected @@ -1,3 +1,14 @@ +#select | MissedReadonlyOpportunity.cs:3:16:3:19 | Bad1 | Field 'Bad1' can be 'readonly'. | | MissedReadonlyOpportunity.cs:4:14:4:17 | Bad2 | Field 'Bad2' can be 'readonly'. | +| MissedReadonlyOpportunity.cs:5:22:5:25 | Bad3 | Field 'Bad3' can be 'readonly'. | +| MissedReadonlyOpportunity.cs:12:20:12:24 | Good7 | Field 'Good7' can be 'readonly'. | +| MissedReadonlyOpportunity.cs:49:19:49:24 | Parent | Field 'Parent' can be 'readonly'. | +| MissedReadonlyOpportunity.cs:50:19:50:22 | Left | Field 'Left' can be 'readonly'. | +| MissedReadonlyOpportunity.cs:70:16:70:16 | X | Field 'X' can be 'readonly'. | +| MissedReadonlyOpportunity.cs:71:16:71:16 | Y | Field 'Y' can be 'readonly'. | | MissedReadonlyOpportunityBad.cs:3:9:3:13 | Field | Field 'Field' can be 'readonly'. | +testFailures +| MissedReadonlyOpportunity.cs:12:20:12:24 | Field 'Good7' can be 'readonly'. | Unexpected result: Alert | +| MissedReadonlyOpportunity.cs:49:19:49:24 | Field 'Parent' can be 'readonly'. | Unexpected result: Alert | +| MissedReadonlyOpportunity.cs:71:16:71:16 | Field 'Y' can be 'readonly'. | Unexpected result: Alert | From 8108c72c17b945f5987fd6a730d5b1a263e8c721 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 19 May 2025 14:15:13 +0200 Subject: [PATCH 28/86] C#: Exclude structs from being flagged in cs/missed-readonly-modifier. --- csharp/ql/src/Language Abuse/MissedReadonlyOpportunity.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/csharp/ql/src/Language Abuse/MissedReadonlyOpportunity.ql b/csharp/ql/src/Language Abuse/MissedReadonlyOpportunity.ql index a71876e8c7d..6946e9b4894 100644 --- a/csharp/ql/src/Language Abuse/MissedReadonlyOpportunity.ql +++ b/csharp/ql/src/Language Abuse/MissedReadonlyOpportunity.ql @@ -27,6 +27,7 @@ predicate isReadonlyCompatibleDefinition(AssignableDefinition def, Field f) { } predicate canBeReadonly(Field f) { + exists(Type t | t = f.getType() | not t instanceof Struct or t.(Struct).isReadonly()) and forex(AssignableDefinition def | defTargetsField(def, f) | isReadonlyCompatibleDefinition(def, f)) } From 19e9197874cd585ce55e4cfbdc00ffb40b6764c1 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 19 May 2025 16:37:14 +0200 Subject: [PATCH 29/86] C#: The field access should be on this for it to be compatible with readonly. --- csharp/ql/src/Language Abuse/MissedReadonlyOpportunity.ql | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/csharp/ql/src/Language Abuse/MissedReadonlyOpportunity.ql b/csharp/ql/src/Language Abuse/MissedReadonlyOpportunity.ql index 6946e9b4894..78cce5126df 100644 --- a/csharp/ql/src/Language Abuse/MissedReadonlyOpportunity.ql +++ b/csharp/ql/src/Language Abuse/MissedReadonlyOpportunity.ql @@ -20,7 +20,10 @@ predicate defTargetsField(AssignableDefinition def, Field f) { predicate isReadonlyCompatibleDefinition(AssignableDefinition def, Field f) { defTargetsField(def, f) and ( - def.getEnclosingCallable().(Constructor).getDeclaringType() = f.getDeclaringType() + def.getEnclosingCallable().(StaticConstructor).getDeclaringType() = f.getDeclaringType() + or + def.getEnclosingCallable().(InstanceConstructor).getDeclaringType() = f.getDeclaringType() and + def.getTargetAccess().(QualifiableExpr).getQualifier() instanceof ThisAccess or def instanceof AssignableDefinitions::InitializerDefinition ) From 008d5b7081b941a092e3b25320b037380154bfdb Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 21 May 2025 15:20:15 +0200 Subject: [PATCH 30/86] C#: Update test expected output. --- .../MissedReadonlyOpportunity.expected | 8 -------- 1 file changed, 8 deletions(-) diff --git a/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.expected b/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.expected index 620b6b2dd11..6a9b286a343 100644 --- a/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.expected +++ b/csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.expected @@ -1,14 +1,6 @@ -#select | MissedReadonlyOpportunity.cs:3:16:3:19 | Bad1 | Field 'Bad1' can be 'readonly'. | | MissedReadonlyOpportunity.cs:4:14:4:17 | Bad2 | Field 'Bad2' can be 'readonly'. | | MissedReadonlyOpportunity.cs:5:22:5:25 | Bad3 | Field 'Bad3' can be 'readonly'. | -| MissedReadonlyOpportunity.cs:12:20:12:24 | Good7 | Field 'Good7' can be 'readonly'. | -| MissedReadonlyOpportunity.cs:49:19:49:24 | Parent | Field 'Parent' can be 'readonly'. | | MissedReadonlyOpportunity.cs:50:19:50:22 | Left | Field 'Left' can be 'readonly'. | | MissedReadonlyOpportunity.cs:70:16:70:16 | X | Field 'X' can be 'readonly'. | -| MissedReadonlyOpportunity.cs:71:16:71:16 | Y | Field 'Y' can be 'readonly'. | | MissedReadonlyOpportunityBad.cs:3:9:3:13 | Field | Field 'Field' can be 'readonly'. | -testFailures -| MissedReadonlyOpportunity.cs:12:20:12:24 | Field 'Good7' can be 'readonly'. | Unexpected result: Alert | -| MissedReadonlyOpportunity.cs:49:19:49:24 | Field 'Parent' can be 'readonly'. | Unexpected result: Alert | -| MissedReadonlyOpportunity.cs:71:16:71:16 | Field 'Y' can be 'readonly'. | Unexpected result: Alert | From 463a71155266d8e2508579f428c86c3503b5bfdb Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 21 May 2025 22:22:10 +0100 Subject: [PATCH 31/86] Use reflection for interface nil check instead --- go/extractor/extractor.go | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/go/extractor/extractor.go b/go/extractor/extractor.go index 42ea0527ce8..67c12737584 100644 --- a/go/extractor/extractor.go +++ b/go/extractor/extractor.go @@ -13,6 +13,7 @@ import ( "log" "os" "path/filepath" + "reflect" "regexp" "runtime" "strconv" @@ -941,16 +942,7 @@ func emitScopeNodeInfo(tw *trap.Writer, nd ast.Node, lbl trap.Label) { // extractExpr extracts AST information for the given expression and all its subexpressions func extractExpr(tw *trap.Writer, expr ast.Expr, parent trap.Label, idx int, skipExtractingValue bool) { - if expr == nil || expr == (*ast.Ident)(nil) || expr == (*ast.BasicLit)(nil) || - expr == (*ast.Ellipsis)(nil) || expr == (*ast.FuncLit)(nil) || - expr == (*ast.CompositeLit)(nil) || expr == (*ast.SelectorExpr)(nil) || - expr == (*ast.IndexListExpr)(nil) || expr == (*ast.SliceExpr)(nil) || - expr == (*ast.TypeAssertExpr)(nil) || expr == (*ast.CallExpr)(nil) || - expr == (*ast.StarExpr)(nil) || expr == (*ast.KeyValueExpr)(nil) || - expr == (*ast.UnaryExpr)(nil) || expr == (*ast.BinaryExpr)(nil) || - expr == (*ast.ArrayType)(nil) || expr == (*ast.StructType)(nil) || - expr == (*ast.FuncType)(nil) || expr == (*ast.InterfaceType)(nil) || - expr == (*ast.MapType)(nil) || expr == (*ast.ChanType)(nil) { + if expr == nil || reflect.ValueOf(expr).IsNil() { return } @@ -1247,15 +1239,7 @@ func extractFields(tw *trap.Writer, fields *ast.FieldList, parent trap.Label, id // extractStmt extracts AST information for a given statement and all other statements or expressions // nested inside it func extractStmt(tw *trap.Writer, stmt ast.Stmt, parent trap.Label, idx int) { - if stmt == nil || stmt == (*ast.DeclStmt)(nil) || - stmt == (*ast.LabeledStmt)(nil) || stmt == (*ast.ExprStmt)(nil) || - stmt == (*ast.SendStmt)(nil) || stmt == (*ast.IncDecStmt)(nil) || - stmt == (*ast.AssignStmt)(nil) || stmt == (*ast.GoStmt)(nil) || - stmt == (*ast.DeferStmt)(nil) || stmt == (*ast.BranchStmt)(nil) || - stmt == (*ast.BlockStmt)(nil) || stmt == (*ast.IfStmt)(nil) || - stmt == (*ast.CaseClause)(nil) || stmt == (*ast.SwitchStmt)(nil) || - stmt == (*ast.TypeSwitchStmt)(nil) || stmt == (*ast.CommClause)(nil) || - stmt == (*ast.ForStmt)(nil) || stmt == (*ast.RangeStmt)(nil) { + if stmt == nil || reflect.ValueOf(stmt).IsNil() { return } @@ -1391,7 +1375,7 @@ func extractStmts(tw *trap.Writer, stmts []ast.Stmt, parent trap.Label, idx int, // extractDecl extracts AST information for the given declaration func extractDecl(tw *trap.Writer, decl ast.Decl, parent trap.Label, idx int) { - if decl == (*ast.FuncDecl)(nil) || decl == (*ast.GenDecl)(nil) { + if reflect.ValueOf(decl).IsNil() { return } lbl := tw.Labeler.LocalID(decl) From bae16f07ff5ae6c52e93924c5217eaa4f33f8cd9 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 22 May 2025 08:42:37 +0200 Subject: [PATCH 32/86] C#: Change note. --- .../src/change-notes/2025-05-22-missed-readonly-modifier.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 csharp/ql/src/change-notes/2025-05-22-missed-readonly-modifier.md diff --git a/csharp/ql/src/change-notes/2025-05-22-missed-readonly-modifier.md b/csharp/ql/src/change-notes/2025-05-22-missed-readonly-modifier.md new file mode 100644 index 00000000000..ee3d60fe4ff --- /dev/null +++ b/csharp/ql/src/change-notes/2025-05-22-missed-readonly-modifier.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The precision of the query `cs/missed-readonly-modifier` has been improved. Some false positives related to static fields and struct type fields have been removed. From 11480d29b7dc425884754ce53a0a0461a786b505 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 21 May 2025 11:26:55 +0100 Subject: [PATCH 33/86] Rust: Add ArithmeticOperation library. --- .../rust/elements/ArithmeticOperation.qll | 41 +++++++++++++++++++ rust/ql/lib/rust.qll | 1 + .../library-tests/operations/Operations.ql | 8 ++++ rust/ql/test/library-tests/operations/test.rs | 22 +++++----- 4 files changed, 61 insertions(+), 11 deletions(-) create mode 100644 rust/ql/lib/codeql/rust/elements/ArithmeticOperation.qll diff --git a/rust/ql/lib/codeql/rust/elements/ArithmeticOperation.qll b/rust/ql/lib/codeql/rust/elements/ArithmeticOperation.qll new file mode 100644 index 00000000000..c91d65c976a --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/ArithmeticOperation.qll @@ -0,0 +1,41 @@ +/** + * Provides classes for arithmetic operations. + */ + +private import codeql.rust.elements.BinaryExpr +private import codeql.rust.elements.PrefixExpr +private import codeql.rust.elements.Operation + +/** + * An arithmetic operation, such as `+`, `*=`, or `-`. + */ +abstract private class ArithmeticOperationImpl extends Operation { } + +final class ArithmeticOperation = ArithmeticOperationImpl; + +/** + * A binary arithmetic operation, such as `+` or `*`. + */ +final class BinaryArithmeticOperation extends BinaryExpr, ArithmeticOperationImpl { + BinaryArithmeticOperation() { + this.getOperatorName() = ["+", "-", "*", "/", "%"] + } +} + +/** + * An arithmetic assignment operation, such as `+=` or `*=`. + */ +final class AssignArithmeticOperation extends BinaryExpr, ArithmeticOperationImpl { + AssignArithmeticOperation() { + this.getOperatorName() = ["+=", "-=", "*=", "/=", "%="] + } +} + +/** + * A prefix arithmetic operation, such as `-`. + */ +final class PrefixArithmeticOperation extends PrefixExpr, ArithmeticOperationImpl { + PrefixArithmeticOperation() { + this.getOperatorName() = "-" + } +} diff --git a/rust/ql/lib/rust.qll b/rust/ql/lib/rust.qll index 4a533b34bad..3f39dee3337 100644 --- a/rust/ql/lib/rust.qll +++ b/rust/ql/lib/rust.qll @@ -4,6 +4,7 @@ import codeql.rust.elements import codeql.Locations import codeql.files.FileSystem import codeql.rust.elements.Operation +import codeql.rust.elements.ArithmeticOperation import codeql.rust.elements.AssignmentOperation import codeql.rust.elements.ComparisonOperation import codeql.rust.elements.LiteralExprExt diff --git a/rust/ql/test/library-tests/operations/Operations.ql b/rust/ql/test/library-tests/operations/Operations.ql index 482373c8d05..f33a8dec6b1 100644 --- a/rust/ql/test/library-tests/operations/Operations.ql +++ b/rust/ql/test/library-tests/operations/Operations.ql @@ -31,6 +31,14 @@ string describe(Expr op) { op instanceof LessOrEqualsOperation and result = "LessOrEqualsOperation" or op instanceof GreaterOrEqualsOperation and result = "GreaterOrEqualsOperation" + or + op instanceof ArithmeticOperation and result = "ArithmeticOperation" + or + op instanceof BinaryArithmeticOperation and result = "BinaryArithmeticOperation" + or + op instanceof AssignArithmeticOperation and result = "AssignArithmeticOperation" + or + op instanceof PrefixArithmeticOperation and result = "PrefixArithmeticOperation" } module OperationsTest implements TestSig { diff --git a/rust/ql/test/library-tests/operations/test.rs b/rust/ql/test/library-tests/operations/test.rs index dba47f5faa3..a8fce0a0ee8 100644 --- a/rust/ql/test/library-tests/operations/test.rs +++ b/rust/ql/test/library-tests/operations/test.rs @@ -19,17 +19,17 @@ fn test_operations( x >= y; // $ Operation Op=>= Operands=2 BinaryExpr ComparisonOperation RelationalOperation GreaterOrEqualsOperation Greater=x Lesser=y // arithmetic operations - x + y; // $ Operation Op=+ Operands=2 BinaryExpr - x - y; // $ Operation Op=- Operands=2 BinaryExpr - x * y; // $ Operation Op=* Operands=2 BinaryExpr - x / y; // $ Operation Op=/ Operands=2 BinaryExpr - x % y; // $ Operation Op=% Operands=2 BinaryExpr - x += y; // $ Operation Op=+= Operands=2 AssignmentOperation BinaryExpr - x -= y; // $ Operation Op=-= Operands=2 AssignmentOperation BinaryExpr - x *= y; // $ Operation Op=*= Operands=2 AssignmentOperation BinaryExpr - x /= y; // $ Operation Op=/= Operands=2 AssignmentOperation BinaryExpr - x %= y; // $ Operation Op=%= Operands=2 AssignmentOperation BinaryExpr - -x; // $ Operation Op=- Operands=1 PrefixExpr + x + y; // $ Operation Op=+ Operands=2 BinaryExpr ArithmeticOperation BinaryArithmeticOperation + x - y; // $ Operation Op=- Operands=2 BinaryExpr ArithmeticOperation BinaryArithmeticOperation + x * y; // $ Operation Op=* Operands=2 BinaryExpr ArithmeticOperation BinaryArithmeticOperation + x / y; // $ Operation Op=/ Operands=2 BinaryExpr ArithmeticOperation BinaryArithmeticOperation + x % y; // $ Operation Op=% Operands=2 BinaryExpr ArithmeticOperation BinaryArithmeticOperation + x += y; // $ Operation Op=+= Operands=2 AssignmentOperation BinaryExpr ArithmeticOperation AssignArithmeticOperation + x -= y; // $ Operation Op=-= Operands=2 AssignmentOperation BinaryExpr ArithmeticOperation AssignArithmeticOperation + x *= y; // $ Operation Op=*= Operands=2 AssignmentOperation BinaryExpr ArithmeticOperation AssignArithmeticOperation + x /= y; // $ Operation Op=/= Operands=2 AssignmentOperation BinaryExpr ArithmeticOperation AssignArithmeticOperation + x %= y; // $ Operation Op=%= Operands=2 AssignmentOperation BinaryExpr ArithmeticOperation AssignArithmeticOperation + -x; // $ Operation Op=- Operands=1 PrefixExpr ArithmeticOperation PrefixArithmeticOperation // logical operations a && b; // $ Operation Op=&& Operands=2 BinaryExpr LogicalOperation From fafdc1d181a114f43c3c17eb5268eb4a75a62fc1 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 21 May 2025 11:33:28 +0100 Subject: [PATCH 34/86] Rust: Add BitwiseOperation library. --- .../codeql/rust/elements/BitwiseOperation.qll | 27 +++++++++++++++++++ rust/ql/lib/rust.qll | 1 + .../library-tests/operations/Operations.ql | 6 +++++ rust/ql/test/library-tests/operations/test.rs | 20 +++++++------- 4 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 rust/ql/lib/codeql/rust/elements/BitwiseOperation.qll diff --git a/rust/ql/lib/codeql/rust/elements/BitwiseOperation.qll b/rust/ql/lib/codeql/rust/elements/BitwiseOperation.qll new file mode 100644 index 00000000000..b906a2216ce --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/BitwiseOperation.qll @@ -0,0 +1,27 @@ +/** + * Provides classes for bitwise operations. + */ + +private import codeql.rust.elements.BinaryExpr +private import codeql.rust.elements.Operation + +/** + * A bitwise operation, such as `&`, `<<`, or `|=`. + */ +abstract private class BitwiseOperationImpl extends Operation { } + +final class BitwiseOperation = BitwiseOperationImpl; + +/** + * A binary bitwise operation, such as `&` or `<<`. + */ +final class BinaryBitwiseOperation extends BinaryExpr, BitwiseOperationImpl { + BinaryBitwiseOperation() { this.getOperatorName() = ["&", "|", "^", "<<", ">>"] } +} + +/** + * A bitwise assignment operation, such as `|=` or `<<=`. + */ +final class AssignBitwiseOperation extends BinaryExpr, BitwiseOperationImpl { + AssignBitwiseOperation() { this.getOperatorName() = ["&=", "|=", "^=", "<<=", ">>="] } +} diff --git a/rust/ql/lib/rust.qll b/rust/ql/lib/rust.qll index 3f39dee3337..e64b0e36abb 100644 --- a/rust/ql/lib/rust.qll +++ b/rust/ql/lib/rust.qll @@ -6,6 +6,7 @@ import codeql.files.FileSystem import codeql.rust.elements.Operation import codeql.rust.elements.ArithmeticOperation import codeql.rust.elements.AssignmentOperation +import codeql.rust.elements.BitwiseOperation import codeql.rust.elements.ComparisonOperation import codeql.rust.elements.LiteralExprExt import codeql.rust.elements.LogicalOperation diff --git a/rust/ql/test/library-tests/operations/Operations.ql b/rust/ql/test/library-tests/operations/Operations.ql index f33a8dec6b1..76e9acfde3f 100644 --- a/rust/ql/test/library-tests/operations/Operations.ql +++ b/rust/ql/test/library-tests/operations/Operations.ql @@ -39,6 +39,12 @@ string describe(Expr op) { op instanceof AssignArithmeticOperation and result = "AssignArithmeticOperation" or op instanceof PrefixArithmeticOperation and result = "PrefixArithmeticOperation" + or + op instanceof BitwiseOperation and result = "BitwiseOperation" + or + op instanceof BinaryBitwiseOperation and result = "BinaryBitwiseOperation" + or + op instanceof AssignBitwiseOperation and result = "AssignBitwiseOperation" } module OperationsTest implements TestSig { diff --git a/rust/ql/test/library-tests/operations/test.rs b/rust/ql/test/library-tests/operations/test.rs index a8fce0a0ee8..72cb8269636 100644 --- a/rust/ql/test/library-tests/operations/test.rs +++ b/rust/ql/test/library-tests/operations/test.rs @@ -37,16 +37,16 @@ fn test_operations( !a; // $ Operation Op=! Operands=1 PrefixExpr LogicalOperation // bitwise operations - x & y; // $ Operation Op=& Operands=2 BinaryExpr - x | y; // $ Operation Op=| Operands=2 BinaryExpr - x ^ y; // $ Operation Op=^ Operands=2 BinaryExpr - x << y; // $ Operation Op=<< Operands=2 BinaryExpr - x >> y; // $ Operation Op=>> Operands=2 BinaryExpr - x &= y; // $ Operation Op=&= Operands=2 AssignmentOperation BinaryExpr - x |= y; // $ Operation Op=|= Operands=2 AssignmentOperation BinaryExpr - x ^= y; // $ Operation Op=^= Operands=2 AssignmentOperation BinaryExpr - x <<= y; // $ Operation Op=<<= Operands=2 AssignmentOperation BinaryExpr - x >>= y; // $ Operation Op=>>= Operands=2 AssignmentOperation BinaryExpr + x & y; // $ Operation Op=& Operands=2 BinaryExpr BitwiseOperation BinaryBitwiseOperation + x | y; // $ Operation Op=| Operands=2 BinaryExpr BitwiseOperation BinaryBitwiseOperation + x ^ y; // $ Operation Op=^ Operands=2 BinaryExpr BitwiseOperation BinaryBitwiseOperation + x << y; // $ Operation Op=<< Operands=2 BinaryExpr BitwiseOperation BinaryBitwiseOperation + x >> y; // $ Operation Op=>> Operands=2 BinaryExpr BitwiseOperation BinaryBitwiseOperation + x &= y; // $ Operation Op=&= Operands=2 AssignmentOperation BinaryExpr BitwiseOperation AssignBitwiseOperation + x |= y; // $ Operation Op=|= Operands=2 AssignmentOperation BinaryExpr BitwiseOperation AssignBitwiseOperation + x ^= y; // $ Operation Op=^= Operands=2 AssignmentOperation BinaryExpr BitwiseOperation AssignBitwiseOperation + x <<= y; // $ Operation Op=<<= Operands=2 AssignmentOperation BinaryExpr BitwiseOperation AssignBitwiseOperation + x >>= y; // $ Operation Op=>>= Operands=2 AssignmentOperation BinaryExpr BitwiseOperation AssignBitwiseOperation // miscellaneous expressions that might be operations *ptr; // $ Operation Op=* Operands=1 PrefixExpr From 6c19cecb076115d621f1725dcccd1b1a1114f991 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 21 May 2025 11:55:48 +0100 Subject: [PATCH 35/86] Rust: Add DerefExpr class. --- rust/ql/lib/codeql/rust/elements/DerefExpr.qll | 13 +++++++++++++ rust/ql/lib/rust.qll | 1 + rust/ql/test/library-tests/operations/Operations.ql | 2 ++ rust/ql/test/library-tests/operations/test.rs | 2 +- 4 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 rust/ql/lib/codeql/rust/elements/DerefExpr.qll diff --git a/rust/ql/lib/codeql/rust/elements/DerefExpr.qll b/rust/ql/lib/codeql/rust/elements/DerefExpr.qll new file mode 100644 index 00000000000..28302a93411 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/DerefExpr.qll @@ -0,0 +1,13 @@ +/** + * Provides classes for deref expressions (`*`). + */ + +private import codeql.rust.elements.PrefixExpr +private import codeql.rust.elements.Operation + +/** + * A dereference expression, `*`. + */ +final class DerefExpr extends PrefixExpr, Operation { + DerefExpr() { this.getOperatorName() = "*" } +} diff --git a/rust/ql/lib/rust.qll b/rust/ql/lib/rust.qll index e64b0e36abb..209a002663f 100644 --- a/rust/ql/lib/rust.qll +++ b/rust/ql/lib/rust.qll @@ -8,6 +8,7 @@ import codeql.rust.elements.ArithmeticOperation import codeql.rust.elements.AssignmentOperation import codeql.rust.elements.BitwiseOperation import codeql.rust.elements.ComparisonOperation +import codeql.rust.elements.DerefExpr import codeql.rust.elements.LiteralExprExt import codeql.rust.elements.LogicalOperation import codeql.rust.elements.AsyncBlockExpr diff --git a/rust/ql/test/library-tests/operations/Operations.ql b/rust/ql/test/library-tests/operations/Operations.ql index 76e9acfde3f..2c2c7ac7e99 100644 --- a/rust/ql/test/library-tests/operations/Operations.ql +++ b/rust/ql/test/library-tests/operations/Operations.ql @@ -45,6 +45,8 @@ string describe(Expr op) { op instanceof BinaryBitwiseOperation and result = "BinaryBitwiseOperation" or op instanceof AssignBitwiseOperation and result = "AssignBitwiseOperation" + or + op instanceof DerefExpr and result = "DerefExpr" } module OperationsTest implements TestSig { diff --git a/rust/ql/test/library-tests/operations/test.rs b/rust/ql/test/library-tests/operations/test.rs index 72cb8269636..662a5ce0252 100644 --- a/rust/ql/test/library-tests/operations/test.rs +++ b/rust/ql/test/library-tests/operations/test.rs @@ -49,7 +49,7 @@ fn test_operations( x >>= y; // $ Operation Op=>>= Operands=2 AssignmentOperation BinaryExpr BitwiseOperation AssignBitwiseOperation // miscellaneous expressions that might be operations - *ptr; // $ Operation Op=* Operands=1 PrefixExpr + *ptr; // $ Operation Op=* Operands=1 PrefixExpr DerefExpr &x; // $ RefExpr res?; From b8f0e4d7e054942f29c1a44cd1995527dd1e07ce Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 21 May 2025 13:49:46 +0100 Subject: [PATCH 36/86] Rust: Use DerefExpr. --- rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll | 2 +- rust/ql/lib/codeql/rust/internal/TypeInference.qll | 6 ++---- .../codeql/rust/security/AccessInvalidPointerExtensions.qll | 4 +--- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll index 9bb2029cd44..790186bf2c9 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll @@ -610,7 +610,7 @@ module Impl { exists(Expr mid | assignmentExprDescendant(mid) and getImmediateParent(e) = mid and - not mid.(PrefixExpr).getOperatorName() = "*" and + not mid instanceof DerefExpr and not mid instanceof FieldExpr and not mid instanceof IndexExpr ) diff --git a/rust/ql/lib/codeql/rust/internal/TypeInference.qll b/rust/ql/lib/codeql/rust/internal/TypeInference.qll index bae628b4723..6ddaa81bfbf 100644 --- a/rust/ql/lib/codeql/rust/internal/TypeInference.qll +++ b/rust/ql/lib/codeql/rust/internal/TypeInference.qll @@ -259,8 +259,7 @@ private predicate typeEqualityLeft(AstNode n1, TypePath path1, AstNode n2, TypeP typeEquality(n1, path1, n2, path2) or n2 = - any(PrefixExpr pe | - pe.getOperatorName() = "*" and + any(DerefExpr pe | pe.getExpr() = n1 and path1.isCons(TRefTypeParameter(), path2) ) @@ -271,8 +270,7 @@ private predicate typeEqualityRight(AstNode n1, TypePath path1, AstNode n2, Type typeEquality(n1, path1, n2, path2) or n2 = - any(PrefixExpr pe | - pe.getOperatorName() = "*" and + any(DerefExpr pe | pe.getExpr() = n1 and path1 = TypePath::cons(TRefTypeParameter(), path2) ) diff --git a/rust/ql/lib/codeql/rust/security/AccessInvalidPointerExtensions.qll b/rust/ql/lib/codeql/rust/security/AccessInvalidPointerExtensions.qll index 37788609211..36abfb62d54 100644 --- a/rust/ql/lib/codeql/rust/security/AccessInvalidPointerExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/AccessInvalidPointerExtensions.qll @@ -50,9 +50,7 @@ module AccessInvalidPointer { * A pointer access using the unary `*` operator. */ private class DereferenceSink extends Sink { - DereferenceSink() { - exists(PrefixExpr p | p.getOperatorName() = "*" and p.getExpr() = this.asExpr().getExpr()) - } + DereferenceSink() { exists(DerefExpr p | p.getExpr() = this.asExpr().getExpr()) } } /** From b22ce5515fe6a52aa7150b028072f86dcb75036e Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 21 May 2025 14:15:47 +0100 Subject: [PATCH 37/86] Rust: Make RefExpr an Operation. --- rust/ql/lib/codeql/rust/elements/internal/RefExprImpl.qll | 7 ++++++- rust/ql/test/library-tests/operations/test.rs | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/rust/ql/lib/codeql/rust/elements/internal/RefExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/RefExprImpl.qll index 83f32d892fb..752b94dbacd 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/RefExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/RefExprImpl.qll @@ -5,6 +5,7 @@ */ private import codeql.rust.elements.internal.generated.RefExpr +private import codeql.rust.elements.internal.OperationImpl::Impl as OperationImpl /** * INTERNAL: This module contains the customizable definition of `RefExpr` and should not @@ -21,11 +22,15 @@ module Impl { * let raw_mut: &mut i32 = &raw mut foo; * ``` */ - class RefExpr extends Generated::RefExpr { + class RefExpr extends Generated::RefExpr, OperationImpl::Operation { override string toStringImpl() { result = "&" + concat(int i | | this.getSpecPart(i), " " order by i) } + override string getOperatorName() { result = "&" } + + override Expr getAnOperand() { result = this.getExpr() } + private string getSpecPart(int index) { index = 0 and this.isRaw() and result = "raw" or diff --git a/rust/ql/test/library-tests/operations/test.rs b/rust/ql/test/library-tests/operations/test.rs index 662a5ce0252..c3cde698aa0 100644 --- a/rust/ql/test/library-tests/operations/test.rs +++ b/rust/ql/test/library-tests/operations/test.rs @@ -50,7 +50,7 @@ fn test_operations( // miscellaneous expressions that might be operations *ptr; // $ Operation Op=* Operands=1 PrefixExpr DerefExpr - &x; // $ RefExpr + &x; // $ Operation Op=& Operands=1 RefExpr MISSING: PrefixExpr res?; return Ok(()); From dc280c6fb7e42f59406d63c0e6b6b01423ae7e2d Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 22 May 2025 15:18:45 +0100 Subject: [PATCH 38/86] Rust: Add missing assignment class relations. --- .../rust/elements/ArithmeticOperation.qll | 17 +++++++---------- .../codeql/rust/elements/BitwiseOperation.qll | 3 ++- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/rust/ql/lib/codeql/rust/elements/ArithmeticOperation.qll b/rust/ql/lib/codeql/rust/elements/ArithmeticOperation.qll index c91d65c976a..81abffa1a38 100644 --- a/rust/ql/lib/codeql/rust/elements/ArithmeticOperation.qll +++ b/rust/ql/lib/codeql/rust/elements/ArithmeticOperation.qll @@ -5,6 +5,7 @@ private import codeql.rust.elements.BinaryExpr private import codeql.rust.elements.PrefixExpr private import codeql.rust.elements.Operation +private import codeql.rust.elements.AssignmentOperation /** * An arithmetic operation, such as `+`, `*=`, or `-`. @@ -17,25 +18,21 @@ final class ArithmeticOperation = ArithmeticOperationImpl; * A binary arithmetic operation, such as `+` or `*`. */ final class BinaryArithmeticOperation extends BinaryExpr, ArithmeticOperationImpl { - BinaryArithmeticOperation() { - this.getOperatorName() = ["+", "-", "*", "/", "%"] - } + BinaryArithmeticOperation() { this.getOperatorName() = ["+", "-", "*", "/", "%"] } } /** * An arithmetic assignment operation, such as `+=` or `*=`. */ -final class AssignArithmeticOperation extends BinaryExpr, ArithmeticOperationImpl { - AssignArithmeticOperation() { - this.getOperatorName() = ["+=", "-=", "*=", "/=", "%="] - } +final class AssignArithmeticOperation extends BinaryExpr, ArithmeticOperationImpl, + AssignmentOperation +{ + AssignArithmeticOperation() { this.getOperatorName() = ["+=", "-=", "*=", "/=", "%="] } } /** * A prefix arithmetic operation, such as `-`. */ final class PrefixArithmeticOperation extends PrefixExpr, ArithmeticOperationImpl { - PrefixArithmeticOperation() { - this.getOperatorName() = "-" - } + PrefixArithmeticOperation() { this.getOperatorName() = "-" } } diff --git a/rust/ql/lib/codeql/rust/elements/BitwiseOperation.qll b/rust/ql/lib/codeql/rust/elements/BitwiseOperation.qll index b906a2216ce..3c1f63158b6 100644 --- a/rust/ql/lib/codeql/rust/elements/BitwiseOperation.qll +++ b/rust/ql/lib/codeql/rust/elements/BitwiseOperation.qll @@ -4,6 +4,7 @@ private import codeql.rust.elements.BinaryExpr private import codeql.rust.elements.Operation +private import codeql.rust.elements.AssignmentOperation /** * A bitwise operation, such as `&`, `<<`, or `|=`. @@ -22,6 +23,6 @@ final class BinaryBitwiseOperation extends BinaryExpr, BitwiseOperationImpl { /** * A bitwise assignment operation, such as `|=` or `<<=`. */ -final class AssignBitwiseOperation extends BinaryExpr, BitwiseOperationImpl { +final class AssignBitwiseOperation extends BinaryExpr, BitwiseOperationImpl, AssignmentOperation { AssignBitwiseOperation() { this.getOperatorName() = ["&=", "|=", "^=", "<<=", ">>="] } } From 32cece3a43a72447a4c927eded79ba4875c10fdf Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 16 May 2025 16:14:51 +0200 Subject: [PATCH 39/86] Rust: adapt `BadCtorInitialization.ql` to attribute macro expansion --- .../security/CWE-696/BadCtorInitialization.ql | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql index 80364a9de06..75946d89e11 100644 --- a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql @@ -44,9 +44,18 @@ class PathElement = AstNode; * reachable from a source. */ predicate edgesFwd(PathElement pred, PathElement succ) { - // attribute (source) -> callable - pred.(CtorAttr) = succ.(Callable).getAnAttr() + // attribute (source) -> function in macro expansion + exists(Function f | + pred.(CtorAttr) = f.getAnAttr() and + ( + f.getAttributeMacroExpansion().getAnItem() = succ.(Callable) + or + // if for some reason the ctor/dtor macro expansion failed, fall back to looking into the unexpanded item + not f.hasAttributeMacroExpansion() and f = succ.(Callable) + ) + ) or + // callable -> callable attribute macro expansion // [forwards reachable] callable -> enclosed call edgesFwd(_, pred) and pred = succ.(CallExprBase).getEnclosingCallable() From abf21ba767e2a23c7ddeda6df33c36549f307da1 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 16 May 2025 16:15:03 +0200 Subject: [PATCH 40/86] Rust: skip macro expansion in unexpanded attribute macro AST --- .../templates/extractor.mustache | 8 +- rust/extractor/src/translate/base.rs | 51 +- rust/extractor/src/translate/generated.rs | 503 ++++++++++++------ 3 files changed, 383 insertions(+), 179 deletions(-) diff --git a/rust/ast-generator/templates/extractor.mustache b/rust/ast-generator/templates/extractor.mustache index c4f8dbd983d..d0c11bb78e0 100644 --- a/rust/ast-generator/templates/extractor.mustache +++ b/rust/ast-generator/templates/extractor.mustache @@ -2,7 +2,7 @@ use super::base::Translator; use super::mappings::TextValue; -use crate::emit_detached; +use crate::{pre_emit,post_emit}; use crate::generated; use crate::trap::{Label, TrapId}; use ra_ap_syntax::ast::{ @@ -22,18 +22,20 @@ impl Translator<'_> { {{#enums}} pub(crate) fn emit_{{snake_case_name}}(&mut self, node: &ast::{{ast_name}}) -> Option> { + pre_emit!({{name}}, self, node); let label = match node { {{#variants}} ast::{{ast_name}}::{{variant_ast_name}}(inner) => self.emit_{{snake_case_name}}(inner).map(Into::into), {{/variants}} }?; - emit_detached!({{name}}, self, node, label); + post_emit!({{name}}, self, node, label); Some(label) } {{/enums}} {{#nodes}} pub(crate) fn emit_{{snake_case_name}}(&mut self, node: &ast::{{ast_name}}) -> Option> { + pre_emit!({{name}}, self, node); {{#has_attrs}} if self.should_be_excluded(node) { return None; } {{/has_attrs}} @@ -58,7 +60,7 @@ impl Translator<'_> { {{/fields}} }); self.emit_location(label, node); - emit_detached!({{name}}, self, node, label); + post_emit!({{name}}, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } diff --git a/rust/extractor/src/translate/base.rs b/rust/extractor/src/translate/base.rs index d0e99e8a5b4..d1cec34242c 100644 --- a/rust/extractor/src/translate/base.rs +++ b/rust/extractor/src/translate/base.rs @@ -11,7 +11,7 @@ use ra_ap_hir::{ }; use ra_ap_hir_def::ModuleId; use ra_ap_hir_def::type_ref::Mutability; -use ra_ap_hir_expand::{ExpandResult, ExpandTo}; +use ra_ap_hir_expand::{ExpandResult, ExpandTo, InFile}; use ra_ap_ide_db::RootDatabase; use ra_ap_ide_db::line_index::{LineCol, LineIndex}; use ra_ap_parser::SyntaxKind; @@ -23,7 +23,15 @@ use ra_ap_syntax::{ }; #[macro_export] -macro_rules! emit_detached { +macro_rules! pre_emit { + (Item, $self:ident, $node:ident) => { + $self.setup_item_expansion($node); + }; + ($($_:tt)*) => {}; +} + +#[macro_export] +macro_rules! post_emit { (MacroCall, $self:ident, $node:ident, $label:ident) => { $self.extract_macro_call_expanded($node, $label); }; @@ -101,7 +109,8 @@ pub struct Translator<'a> { line_index: LineIndex, file_id: Option, pub semantics: Option<&'a Semantics<'a, RootDatabase>>, - resolve_paths: ResolvePaths, + resolve_paths: bool, + macro_context_depth: usize, } const UNKNOWN_LOCATION: (LineCol, LineCol) = @@ -123,7 +132,8 @@ impl<'a> Translator<'a> { line_index, file_id: semantic_info.map(|i| i.file_id), semantics: semantic_info.map(|i| i.semantics), - resolve_paths, + resolve_paths: resolve_paths == ResolvePaths::Yes, + macro_context_depth: 0, } } fn location(&self, range: TextRange) -> Option<(LineCol, LineCol)> { @@ -321,6 +331,11 @@ impl<'a> Translator<'a> { mcall: &ast::MacroCall, label: Label, ) { + if self.macro_context_depth > 0 { + // we are in an attribute macro, don't emit anything: we would be failing to expand any + // way as rust-analyser now only expands in the context of an expansion + return; + } if let Some(expanded) = self .semantics .as_ref() @@ -521,7 +536,7 @@ impl<'a> Translator<'a> { item: &T, label: Label, ) { - if self.resolve_paths == ResolvePaths::No { + if !self.resolve_paths { return; } (|| { @@ -544,7 +559,7 @@ impl<'a> Translator<'a> { item: &ast::Variant, label: Label, ) { - if self.resolve_paths == ResolvePaths::No { + if !self.resolve_paths { return; } (|| { @@ -567,7 +582,7 @@ impl<'a> Translator<'a> { item: &impl PathAst, label: Label, ) { - if self.resolve_paths == ResolvePaths::No { + if !self.resolve_paths { return; } (|| { @@ -590,7 +605,7 @@ impl<'a> Translator<'a> { item: &ast::MethodCallExpr, label: Label, ) { - if self.resolve_paths == ResolvePaths::No { + if !self.resolve_paths { return; } (|| { @@ -653,9 +668,29 @@ impl<'a> Translator<'a> { } } + pub(crate) fn setup_item_expansion(&mut self, node: &ast::Item) { + if self.semantics.is_some_and(|s| { + let file = s.hir_file_for(node.syntax()); + let node = InFile::new(file, node); + s.is_attr_macro_call(node) + }) { + self.macro_context_depth += 1; + } + } + pub(crate) fn emit_item_expansion(&mut self, node: &ast::Item, label: Label) { (|| { let semantics = self.semantics?; + let file = semantics.hir_file_for(node.syntax()); + let infile_node = InFile::new(file, node); + if !semantics.is_attr_macro_call(infile_node) { + return None; + } + self.macro_context_depth -= 1; + if self.macro_context_depth > 0 { + // only expand the outermost attribute macro + return None; + } let ExpandResult { value: expanded, .. } = semantics.expand_attr_macro(node)?; diff --git a/rust/extractor/src/translate/generated.rs b/rust/extractor/src/translate/generated.rs index 5002f09c4d8..fe8da75770c 100644 --- a/rust/extractor/src/translate/generated.rs +++ b/rust/extractor/src/translate/generated.rs @@ -1,9 +1,9 @@ //! Generated by `ast-generator`, do not edit by hand. use super::base::Translator; use super::mappings::TextValue; -use crate::emit_detached; use crate::generated; use crate::trap::{Label, TrapId}; +use crate::{post_emit, pre_emit}; use ra_ap_syntax::ast::{ HasArgList, HasAttrs, HasGenericArgs, HasGenericParams, HasLoopBody, HasModuleItem, HasName, HasTypeBounds, HasVisibility, RangeItem, @@ -21,6 +21,7 @@ impl Translator<'_> { &mut self, node: &ast::AsmOperand, ) -> Option> { + pre_emit!(AsmOperand, self, node); let label = match node { ast::AsmOperand::AsmConst(inner) => self.emit_asm_const(inner).map(Into::into), ast::AsmOperand::AsmLabel(inner) => self.emit_asm_label(inner).map(Into::into), @@ -29,13 +30,14 @@ impl Translator<'_> { } ast::AsmOperand::AsmSym(inner) => self.emit_asm_sym(inner).map(Into::into), }?; - emit_detached!(AsmOperand, self, node, label); + post_emit!(AsmOperand, self, node, label); Some(label) } pub(crate) fn emit_asm_piece( &mut self, node: &ast::AsmPiece, ) -> Option> { + pre_emit!(AsmPiece, self, node); let label = match node { ast::AsmPiece::AsmClobberAbi(inner) => self.emit_asm_clobber_abi(inner).map(Into::into), ast::AsmPiece::AsmOperandNamed(inner) => { @@ -43,23 +45,25 @@ impl Translator<'_> { } ast::AsmPiece::AsmOptions(inner) => self.emit_asm_options(inner).map(Into::into), }?; - emit_detached!(AsmPiece, self, node, label); + post_emit!(AsmPiece, self, node, label); Some(label) } pub(crate) fn emit_assoc_item( &mut self, node: &ast::AssocItem, ) -> Option> { + pre_emit!(AssocItem, self, node); let label = match node { ast::AssocItem::Const(inner) => self.emit_const(inner).map(Into::into), ast::AssocItem::Fn(inner) => self.emit_fn(inner).map(Into::into), ast::AssocItem::MacroCall(inner) => self.emit_macro_call(inner).map(Into::into), ast::AssocItem::TypeAlias(inner) => self.emit_type_alias(inner).map(Into::into), }?; - emit_detached!(AssocItem, self, node, label); + post_emit!(AssocItem, self, node, label); Some(label) } pub(crate) fn emit_expr(&mut self, node: &ast::Expr) -> Option> { + pre_emit!(Expr, self, node); let label = match node { ast::Expr::ArrayExpr(inner) => self.emit_array_expr(inner).map(Into::into), ast::Expr::AsmExpr(inner) => self.emit_asm_expr(inner).map(Into::into), @@ -98,26 +102,28 @@ impl Translator<'_> { ast::Expr::YeetExpr(inner) => self.emit_yeet_expr(inner).map(Into::into), ast::Expr::YieldExpr(inner) => self.emit_yield_expr(inner).map(Into::into), }?; - emit_detached!(Expr, self, node, label); + post_emit!(Expr, self, node, label); Some(label) } pub(crate) fn emit_extern_item( &mut self, node: &ast::ExternItem, ) -> Option> { + pre_emit!(ExternItem, self, node); let label = match node { ast::ExternItem::Fn(inner) => self.emit_fn(inner).map(Into::into), ast::ExternItem::MacroCall(inner) => self.emit_macro_call(inner).map(Into::into), ast::ExternItem::Static(inner) => self.emit_static(inner).map(Into::into), ast::ExternItem::TypeAlias(inner) => self.emit_type_alias(inner).map(Into::into), }?; - emit_detached!(ExternItem, self, node, label); + post_emit!(ExternItem, self, node, label); Some(label) } pub(crate) fn emit_field_list( &mut self, node: &ast::FieldList, ) -> Option> { + pre_emit!(FieldList, self, node); let label = match node { ast::FieldList::RecordFieldList(inner) => { self.emit_record_field_list(inner).map(Into::into) @@ -126,26 +132,28 @@ impl Translator<'_> { self.emit_tuple_field_list(inner).map(Into::into) } }?; - emit_detached!(FieldList, self, node, label); + post_emit!(FieldList, self, node, label); Some(label) } pub(crate) fn emit_generic_arg( &mut self, node: &ast::GenericArg, ) -> Option> { + pre_emit!(GenericArg, self, node); let label = match node { ast::GenericArg::AssocTypeArg(inner) => self.emit_assoc_type_arg(inner).map(Into::into), ast::GenericArg::ConstArg(inner) => self.emit_const_arg(inner).map(Into::into), ast::GenericArg::LifetimeArg(inner) => self.emit_lifetime_arg(inner).map(Into::into), ast::GenericArg::TypeArg(inner) => self.emit_type_arg(inner).map(Into::into), }?; - emit_detached!(GenericArg, self, node, label); + post_emit!(GenericArg, self, node, label); Some(label) } pub(crate) fn emit_generic_param( &mut self, node: &ast::GenericParam, ) -> Option> { + pre_emit!(GenericParam, self, node); let label = match node { ast::GenericParam::ConstParam(inner) => self.emit_const_param(inner).map(Into::into), ast::GenericParam::LifetimeParam(inner) => { @@ -153,10 +161,11 @@ impl Translator<'_> { } ast::GenericParam::TypeParam(inner) => self.emit_type_param(inner).map(Into::into), }?; - emit_detached!(GenericParam, self, node, label); + post_emit!(GenericParam, self, node, label); Some(label) } pub(crate) fn emit_pat(&mut self, node: &ast::Pat) -> Option> { + pre_emit!(Pat, self, node); let label = match node { ast::Pat::BoxPat(inner) => self.emit_box_pat(inner).map(Into::into), ast::Pat::ConstBlockPat(inner) => self.emit_const_block_pat(inner).map(Into::into), @@ -175,19 +184,21 @@ impl Translator<'_> { ast::Pat::TupleStructPat(inner) => self.emit_tuple_struct_pat(inner).map(Into::into), ast::Pat::WildcardPat(inner) => self.emit_wildcard_pat(inner).map(Into::into), }?; - emit_detached!(Pat, self, node, label); + post_emit!(Pat, self, node, label); Some(label) } pub(crate) fn emit_stmt(&mut self, node: &ast::Stmt) -> Option> { + pre_emit!(Stmt, self, node); let label = match node { ast::Stmt::ExprStmt(inner) => self.emit_expr_stmt(inner).map(Into::into), ast::Stmt::Item(inner) => self.emit_item(inner).map(Into::into), ast::Stmt::LetStmt(inner) => self.emit_let_stmt(inner).map(Into::into), }?; - emit_detached!(Stmt, self, node, label); + post_emit!(Stmt, self, node, label); Some(label) } pub(crate) fn emit_type(&mut self, node: &ast::Type) -> Option> { + pre_emit!(TypeRepr, self, node); let label = match node { ast::Type::ArrayType(inner) => self.emit_array_type(inner).map(Into::into), ast::Type::DynTraitType(inner) => self.emit_dyn_trait_type(inner).map(Into::into), @@ -204,21 +215,23 @@ impl Translator<'_> { ast::Type::SliceType(inner) => self.emit_slice_type(inner).map(Into::into), ast::Type::TupleType(inner) => self.emit_tuple_type(inner).map(Into::into), }?; - emit_detached!(TypeRepr, self, node, label); + post_emit!(TypeRepr, self, node, label); Some(label) } pub(crate) fn emit_use_bound_generic_arg( &mut self, node: &ast::UseBoundGenericArg, ) -> Option> { + pre_emit!(UseBoundGenericArg, self, node); let label = match node { ast::UseBoundGenericArg::Lifetime(inner) => self.emit_lifetime(inner).map(Into::into), ast::UseBoundGenericArg::NameRef(inner) => self.emit_name_ref(inner).map(Into::into), }?; - emit_detached!(UseBoundGenericArg, self, node, label); + post_emit!(UseBoundGenericArg, self, node, label); Some(label) } pub(crate) fn emit_item(&mut self, node: &ast::Item) -> Option> { + pre_emit!(Item, self, node); let label = match node { ast::Item::Const(inner) => self.emit_const(inner).map(Into::into), ast::Item::Enum(inner) => self.emit_enum(inner).map(Into::into), @@ -238,17 +251,18 @@ impl Translator<'_> { ast::Item::Union(inner) => self.emit_union(inner).map(Into::into), ast::Item::Use(inner) => self.emit_use(inner).map(Into::into), }?; - emit_detached!(Item, self, node, label); + post_emit!(Item, self, node, label); Some(label) } pub(crate) fn emit_abi(&mut self, node: &ast::Abi) -> Option> { + pre_emit!(Abi, self, node); let abi_string = node.try_get_text(); let label = self.trap.emit(generated::Abi { id: TrapId::Star, abi_string, }); self.emit_location(label, node); - emit_detached!(Abi, self, node, label); + post_emit!(Abi, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -256,13 +270,14 @@ impl Translator<'_> { &mut self, node: &ast::ArgList, ) -> Option> { + pre_emit!(ArgList, self, node); let args = node.args().filter_map(|x| self.emit_expr(&x)).collect(); let label = self.trap.emit(generated::ArgList { id: TrapId::Star, args, }); self.emit_location(label, node); - emit_detached!(ArgList, self, node, label); + post_emit!(ArgList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -270,6 +285,7 @@ impl Translator<'_> { &mut self, node: &ast::ArrayExpr, ) -> Option> { + pre_emit!(ArrayExprInternal, self, node); if self.should_be_excluded(node) { return None; } @@ -283,7 +299,7 @@ impl Translator<'_> { is_semicolon, }); self.emit_location(label, node); - emit_detached!(ArrayExprInternal, self, node, label); + post_emit!(ArrayExprInternal, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -291,6 +307,7 @@ impl Translator<'_> { &mut self, node: &ast::ArrayType, ) -> Option> { + pre_emit!(ArrayTypeRepr, self, node); let const_arg = node.const_arg().and_then(|x| self.emit_const_arg(&x)); let element_type_repr = node.ty().and_then(|x| self.emit_type(&x)); let label = self.trap.emit(generated::ArrayTypeRepr { @@ -299,7 +316,7 @@ impl Translator<'_> { element_type_repr, }); self.emit_location(label, node); - emit_detached!(ArrayTypeRepr, self, node, label); + post_emit!(ArrayTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -307,11 +324,12 @@ impl Translator<'_> { &mut self, node: &ast::AsmClobberAbi, ) -> Option> { + pre_emit!(AsmClobberAbi, self, node); let label = self .trap .emit(generated::AsmClobberAbi { id: TrapId::Star }); self.emit_location(label, node); - emit_detached!(AsmClobberAbi, self, node, label); + post_emit!(AsmClobberAbi, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -319,6 +337,7 @@ impl Translator<'_> { &mut self, node: &ast::AsmConst, ) -> Option> { + pre_emit!(AsmConst, self, node); let expr = node.expr().and_then(|x| self.emit_expr(&x)); let is_const = node.const_token().is_some(); let label = self.trap.emit(generated::AsmConst { @@ -327,7 +346,7 @@ impl Translator<'_> { is_const, }); self.emit_location(label, node); - emit_detached!(AsmConst, self, node, label); + post_emit!(AsmConst, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -335,9 +354,10 @@ impl Translator<'_> { &mut self, node: &ast::AsmDirSpec, ) -> Option> { + pre_emit!(AsmDirSpec, self, node); let label = self.trap.emit(generated::AsmDirSpec { id: TrapId::Star }); self.emit_location(label, node); - emit_detached!(AsmDirSpec, self, node, label); + post_emit!(AsmDirSpec, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -345,6 +365,7 @@ impl Translator<'_> { &mut self, node: &ast::AsmExpr, ) -> Option> { + pre_emit!(AsmExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -361,7 +382,7 @@ impl Translator<'_> { template, }); self.emit_location(label, node); - emit_detached!(AsmExpr, self, node, label); + post_emit!(AsmExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -369,13 +390,14 @@ impl Translator<'_> { &mut self, node: &ast::AsmLabel, ) -> Option> { + pre_emit!(AsmLabel, self, node); let block_expr = node.block_expr().and_then(|x| self.emit_block_expr(&x)); let label = self.trap.emit(generated::AsmLabel { id: TrapId::Star, block_expr, }); self.emit_location(label, node); - emit_detached!(AsmLabel, self, node, label); + post_emit!(AsmLabel, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -383,6 +405,7 @@ impl Translator<'_> { &mut self, node: &ast::AsmOperandExpr, ) -> Option> { + pre_emit!(AsmOperandExpr, self, node); let in_expr = node.in_expr().and_then(|x| self.emit_expr(&x)); let out_expr = node.out_expr().and_then(|x| self.emit_expr(&x)); let label = self.trap.emit(generated::AsmOperandExpr { @@ -391,7 +414,7 @@ impl Translator<'_> { out_expr, }); self.emit_location(label, node); - emit_detached!(AsmOperandExpr, self, node, label); + post_emit!(AsmOperandExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -399,6 +422,7 @@ impl Translator<'_> { &mut self, node: &ast::AsmOperandNamed, ) -> Option> { + pre_emit!(AsmOperandNamed, self, node); let asm_operand = node.asm_operand().and_then(|x| self.emit_asm_operand(&x)); let name = node.name().and_then(|x| self.emit_name(&x)); let label = self.trap.emit(generated::AsmOperandNamed { @@ -407,7 +431,7 @@ impl Translator<'_> { name, }); self.emit_location(label, node); - emit_detached!(AsmOperandNamed, self, node, label); + post_emit!(AsmOperandNamed, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -415,13 +439,14 @@ impl Translator<'_> { &mut self, node: &ast::AsmOption, ) -> Option> { + pre_emit!(AsmOption, self, node); let is_raw = node.raw_token().is_some(); let label = self.trap.emit(generated::AsmOption { id: TrapId::Star, is_raw, }); self.emit_location(label, node); - emit_detached!(AsmOption, self, node, label); + post_emit!(AsmOption, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -429,6 +454,7 @@ impl Translator<'_> { &mut self, node: &ast::AsmOptions, ) -> Option> { + pre_emit!(AsmOptionsList, self, node); let asm_options = node .asm_options() .filter_map(|x| self.emit_asm_option(&x)) @@ -438,7 +464,7 @@ impl Translator<'_> { asm_options, }); self.emit_location(label, node); - emit_detached!(AsmOptionsList, self, node, label); + post_emit!(AsmOptionsList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -446,6 +472,7 @@ impl Translator<'_> { &mut self, node: &ast::AsmRegOperand, ) -> Option> { + pre_emit!(AsmRegOperand, self, node); let asm_dir_spec = node.asm_dir_spec().and_then(|x| self.emit_asm_dir_spec(&x)); let asm_operand_expr = node .asm_operand_expr() @@ -458,7 +485,7 @@ impl Translator<'_> { asm_reg_spec, }); self.emit_location(label, node); - emit_detached!(AsmRegOperand, self, node, label); + post_emit!(AsmRegOperand, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -466,24 +493,26 @@ impl Translator<'_> { &mut self, node: &ast::AsmRegSpec, ) -> Option> { + pre_emit!(AsmRegSpec, self, node); let identifier = node.name_ref().and_then(|x| self.emit_name_ref(&x)); let label = self.trap.emit(generated::AsmRegSpec { id: TrapId::Star, identifier, }); self.emit_location(label, node); - emit_detached!(AsmRegSpec, self, node, label); + post_emit!(AsmRegSpec, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_asm_sym(&mut self, node: &ast::AsmSym) -> Option> { + pre_emit!(AsmSym, self, node); let path = node.path().and_then(|x| self.emit_path(&x)); let label = self.trap.emit(generated::AsmSym { id: TrapId::Star, path, }); self.emit_location(label, node); - emit_detached!(AsmSym, self, node, label); + post_emit!(AsmSym, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -491,6 +520,7 @@ impl Translator<'_> { &mut self, node: &ast::AssocItemList, ) -> Option> { + pre_emit!(AssocItemList, self, node); if self.should_be_excluded(node) { return None; } @@ -505,7 +535,7 @@ impl Translator<'_> { attrs, }); self.emit_location(label, node); - emit_detached!(AssocItemList, self, node, label); + post_emit!(AssocItemList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -513,6 +543,7 @@ impl Translator<'_> { &mut self, node: &ast::AssocTypeArg, ) -> Option> { + pre_emit!(AssocTypeArg, self, node); let const_arg = node.const_arg().and_then(|x| self.emit_const_arg(&x)); let generic_arg_list = node .generic_arg_list() @@ -539,18 +570,19 @@ impl Translator<'_> { type_bound_list, }); self.emit_location(label, node); - emit_detached!(AssocTypeArg, self, node, label); + post_emit!(AssocTypeArg, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_attr(&mut self, node: &ast::Attr) -> Option> { + pre_emit!(Attr, self, node); let meta = node.meta().and_then(|x| self.emit_meta(&x)); let label = self.trap.emit(generated::Attr { id: TrapId::Star, meta, }); self.emit_location(label, node); - emit_detached!(Attr, self, node, label); + post_emit!(Attr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -558,6 +590,7 @@ impl Translator<'_> { &mut self, node: &ast::AwaitExpr, ) -> Option> { + pre_emit!(AwaitExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -569,7 +602,7 @@ impl Translator<'_> { expr, }); self.emit_location(label, node); - emit_detached!(AwaitExpr, self, node, label); + post_emit!(AwaitExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -577,6 +610,7 @@ impl Translator<'_> { &mut self, node: &ast::BecomeExpr, ) -> Option> { + pre_emit!(BecomeExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -588,7 +622,7 @@ impl Translator<'_> { expr, }); self.emit_location(label, node); - emit_detached!(BecomeExpr, self, node, label); + post_emit!(BecomeExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -596,6 +630,7 @@ impl Translator<'_> { &mut self, node: &ast::BinExpr, ) -> Option> { + pre_emit!(BinaryExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -611,7 +646,7 @@ impl Translator<'_> { rhs, }); self.emit_location(label, node); - emit_detached!(BinaryExpr, self, node, label); + post_emit!(BinaryExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -619,6 +654,7 @@ impl Translator<'_> { &mut self, node: &ast::BlockExpr, ) -> Option> { + pre_emit!(BlockExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -644,18 +680,19 @@ impl Translator<'_> { stmt_list, }); self.emit_location(label, node); - emit_detached!(BlockExpr, self, node, label); + post_emit!(BlockExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_box_pat(&mut self, node: &ast::BoxPat) -> Option> { + pre_emit!(BoxPat, self, node); let pat = node.pat().and_then(|x| self.emit_pat(&x)); let label = self.trap.emit(generated::BoxPat { id: TrapId::Star, pat, }); self.emit_location(label, node); - emit_detached!(BoxPat, self, node, label); + post_emit!(BoxPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -663,6 +700,7 @@ impl Translator<'_> { &mut self, node: &ast::BreakExpr, ) -> Option> { + pre_emit!(BreakExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -676,7 +714,7 @@ impl Translator<'_> { lifetime, }); self.emit_location(label, node); - emit_detached!(BreakExpr, self, node, label); + post_emit!(BreakExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -684,6 +722,7 @@ impl Translator<'_> { &mut self, node: &ast::CallExpr, ) -> Option> { + pre_emit!(CallExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -697,7 +736,7 @@ impl Translator<'_> { function, }); self.emit_location(label, node); - emit_detached!(CallExpr, self, node, label); + post_emit!(CallExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -705,6 +744,7 @@ impl Translator<'_> { &mut self, node: &ast::CastExpr, ) -> Option> { + pre_emit!(CastExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -718,7 +758,7 @@ impl Translator<'_> { type_repr, }); self.emit_location(label, node); - emit_detached!(CastExpr, self, node, label); + post_emit!(CastExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -726,6 +766,7 @@ impl Translator<'_> { &mut self, node: &ast::ClosureBinder, ) -> Option> { + pre_emit!(ClosureBinder, self, node); let generic_param_list = node .generic_param_list() .and_then(|x| self.emit_generic_param_list(&x)); @@ -734,7 +775,7 @@ impl Translator<'_> { generic_param_list, }); self.emit_location(label, node); - emit_detached!(ClosureBinder, self, node, label); + post_emit!(ClosureBinder, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -742,6 +783,7 @@ impl Translator<'_> { &mut self, node: &ast::ClosureExpr, ) -> Option> { + pre_emit!(ClosureExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -771,11 +813,12 @@ impl Translator<'_> { ret_type, }); self.emit_location(label, node); - emit_detached!(ClosureExpr, self, node, label); + post_emit!(ClosureExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_const(&mut self, node: &ast::Const) -> Option> { + pre_emit!(Const, self, node); if self.should_be_excluded(node) { return None; } @@ -797,7 +840,7 @@ impl Translator<'_> { visibility, }); self.emit_location(label, node); - emit_detached!(Const, self, node, label); + post_emit!(Const, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -805,13 +848,14 @@ impl Translator<'_> { &mut self, node: &ast::ConstArg, ) -> Option> { + pre_emit!(ConstArg, self, node); let expr = node.expr().and_then(|x| self.emit_expr(&x)); let label = self.trap.emit(generated::ConstArg { id: TrapId::Star, expr, }); self.emit_location(label, node); - emit_detached!(ConstArg, self, node, label); + post_emit!(ConstArg, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -819,6 +863,7 @@ impl Translator<'_> { &mut self, node: &ast::ConstBlockPat, ) -> Option> { + pre_emit!(ConstBlockPat, self, node); let block_expr = node.block_expr().and_then(|x| self.emit_block_expr(&x)); let is_const = node.const_token().is_some(); let label = self.trap.emit(generated::ConstBlockPat { @@ -827,7 +872,7 @@ impl Translator<'_> { is_const, }); self.emit_location(label, node); - emit_detached!(ConstBlockPat, self, node, label); + post_emit!(ConstBlockPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -835,6 +880,7 @@ impl Translator<'_> { &mut self, node: &ast::ConstParam, ) -> Option> { + pre_emit!(ConstParam, self, node); if self.should_be_excluded(node) { return None; } @@ -852,7 +898,7 @@ impl Translator<'_> { type_repr, }); self.emit_location(label, node); - emit_detached!(ConstParam, self, node, label); + post_emit!(ConstParam, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -860,6 +906,7 @@ impl Translator<'_> { &mut self, node: &ast::ContinueExpr, ) -> Option> { + pre_emit!(ContinueExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -871,7 +918,7 @@ impl Translator<'_> { lifetime, }); self.emit_location(label, node); - emit_detached!(ContinueExpr, self, node, label); + post_emit!(ContinueExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -879,6 +926,7 @@ impl Translator<'_> { &mut self, node: &ast::DynTraitType, ) -> Option> { + pre_emit!(DynTraitTypeRepr, self, node); let type_bound_list = node .type_bound_list() .and_then(|x| self.emit_type_bound_list(&x)); @@ -887,11 +935,12 @@ impl Translator<'_> { type_bound_list, }); self.emit_location(label, node); - emit_detached!(DynTraitTypeRepr, self, node, label); + post_emit!(DynTraitTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_enum(&mut self, node: &ast::Enum) -> Option> { + pre_emit!(Enum, self, node); if self.should_be_excluded(node) { return None; } @@ -913,7 +962,7 @@ impl Translator<'_> { where_clause, }); self.emit_location(label, node); - emit_detached!(Enum, self, node, label); + post_emit!(Enum, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -921,13 +970,14 @@ impl Translator<'_> { &mut self, node: &ast::ExprStmt, ) -> Option> { + pre_emit!(ExprStmt, self, node); let expr = node.expr().and_then(|x| self.emit_expr(&x)); let label = self.trap.emit(generated::ExprStmt { id: TrapId::Star, expr, }); self.emit_location(label, node); - emit_detached!(ExprStmt, self, node, label); + post_emit!(ExprStmt, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -935,6 +985,7 @@ impl Translator<'_> { &mut self, node: &ast::ExternBlock, ) -> Option> { + pre_emit!(ExternBlock, self, node); if self.should_be_excluded(node) { return None; } @@ -952,7 +1003,7 @@ impl Translator<'_> { is_unsafe, }); self.emit_location(label, node); - emit_detached!(ExternBlock, self, node, label); + post_emit!(ExternBlock, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -960,6 +1011,7 @@ impl Translator<'_> { &mut self, node: &ast::ExternCrate, ) -> Option> { + pre_emit!(ExternCrate, self, node); if self.should_be_excluded(node) { return None; } @@ -975,7 +1027,7 @@ impl Translator<'_> { visibility, }); self.emit_location(label, node); - emit_detached!(ExternCrate, self, node, label); + post_emit!(ExternCrate, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -983,6 +1035,7 @@ impl Translator<'_> { &mut self, node: &ast::ExternItemList, ) -> Option> { + pre_emit!(ExternItemList, self, node); if self.should_be_excluded(node) { return None; } @@ -997,7 +1050,7 @@ impl Translator<'_> { extern_items, }); self.emit_location(label, node); - emit_detached!(ExternItemList, self, node, label); + post_emit!(ExternItemList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1005,6 +1058,7 @@ impl Translator<'_> { &mut self, node: &ast::FieldExpr, ) -> Option> { + pre_emit!(FieldExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1018,11 +1072,12 @@ impl Translator<'_> { identifier, }); self.emit_location(label, node); - emit_detached!(FieldExpr, self, node, label); + post_emit!(FieldExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_fn(&mut self, node: &ast::Fn) -> Option> { + pre_emit!(Function, self, node); if self.should_be_excluded(node) { return None; } @@ -1060,7 +1115,7 @@ impl Translator<'_> { where_clause, }); self.emit_location(label, node); - emit_detached!(Function, self, node, label); + post_emit!(Function, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1068,6 +1123,7 @@ impl Translator<'_> { &mut self, node: &ast::FnPtrType, ) -> Option> { + pre_emit!(FnPtrTypeRepr, self, node); let abi = node.abi().and_then(|x| self.emit_abi(&x)); let is_async = node.async_token().is_some(); let is_const = node.const_token().is_some(); @@ -1084,7 +1140,7 @@ impl Translator<'_> { ret_type, }); self.emit_location(label, node); - emit_detached!(FnPtrTypeRepr, self, node, label); + post_emit!(FnPtrTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1092,6 +1148,7 @@ impl Translator<'_> { &mut self, node: &ast::ForExpr, ) -> Option> { + pre_emit!(ForExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1109,7 +1166,7 @@ impl Translator<'_> { pat, }); self.emit_location(label, node); - emit_detached!(ForExpr, self, node, label); + post_emit!(ForExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1117,6 +1174,7 @@ impl Translator<'_> { &mut self, node: &ast::ForType, ) -> Option> { + pre_emit!(ForTypeRepr, self, node); let generic_param_list = node .generic_param_list() .and_then(|x| self.emit_generic_param_list(&x)); @@ -1127,7 +1185,7 @@ impl Translator<'_> { type_repr, }); self.emit_location(label, node); - emit_detached!(ForTypeRepr, self, node, label); + post_emit!(ForTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1135,6 +1193,7 @@ impl Translator<'_> { &mut self, node: &ast::FormatArgsArg, ) -> Option> { + pre_emit!(FormatArgsArg, self, node); let expr = node.expr().and_then(|x| self.emit_expr(&x)); let name = node.name().and_then(|x| self.emit_name(&x)); let label = self.trap.emit(generated::FormatArgsArg { @@ -1143,7 +1202,7 @@ impl Translator<'_> { name, }); self.emit_location(label, node); - emit_detached!(FormatArgsArg, self, node, label); + post_emit!(FormatArgsArg, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1151,6 +1210,7 @@ impl Translator<'_> { &mut self, node: &ast::FormatArgsExpr, ) -> Option> { + pre_emit!(FormatArgsExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1167,7 +1227,7 @@ impl Translator<'_> { template, }); self.emit_location(label, node); - emit_detached!(FormatArgsExpr, self, node, label); + post_emit!(FormatArgsExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1175,6 +1235,7 @@ impl Translator<'_> { &mut self, node: &ast::GenericArgList, ) -> Option> { + pre_emit!(GenericArgList, self, node); let generic_args = node .generic_args() .filter_map(|x| self.emit_generic_arg(&x)) @@ -1184,7 +1245,7 @@ impl Translator<'_> { generic_args, }); self.emit_location(label, node); - emit_detached!(GenericArgList, self, node, label); + post_emit!(GenericArgList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1192,6 +1253,7 @@ impl Translator<'_> { &mut self, node: &ast::GenericParamList, ) -> Option> { + pre_emit!(GenericParamList, self, node); let generic_params = node .generic_params() .filter_map(|x| self.emit_generic_param(&x)) @@ -1201,7 +1263,7 @@ impl Translator<'_> { generic_params, }); self.emit_location(label, node); - emit_detached!(GenericParamList, self, node, label); + post_emit!(GenericParamList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1209,6 +1271,7 @@ impl Translator<'_> { &mut self, node: &ast::IdentPat, ) -> Option> { + pre_emit!(IdentPat, self, node); if self.should_be_excluded(node) { return None; } @@ -1226,11 +1289,12 @@ impl Translator<'_> { pat, }); self.emit_location(label, node); - emit_detached!(IdentPat, self, node, label); + post_emit!(IdentPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_if_expr(&mut self, node: &ast::IfExpr) -> Option> { + pre_emit!(IfExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1246,11 +1310,12 @@ impl Translator<'_> { then, }); self.emit_location(label, node); - emit_detached!(IfExpr, self, node, label); + post_emit!(IfExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_impl(&mut self, node: &ast::Impl) -> Option> { + pre_emit!(Impl, self, node); if self.should_be_excluded(node) { return None; } @@ -1282,7 +1347,7 @@ impl Translator<'_> { where_clause, }); self.emit_location(label, node); - emit_detached!(Impl, self, node, label); + post_emit!(Impl, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1290,6 +1355,7 @@ impl Translator<'_> { &mut self, node: &ast::ImplTraitType, ) -> Option> { + pre_emit!(ImplTraitTypeRepr, self, node); let type_bound_list = node .type_bound_list() .and_then(|x| self.emit_type_bound_list(&x)); @@ -1298,7 +1364,7 @@ impl Translator<'_> { type_bound_list, }); self.emit_location(label, node); - emit_detached!(ImplTraitTypeRepr, self, node, label); + post_emit!(ImplTraitTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1306,6 +1372,7 @@ impl Translator<'_> { &mut self, node: &ast::IndexExpr, ) -> Option> { + pre_emit!(IndexExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1319,7 +1386,7 @@ impl Translator<'_> { index, }); self.emit_location(label, node); - emit_detached!(IndexExpr, self, node, label); + post_emit!(IndexExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1327,11 +1394,12 @@ impl Translator<'_> { &mut self, node: &ast::InferType, ) -> Option> { + pre_emit!(InferTypeRepr, self, node); let label = self .trap .emit(generated::InferTypeRepr { id: TrapId::Star }); self.emit_location(label, node); - emit_detached!(InferTypeRepr, self, node, label); + post_emit!(InferTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1339,6 +1407,7 @@ impl Translator<'_> { &mut self, node: &ast::ItemList, ) -> Option> { + pre_emit!(ItemList, self, node); if self.should_be_excluded(node) { return None; } @@ -1350,18 +1419,19 @@ impl Translator<'_> { items, }); self.emit_location(label, node); - emit_detached!(ItemList, self, node, label); + post_emit!(ItemList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_label(&mut self, node: &ast::Label) -> Option> { + pre_emit!(Label, self, node); let lifetime = node.lifetime().and_then(|x| self.emit_lifetime(&x)); let label = self.trap.emit(generated::Label { id: TrapId::Star, lifetime, }); self.emit_location(label, node); - emit_detached!(Label, self, node, label); + post_emit!(Label, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1369,13 +1439,14 @@ impl Translator<'_> { &mut self, node: &ast::LetElse, ) -> Option> { + pre_emit!(LetElse, self, node); let block_expr = node.block_expr().and_then(|x| self.emit_block_expr(&x)); let label = self.trap.emit(generated::LetElse { id: TrapId::Star, block_expr, }); self.emit_location(label, node); - emit_detached!(LetElse, self, node, label); + post_emit!(LetElse, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1383,6 +1454,7 @@ impl Translator<'_> { &mut self, node: &ast::LetExpr, ) -> Option> { + pre_emit!(LetExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1396,7 +1468,7 @@ impl Translator<'_> { pat, }); self.emit_location(label, node); - emit_detached!(LetExpr, self, node, label); + post_emit!(LetExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1404,6 +1476,7 @@ impl Translator<'_> { &mut self, node: &ast::LetStmt, ) -> Option> { + pre_emit!(LetStmt, self, node); if self.should_be_excluded(node) { return None; } @@ -1421,7 +1494,7 @@ impl Translator<'_> { type_repr, }); self.emit_location(label, node); - emit_detached!(LetStmt, self, node, label); + post_emit!(LetStmt, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1429,13 +1502,14 @@ impl Translator<'_> { &mut self, node: &ast::Lifetime, ) -> Option> { + pre_emit!(Lifetime, self, node); let text = node.try_get_text(); let label = self.trap.emit(generated::Lifetime { id: TrapId::Star, text, }); self.emit_location(label, node); - emit_detached!(Lifetime, self, node, label); + post_emit!(Lifetime, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1443,13 +1517,14 @@ impl Translator<'_> { &mut self, node: &ast::LifetimeArg, ) -> Option> { + pre_emit!(LifetimeArg, self, node); let lifetime = node.lifetime().and_then(|x| self.emit_lifetime(&x)); let label = self.trap.emit(generated::LifetimeArg { id: TrapId::Star, lifetime, }); self.emit_location(label, node); - emit_detached!(LifetimeArg, self, node, label); + post_emit!(LifetimeArg, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1457,6 +1532,7 @@ impl Translator<'_> { &mut self, node: &ast::LifetimeParam, ) -> Option> { + pre_emit!(LifetimeParam, self, node); if self.should_be_excluded(node) { return None; } @@ -1472,7 +1548,7 @@ impl Translator<'_> { type_bound_list, }); self.emit_location(label, node); - emit_detached!(LifetimeParam, self, node, label); + post_emit!(LifetimeParam, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1480,6 +1556,7 @@ impl Translator<'_> { &mut self, node: &ast::Literal, ) -> Option> { + pre_emit!(LiteralExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1491,7 +1568,7 @@ impl Translator<'_> { text_value, }); self.emit_location(label, node); - emit_detached!(LiteralExpr, self, node, label); + post_emit!(LiteralExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1499,13 +1576,14 @@ impl Translator<'_> { &mut self, node: &ast::LiteralPat, ) -> Option> { + pre_emit!(LiteralPat, self, node); let literal = node.literal().and_then(|x| self.emit_literal(&x)); let label = self.trap.emit(generated::LiteralPat { id: TrapId::Star, literal, }); self.emit_location(label, node); - emit_detached!(LiteralPat, self, node, label); + post_emit!(LiteralPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1513,6 +1591,7 @@ impl Translator<'_> { &mut self, node: &ast::LoopExpr, ) -> Option> { + pre_emit!(LoopExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1526,7 +1605,7 @@ impl Translator<'_> { loop_body, }); self.emit_location(label, node); - emit_detached!(LoopExpr, self, node, label); + post_emit!(LoopExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1534,6 +1613,7 @@ impl Translator<'_> { &mut self, node: &ast::MacroCall, ) -> Option> { + pre_emit!(MacroCall, self, node); if self.should_be_excluded(node) { return None; } @@ -1547,7 +1627,7 @@ impl Translator<'_> { token_tree, }); self.emit_location(label, node); - emit_detached!(MacroCall, self, node, label); + post_emit!(MacroCall, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1555,6 +1635,7 @@ impl Translator<'_> { &mut self, node: &ast::MacroDef, ) -> Option> { + pre_emit!(MacroDef, self, node); if self.should_be_excluded(node) { return None; } @@ -1572,7 +1653,7 @@ impl Translator<'_> { visibility, }); self.emit_location(label, node); - emit_detached!(MacroDef, self, node, label); + post_emit!(MacroDef, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1580,13 +1661,14 @@ impl Translator<'_> { &mut self, node: &ast::MacroExpr, ) -> Option> { + pre_emit!(MacroExpr, self, node); let macro_call = node.macro_call().and_then(|x| self.emit_macro_call(&x)); let label = self.trap.emit(generated::MacroExpr { id: TrapId::Star, macro_call, }); self.emit_location(label, node); - emit_detached!(MacroExpr, self, node, label); + post_emit!(MacroExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1594,13 +1676,14 @@ impl Translator<'_> { &mut self, node: &ast::MacroItems, ) -> Option> { + pre_emit!(MacroItems, self, node); let items = node.items().filter_map(|x| self.emit_item(&x)).collect(); let label = self.trap.emit(generated::MacroItems { id: TrapId::Star, items, }); self.emit_location(label, node); - emit_detached!(MacroItems, self, node, label); + post_emit!(MacroItems, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1608,13 +1691,14 @@ impl Translator<'_> { &mut self, node: &ast::MacroPat, ) -> Option> { + pre_emit!(MacroPat, self, node); let macro_call = node.macro_call().and_then(|x| self.emit_macro_call(&x)); let label = self.trap.emit(generated::MacroPat { id: TrapId::Star, macro_call, }); self.emit_location(label, node); - emit_detached!(MacroPat, self, node, label); + post_emit!(MacroPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1622,6 +1706,7 @@ impl Translator<'_> { &mut self, node: &ast::MacroRules, ) -> Option> { + pre_emit!(MacroRules, self, node); if self.should_be_excluded(node) { return None; } @@ -1637,7 +1722,7 @@ impl Translator<'_> { visibility, }); self.emit_location(label, node); - emit_detached!(MacroRules, self, node, label); + post_emit!(MacroRules, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1645,6 +1730,7 @@ impl Translator<'_> { &mut self, node: &ast::MacroStmts, ) -> Option> { + pre_emit!(MacroBlockExpr, self, node); let tail_expr = node.expr().and_then(|x| self.emit_expr(&x)); let statements = node .statements() @@ -1656,7 +1742,7 @@ impl Translator<'_> { statements, }); self.emit_location(label, node); - emit_detached!(MacroBlockExpr, self, node, label); + post_emit!(MacroBlockExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1664,13 +1750,14 @@ impl Translator<'_> { &mut self, node: &ast::MacroType, ) -> Option> { + pre_emit!(MacroTypeRepr, self, node); let macro_call = node.macro_call().and_then(|x| self.emit_macro_call(&x)); let label = self.trap.emit(generated::MacroTypeRepr { id: TrapId::Star, macro_call, }); self.emit_location(label, node); - emit_detached!(MacroTypeRepr, self, node, label); + post_emit!(MacroTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1678,6 +1765,7 @@ impl Translator<'_> { &mut self, node: &ast::MatchArm, ) -> Option> { + pre_emit!(MatchArm, self, node); if self.should_be_excluded(node) { return None; } @@ -1693,7 +1781,7 @@ impl Translator<'_> { pat, }); self.emit_location(label, node); - emit_detached!(MatchArm, self, node, label); + post_emit!(MatchArm, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1701,6 +1789,7 @@ impl Translator<'_> { &mut self, node: &ast::MatchArmList, ) -> Option> { + pre_emit!(MatchArmList, self, node); if self.should_be_excluded(node) { return None; } @@ -1715,7 +1804,7 @@ impl Translator<'_> { attrs, }); self.emit_location(label, node); - emit_detached!(MatchArmList, self, node, label); + post_emit!(MatchArmList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1723,6 +1812,7 @@ impl Translator<'_> { &mut self, node: &ast::MatchExpr, ) -> Option> { + pre_emit!(MatchExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1738,7 +1828,7 @@ impl Translator<'_> { match_arm_list, }); self.emit_location(label, node); - emit_detached!(MatchExpr, self, node, label); + post_emit!(MatchExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1746,17 +1836,19 @@ impl Translator<'_> { &mut self, node: &ast::MatchGuard, ) -> Option> { + pre_emit!(MatchGuard, self, node); let condition = node.condition().and_then(|x| self.emit_expr(&x)); let label = self.trap.emit(generated::MatchGuard { id: TrapId::Star, condition, }); self.emit_location(label, node); - emit_detached!(MatchGuard, self, node, label); + post_emit!(MatchGuard, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_meta(&mut self, node: &ast::Meta) -> Option> { + pre_emit!(Meta, self, node); let expr = node.expr().and_then(|x| self.emit_expr(&x)); let is_unsafe = node.unsafe_token().is_some(); let path = node.path().and_then(|x| self.emit_path(&x)); @@ -1769,7 +1861,7 @@ impl Translator<'_> { token_tree, }); self.emit_location(label, node); - emit_detached!(Meta, self, node, label); + post_emit!(Meta, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1777,6 +1869,7 @@ impl Translator<'_> { &mut self, node: &ast::MethodCallExpr, ) -> Option> { + pre_emit!(MethodCallExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1796,11 +1889,12 @@ impl Translator<'_> { receiver, }); self.emit_location(label, node); - emit_detached!(MethodCallExpr, self, node, label); + post_emit!(MethodCallExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_module(&mut self, node: &ast::Module) -> Option> { + pre_emit!(Module, self, node); if self.should_be_excluded(node) { return None; } @@ -1816,18 +1910,19 @@ impl Translator<'_> { visibility, }); self.emit_location(label, node); - emit_detached!(Module, self, node, label); + post_emit!(Module, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_name(&mut self, node: &ast::Name) -> Option> { + pre_emit!(Name, self, node); let text = node.try_get_text(); let label = self.trap.emit(generated::Name { id: TrapId::Star, text, }); self.emit_location(label, node); - emit_detached!(Name, self, node, label); + post_emit!(Name, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1835,13 +1930,14 @@ impl Translator<'_> { &mut self, node: &ast::NameRef, ) -> Option> { + pre_emit!(NameRef, self, node); let text = node.try_get_text(); let label = self.trap.emit(generated::NameRef { id: TrapId::Star, text, }); self.emit_location(label, node); - emit_detached!(NameRef, self, node, label); + post_emit!(NameRef, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1849,11 +1945,12 @@ impl Translator<'_> { &mut self, node: &ast::NeverType, ) -> Option> { + pre_emit!(NeverTypeRepr, self, node); let label = self .trap .emit(generated::NeverTypeRepr { id: TrapId::Star }); self.emit_location(label, node); - emit_detached!(NeverTypeRepr, self, node, label); + post_emit!(NeverTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1861,6 +1958,7 @@ impl Translator<'_> { &mut self, node: &ast::OffsetOfExpr, ) -> Option> { + pre_emit!(OffsetOfExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1877,22 +1975,24 @@ impl Translator<'_> { type_repr, }); self.emit_location(label, node); - emit_detached!(OffsetOfExpr, self, node, label); + post_emit!(OffsetOfExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_or_pat(&mut self, node: &ast::OrPat) -> Option> { + pre_emit!(OrPat, self, node); let pats = node.pats().filter_map(|x| self.emit_pat(&x)).collect(); let label = self.trap.emit(generated::OrPat { id: TrapId::Star, pats, }); self.emit_location(label, node); - emit_detached!(OrPat, self, node, label); + post_emit!(OrPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_param(&mut self, node: &ast::Param) -> Option> { + pre_emit!(Param, self, node); if self.should_be_excluded(node) { return None; } @@ -1906,7 +2006,7 @@ impl Translator<'_> { type_repr, }); self.emit_location(label, node); - emit_detached!(Param, self, node, label); + post_emit!(Param, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1914,6 +2014,7 @@ impl Translator<'_> { &mut self, node: &ast::ParamList, ) -> Option> { + pre_emit!(ParamList, self, node); let params = node.params().filter_map(|x| self.emit_param(&x)).collect(); let self_param = node.self_param().and_then(|x| self.emit_self_param(&x)); let label = self.trap.emit(generated::ParamList { @@ -1922,7 +2023,7 @@ impl Translator<'_> { self_param, }); self.emit_location(label, node); - emit_detached!(ParamList, self, node, label); + post_emit!(ParamList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1930,6 +2031,7 @@ impl Translator<'_> { &mut self, node: &ast::ParenExpr, ) -> Option> { + pre_emit!(ParenExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -1941,7 +2043,7 @@ impl Translator<'_> { expr, }); self.emit_location(label, node); - emit_detached!(ParenExpr, self, node, label); + post_emit!(ParenExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1949,13 +2051,14 @@ impl Translator<'_> { &mut self, node: &ast::ParenPat, ) -> Option> { + pre_emit!(ParenPat, self, node); let pat = node.pat().and_then(|x| self.emit_pat(&x)); let label = self.trap.emit(generated::ParenPat { id: TrapId::Star, pat, }); self.emit_location(label, node); - emit_detached!(ParenPat, self, node, label); + post_emit!(ParenPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1963,13 +2066,14 @@ impl Translator<'_> { &mut self, node: &ast::ParenType, ) -> Option> { + pre_emit!(ParenTypeRepr, self, node); let type_repr = node.ty().and_then(|x| self.emit_type(&x)); let label = self.trap.emit(generated::ParenTypeRepr { id: TrapId::Star, type_repr, }); self.emit_location(label, node); - emit_detached!(ParenTypeRepr, self, node, label); + post_emit!(ParenTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -1977,6 +2081,7 @@ impl Translator<'_> { &mut self, node: &ast::ParenthesizedArgList, ) -> Option> { + pre_emit!(ParenthesizedArgList, self, node); let type_args = node .type_args() .filter_map(|x| self.emit_type_arg(&x)) @@ -1986,11 +2091,12 @@ impl Translator<'_> { type_args, }); self.emit_location(label, node); - emit_detached!(ParenthesizedArgList, self, node, label); + post_emit!(ParenthesizedArgList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_path(&mut self, node: &ast::Path) -> Option> { + pre_emit!(Path, self, node); let qualifier = node.qualifier().and_then(|x| self.emit_path(&x)); let segment = node.segment().and_then(|x| self.emit_path_segment(&x)); let label = self.trap.emit(generated::Path { @@ -1999,7 +2105,7 @@ impl Translator<'_> { segment, }); self.emit_location(label, node); - emit_detached!(Path, self, node, label); + post_emit!(Path, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2007,6 +2113,7 @@ impl Translator<'_> { &mut self, node: &ast::PathExpr, ) -> Option> { + pre_emit!(PathExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -2018,7 +2125,7 @@ impl Translator<'_> { path, }); self.emit_location(label, node); - emit_detached!(PathExpr, self, node, label); + post_emit!(PathExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2026,13 +2133,14 @@ impl Translator<'_> { &mut self, node: &ast::PathPat, ) -> Option> { + pre_emit!(PathPat, self, node); let path = node.path().and_then(|x| self.emit_path(&x)); let label = self.trap.emit(generated::PathPat { id: TrapId::Star, path, }); self.emit_location(label, node); - emit_detached!(PathPat, self, node, label); + post_emit!(PathPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2040,6 +2148,7 @@ impl Translator<'_> { &mut self, node: &ast::PathSegment, ) -> Option> { + pre_emit!(PathSegment, self, node); let generic_arg_list = node .generic_arg_list() .and_then(|x| self.emit_generic_arg_list(&x)); @@ -2060,7 +2169,7 @@ impl Translator<'_> { return_type_syntax, }); self.emit_location(label, node); - emit_detached!(PathSegment, self, node, label); + post_emit!(PathSegment, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2068,13 +2177,14 @@ impl Translator<'_> { &mut self, node: &ast::PathType, ) -> Option> { + pre_emit!(PathTypeRepr, self, node); let path = node.path().and_then(|x| self.emit_path(&x)); let label = self.trap.emit(generated::PathTypeRepr { id: TrapId::Star, path, }); self.emit_location(label, node); - emit_detached!(PathTypeRepr, self, node, label); + post_emit!(PathTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2082,6 +2192,7 @@ impl Translator<'_> { &mut self, node: &ast::PrefixExpr, ) -> Option> { + pre_emit!(PrefixExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -2095,7 +2206,7 @@ impl Translator<'_> { operator_name, }); self.emit_location(label, node); - emit_detached!(PrefixExpr, self, node, label); + post_emit!(PrefixExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2103,6 +2214,7 @@ impl Translator<'_> { &mut self, node: &ast::PtrType, ) -> Option> { + pre_emit!(PtrTypeRepr, self, node); let is_const = node.const_token().is_some(); let is_mut = node.mut_token().is_some(); let type_repr = node.ty().and_then(|x| self.emit_type(&x)); @@ -2113,7 +2225,7 @@ impl Translator<'_> { type_repr, }); self.emit_location(label, node); - emit_detached!(PtrTypeRepr, self, node, label); + post_emit!(PtrTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2121,6 +2233,7 @@ impl Translator<'_> { &mut self, node: &ast::RangeExpr, ) -> Option> { + pre_emit!(RangeExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -2136,7 +2249,7 @@ impl Translator<'_> { start, }); self.emit_location(label, node); - emit_detached!(RangeExpr, self, node, label); + post_emit!(RangeExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2144,6 +2257,7 @@ impl Translator<'_> { &mut self, node: &ast::RangePat, ) -> Option> { + pre_emit!(RangePat, self, node); let end = node.end().and_then(|x| self.emit_pat(&x)); let operator_name = node.try_get_text(); let start = node.start().and_then(|x| self.emit_pat(&x)); @@ -2154,7 +2268,7 @@ impl Translator<'_> { start, }); self.emit_location(label, node); - emit_detached!(RangePat, self, node, label); + post_emit!(RangePat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2162,6 +2276,7 @@ impl Translator<'_> { &mut self, node: &ast::RecordExpr, ) -> Option> { + pre_emit!(StructExpr, self, node); let path = node.path().and_then(|x| self.emit_path(&x)); let struct_expr_field_list = node .record_expr_field_list() @@ -2172,7 +2287,7 @@ impl Translator<'_> { struct_expr_field_list, }); self.emit_location(label, node); - emit_detached!(StructExpr, self, node, label); + post_emit!(StructExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2180,6 +2295,7 @@ impl Translator<'_> { &mut self, node: &ast::RecordExprField, ) -> Option> { + pre_emit!(StructExprField, self, node); if self.should_be_excluded(node) { return None; } @@ -2193,7 +2309,7 @@ impl Translator<'_> { identifier, }); self.emit_location(label, node); - emit_detached!(StructExprField, self, node, label); + post_emit!(StructExprField, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2201,6 +2317,7 @@ impl Translator<'_> { &mut self, node: &ast::RecordExprFieldList, ) -> Option> { + pre_emit!(StructExprFieldList, self, node); if self.should_be_excluded(node) { return None; } @@ -2217,7 +2334,7 @@ impl Translator<'_> { spread, }); self.emit_location(label, node); - emit_detached!(StructExprFieldList, self, node, label); + post_emit!(StructExprFieldList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2225,6 +2342,7 @@ impl Translator<'_> { &mut self, node: &ast::RecordField, ) -> Option> { + pre_emit!(StructField, self, node); if self.should_be_excluded(node) { return None; } @@ -2244,7 +2362,7 @@ impl Translator<'_> { visibility, }); self.emit_location(label, node); - emit_detached!(StructField, self, node, label); + post_emit!(StructField, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2252,6 +2370,7 @@ impl Translator<'_> { &mut self, node: &ast::RecordFieldList, ) -> Option> { + pre_emit!(StructFieldList, self, node); let fields = node .fields() .filter_map(|x| self.emit_record_field(&x)) @@ -2261,7 +2380,7 @@ impl Translator<'_> { fields, }); self.emit_location(label, node); - emit_detached!(StructFieldList, self, node, label); + post_emit!(StructFieldList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2269,6 +2388,7 @@ impl Translator<'_> { &mut self, node: &ast::RecordPat, ) -> Option> { + pre_emit!(StructPat, self, node); let path = node.path().and_then(|x| self.emit_path(&x)); let struct_pat_field_list = node .record_pat_field_list() @@ -2279,7 +2399,7 @@ impl Translator<'_> { struct_pat_field_list, }); self.emit_location(label, node); - emit_detached!(StructPat, self, node, label); + post_emit!(StructPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2287,6 +2407,7 @@ impl Translator<'_> { &mut self, node: &ast::RecordPatField, ) -> Option> { + pre_emit!(StructPatField, self, node); if self.should_be_excluded(node) { return None; } @@ -2300,7 +2421,7 @@ impl Translator<'_> { pat, }); self.emit_location(label, node); - emit_detached!(StructPatField, self, node, label); + post_emit!(StructPatField, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2308,6 +2429,7 @@ impl Translator<'_> { &mut self, node: &ast::RecordPatFieldList, ) -> Option> { + pre_emit!(StructPatFieldList, self, node); let fields = node .fields() .filter_map(|x| self.emit_record_pat_field(&x)) @@ -2319,7 +2441,7 @@ impl Translator<'_> { rest_pat, }); self.emit_location(label, node); - emit_detached!(StructPatFieldList, self, node, label); + post_emit!(StructPatFieldList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2327,6 +2449,7 @@ impl Translator<'_> { &mut self, node: &ast::RefExpr, ) -> Option> { + pre_emit!(RefExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -2344,11 +2467,12 @@ impl Translator<'_> { is_raw, }); self.emit_location(label, node); - emit_detached!(RefExpr, self, node, label); + post_emit!(RefExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_ref_pat(&mut self, node: &ast::RefPat) -> Option> { + pre_emit!(RefPat, self, node); let is_mut = node.mut_token().is_some(); let pat = node.pat().and_then(|x| self.emit_pat(&x)); let label = self.trap.emit(generated::RefPat { @@ -2357,7 +2481,7 @@ impl Translator<'_> { pat, }); self.emit_location(label, node); - emit_detached!(RefPat, self, node, label); + post_emit!(RefPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2365,6 +2489,7 @@ impl Translator<'_> { &mut self, node: &ast::RefType, ) -> Option> { + pre_emit!(RefTypeRepr, self, node); let is_mut = node.mut_token().is_some(); let lifetime = node.lifetime().and_then(|x| self.emit_lifetime(&x)); let type_repr = node.ty().and_then(|x| self.emit_type(&x)); @@ -2375,18 +2500,19 @@ impl Translator<'_> { type_repr, }); self.emit_location(label, node); - emit_detached!(RefTypeRepr, self, node, label); + post_emit!(RefTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_rename(&mut self, node: &ast::Rename) -> Option> { + pre_emit!(Rename, self, node); let name = node.name().and_then(|x| self.emit_name(&x)); let label = self.trap.emit(generated::Rename { id: TrapId::Star, name, }); self.emit_location(label, node); - emit_detached!(Rename, self, node, label); + post_emit!(Rename, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2394,6 +2520,7 @@ impl Translator<'_> { &mut self, node: &ast::RestPat, ) -> Option> { + pre_emit!(RestPat, self, node); if self.should_be_excluded(node) { return None; } @@ -2403,7 +2530,7 @@ impl Translator<'_> { attrs, }); self.emit_location(label, node); - emit_detached!(RestPat, self, node, label); + post_emit!(RestPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2411,13 +2538,14 @@ impl Translator<'_> { &mut self, node: &ast::RetType, ) -> Option> { + pre_emit!(RetTypeRepr, self, node); let type_repr = node.ty().and_then(|x| self.emit_type(&x)); let label = self.trap.emit(generated::RetTypeRepr { id: TrapId::Star, type_repr, }); self.emit_location(label, node); - emit_detached!(RetTypeRepr, self, node, label); + post_emit!(RetTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2425,6 +2553,7 @@ impl Translator<'_> { &mut self, node: &ast::ReturnExpr, ) -> Option> { + pre_emit!(ReturnExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -2436,7 +2565,7 @@ impl Translator<'_> { expr, }); self.emit_location(label, node); - emit_detached!(ReturnExpr, self, node, label); + post_emit!(ReturnExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2444,11 +2573,12 @@ impl Translator<'_> { &mut self, node: &ast::ReturnTypeSyntax, ) -> Option> { + pre_emit!(ReturnTypeSyntax, self, node); let label = self .trap .emit(generated::ReturnTypeSyntax { id: TrapId::Star }); self.emit_location(label, node); - emit_detached!(ReturnTypeSyntax, self, node, label); + post_emit!(ReturnTypeSyntax, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2456,6 +2586,7 @@ impl Translator<'_> { &mut self, node: &ast::SelfParam, ) -> Option> { + pre_emit!(SelfParam, self, node); if self.should_be_excluded(node) { return None; } @@ -2475,7 +2606,7 @@ impl Translator<'_> { type_repr, }); self.emit_location(label, node); - emit_detached!(SelfParam, self, node, label); + post_emit!(SelfParam, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2483,13 +2614,14 @@ impl Translator<'_> { &mut self, node: &ast::SlicePat, ) -> Option> { + pre_emit!(SlicePat, self, node); let pats = node.pats().filter_map(|x| self.emit_pat(&x)).collect(); let label = self.trap.emit(generated::SlicePat { id: TrapId::Star, pats, }); self.emit_location(label, node); - emit_detached!(SlicePat, self, node, label); + post_emit!(SlicePat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2497,13 +2629,14 @@ impl Translator<'_> { &mut self, node: &ast::SliceType, ) -> Option> { + pre_emit!(SliceTypeRepr, self, node); let type_repr = node.ty().and_then(|x| self.emit_type(&x)); let label = self.trap.emit(generated::SliceTypeRepr { id: TrapId::Star, type_repr, }); self.emit_location(label, node); - emit_detached!(SliceTypeRepr, self, node, label); + post_emit!(SliceTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2511,6 +2644,7 @@ impl Translator<'_> { &mut self, node: &ast::SourceFile, ) -> Option> { + pre_emit!(SourceFile, self, node); if self.should_be_excluded(node) { return None; } @@ -2522,11 +2656,12 @@ impl Translator<'_> { items, }); self.emit_location(label, node); - emit_detached!(SourceFile, self, node, label); + post_emit!(SourceFile, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_static(&mut self, node: &ast::Static) -> Option> { + pre_emit!(Static, self, node); if self.should_be_excluded(node) { return None; } @@ -2550,7 +2685,7 @@ impl Translator<'_> { visibility, }); self.emit_location(label, node); - emit_detached!(Static, self, node, label); + post_emit!(Static, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2558,6 +2693,7 @@ impl Translator<'_> { &mut self, node: &ast::StmtList, ) -> Option> { + pre_emit!(StmtList, self, node); if self.should_be_excluded(node) { return None; } @@ -2574,11 +2710,12 @@ impl Translator<'_> { tail_expr, }); self.emit_location(label, node); - emit_detached!(StmtList, self, node, label); + post_emit!(StmtList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_struct(&mut self, node: &ast::Struct) -> Option> { + pre_emit!(Struct, self, node); if self.should_be_excluded(node) { return None; } @@ -2600,7 +2737,7 @@ impl Translator<'_> { where_clause, }); self.emit_location(label, node); - emit_detached!(Struct, self, node, label); + post_emit!(Struct, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2608,13 +2745,15 @@ impl Translator<'_> { &mut self, node: &ast::TokenTree, ) -> Option> { + pre_emit!(TokenTree, self, node); let label = self.trap.emit(generated::TokenTree { id: TrapId::Star }); self.emit_location(label, node); - emit_detached!(TokenTree, self, node, label); + post_emit!(TokenTree, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_trait(&mut self, node: &ast::Trait) -> Option> { + pre_emit!(Trait, self, node); if self.should_be_excluded(node) { return None; } @@ -2646,7 +2785,7 @@ impl Translator<'_> { where_clause, }); self.emit_location(label, node); - emit_detached!(Trait, self, node, label); + post_emit!(Trait, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2654,6 +2793,7 @@ impl Translator<'_> { &mut self, node: &ast::TraitAlias, ) -> Option> { + pre_emit!(TraitAlias, self, node); if self.should_be_excluded(node) { return None; } @@ -2677,7 +2817,7 @@ impl Translator<'_> { where_clause, }); self.emit_location(label, node); - emit_detached!(TraitAlias, self, node, label); + post_emit!(TraitAlias, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2685,6 +2825,7 @@ impl Translator<'_> { &mut self, node: &ast::TryExpr, ) -> Option> { + pre_emit!(TryExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -2696,7 +2837,7 @@ impl Translator<'_> { expr, }); self.emit_location(label, node); - emit_detached!(TryExpr, self, node, label); + post_emit!(TryExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2704,6 +2845,7 @@ impl Translator<'_> { &mut self, node: &ast::TupleExpr, ) -> Option> { + pre_emit!(TupleExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -2715,7 +2857,7 @@ impl Translator<'_> { fields, }); self.emit_location(label, node); - emit_detached!(TupleExpr, self, node, label); + post_emit!(TupleExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2723,6 +2865,7 @@ impl Translator<'_> { &mut self, node: &ast::TupleField, ) -> Option> { + pre_emit!(TupleField, self, node); if self.should_be_excluded(node) { return None; } @@ -2736,7 +2879,7 @@ impl Translator<'_> { visibility, }); self.emit_location(label, node); - emit_detached!(TupleField, self, node, label); + post_emit!(TupleField, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2744,6 +2887,7 @@ impl Translator<'_> { &mut self, node: &ast::TupleFieldList, ) -> Option> { + pre_emit!(TupleFieldList, self, node); let fields = node .fields() .filter_map(|x| self.emit_tuple_field(&x)) @@ -2753,7 +2897,7 @@ impl Translator<'_> { fields, }); self.emit_location(label, node); - emit_detached!(TupleFieldList, self, node, label); + post_emit!(TupleFieldList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2761,13 +2905,14 @@ impl Translator<'_> { &mut self, node: &ast::TuplePat, ) -> Option> { + pre_emit!(TuplePat, self, node); let fields = node.fields().filter_map(|x| self.emit_pat(&x)).collect(); let label = self.trap.emit(generated::TuplePat { id: TrapId::Star, fields, }); self.emit_location(label, node); - emit_detached!(TuplePat, self, node, label); + post_emit!(TuplePat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2775,6 +2920,7 @@ impl Translator<'_> { &mut self, node: &ast::TupleStructPat, ) -> Option> { + pre_emit!(TupleStructPat, self, node); let fields = node.fields().filter_map(|x| self.emit_pat(&x)).collect(); let path = node.path().and_then(|x| self.emit_path(&x)); let label = self.trap.emit(generated::TupleStructPat { @@ -2783,7 +2929,7 @@ impl Translator<'_> { path, }); self.emit_location(label, node); - emit_detached!(TupleStructPat, self, node, label); + post_emit!(TupleStructPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2791,13 +2937,14 @@ impl Translator<'_> { &mut self, node: &ast::TupleType, ) -> Option> { + pre_emit!(TupleTypeRepr, self, node); let fields = node.fields().filter_map(|x| self.emit_type(&x)).collect(); let label = self.trap.emit(generated::TupleTypeRepr { id: TrapId::Star, fields, }); self.emit_location(label, node); - emit_detached!(TupleTypeRepr, self, node, label); + post_emit!(TupleTypeRepr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2805,6 +2952,7 @@ impl Translator<'_> { &mut self, node: &ast::TypeAlias, ) -> Option> { + pre_emit!(TypeAlias, self, node); if self.should_be_excluded(node) { return None; } @@ -2832,7 +2980,7 @@ impl Translator<'_> { where_clause, }); self.emit_location(label, node); - emit_detached!(TypeAlias, self, node, label); + post_emit!(TypeAlias, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2840,13 +2988,14 @@ impl Translator<'_> { &mut self, node: &ast::TypeArg, ) -> Option> { + pre_emit!(TypeArg, self, node); let type_repr = node.ty().and_then(|x| self.emit_type(&x)); let label = self.trap.emit(generated::TypeArg { id: TrapId::Star, type_repr, }); self.emit_location(label, node); - emit_detached!(TypeArg, self, node, label); + post_emit!(TypeArg, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2854,6 +3003,7 @@ impl Translator<'_> { &mut self, node: &ast::TypeBound, ) -> Option> { + pre_emit!(TypeBound, self, node); let is_async = node.async_token().is_some(); let is_const = node.const_token().is_some(); let lifetime = node.lifetime().and_then(|x| self.emit_lifetime(&x)); @@ -2870,7 +3020,7 @@ impl Translator<'_> { use_bound_generic_args, }); self.emit_location(label, node); - emit_detached!(TypeBound, self, node, label); + post_emit!(TypeBound, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2878,6 +3028,7 @@ impl Translator<'_> { &mut self, node: &ast::TypeBoundList, ) -> Option> { + pre_emit!(TypeBoundList, self, node); let bounds = node .bounds() .filter_map(|x| self.emit_type_bound(&x)) @@ -2887,7 +3038,7 @@ impl Translator<'_> { bounds, }); self.emit_location(label, node); - emit_detached!(TypeBoundList, self, node, label); + post_emit!(TypeBoundList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2895,6 +3046,7 @@ impl Translator<'_> { &mut self, node: &ast::TypeParam, ) -> Option> { + pre_emit!(TypeParam, self, node); if self.should_be_excluded(node) { return None; } @@ -2912,7 +3064,7 @@ impl Translator<'_> { type_bound_list, }); self.emit_location(label, node); - emit_detached!(TypeParam, self, node, label); + post_emit!(TypeParam, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2920,6 +3072,7 @@ impl Translator<'_> { &mut self, node: &ast::UnderscoreExpr, ) -> Option> { + pre_emit!(UnderscoreExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -2929,11 +3082,12 @@ impl Translator<'_> { attrs, }); self.emit_location(label, node); - emit_detached!(UnderscoreExpr, self, node, label); + post_emit!(UnderscoreExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_union(&mut self, node: &ast::Union) -> Option> { + pre_emit!(Union, self, node); if self.should_be_excluded(node) { return None; } @@ -2957,11 +3111,12 @@ impl Translator<'_> { where_clause, }); self.emit_location(label, node); - emit_detached!(Union, self, node, label); + post_emit!(Union, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } pub(crate) fn emit_use(&mut self, node: &ast::Use) -> Option> { + pre_emit!(Use, self, node); if self.should_be_excluded(node) { return None; } @@ -2975,7 +3130,7 @@ impl Translator<'_> { visibility, }); self.emit_location(label, node); - emit_detached!(Use, self, node, label); + post_emit!(Use, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -2983,6 +3138,7 @@ impl Translator<'_> { &mut self, node: &ast::UseBoundGenericArgs, ) -> Option> { + pre_emit!(UseBoundGenericArgs, self, node); let use_bound_generic_args = node .use_bound_generic_args() .filter_map(|x| self.emit_use_bound_generic_arg(&x)) @@ -2992,7 +3148,7 @@ impl Translator<'_> { use_bound_generic_args, }); self.emit_location(label, node); - emit_detached!(UseBoundGenericArgs, self, node, label); + post_emit!(UseBoundGenericArgs, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3000,6 +3156,7 @@ impl Translator<'_> { &mut self, node: &ast::UseTree, ) -> Option> { + pre_emit!(UseTree, self, node); let is_glob = node.star_token().is_some(); let path = node.path().and_then(|x| self.emit_path(&x)); let rename = node.rename().and_then(|x| self.emit_rename(&x)); @@ -3014,7 +3171,7 @@ impl Translator<'_> { use_tree_list, }); self.emit_location(label, node); - emit_detached!(UseTree, self, node, label); + post_emit!(UseTree, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3022,6 +3179,7 @@ impl Translator<'_> { &mut self, node: &ast::UseTreeList, ) -> Option> { + pre_emit!(UseTreeList, self, node); let use_trees = node .use_trees() .filter_map(|x| self.emit_use_tree(&x)) @@ -3031,7 +3189,7 @@ impl Translator<'_> { use_trees, }); self.emit_location(label, node); - emit_detached!(UseTreeList, self, node, label); + post_emit!(UseTreeList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3039,6 +3197,7 @@ impl Translator<'_> { &mut self, node: &ast::Variant, ) -> Option> { + pre_emit!(Variant, self, node); if self.should_be_excluded(node) { return None; } @@ -3056,7 +3215,7 @@ impl Translator<'_> { visibility, }); self.emit_location(label, node); - emit_detached!(Variant, self, node, label); + post_emit!(Variant, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3064,6 +3223,7 @@ impl Translator<'_> { &mut self, node: &ast::VariantList, ) -> Option> { + pre_emit!(VariantList, self, node); let variants = node .variants() .filter_map(|x| self.emit_variant(&x)) @@ -3073,7 +3233,7 @@ impl Translator<'_> { variants, }); self.emit_location(label, node); - emit_detached!(VariantList, self, node, label); + post_emit!(VariantList, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3081,13 +3241,14 @@ impl Translator<'_> { &mut self, node: &ast::Visibility, ) -> Option> { + pre_emit!(Visibility, self, node); let path = node.path().and_then(|x| self.emit_path(&x)); let label = self.trap.emit(generated::Visibility { id: TrapId::Star, path, }); self.emit_location(label, node); - emit_detached!(Visibility, self, node, label); + post_emit!(Visibility, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3095,6 +3256,7 @@ impl Translator<'_> { &mut self, node: &ast::WhereClause, ) -> Option> { + pre_emit!(WhereClause, self, node); let predicates = node .predicates() .filter_map(|x| self.emit_where_pred(&x)) @@ -3104,7 +3266,7 @@ impl Translator<'_> { predicates, }); self.emit_location(label, node); - emit_detached!(WhereClause, self, node, label); + post_emit!(WhereClause, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3112,6 +3274,7 @@ impl Translator<'_> { &mut self, node: &ast::WherePred, ) -> Option> { + pre_emit!(WherePred, self, node); let generic_param_list = node .generic_param_list() .and_then(|x| self.emit_generic_param_list(&x)); @@ -3128,7 +3291,7 @@ impl Translator<'_> { type_bound_list, }); self.emit_location(label, node); - emit_detached!(WherePred, self, node, label); + post_emit!(WherePred, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3136,6 +3299,7 @@ impl Translator<'_> { &mut self, node: &ast::WhileExpr, ) -> Option> { + pre_emit!(WhileExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -3151,7 +3315,7 @@ impl Translator<'_> { loop_body, }); self.emit_location(label, node); - emit_detached!(WhileExpr, self, node, label); + post_emit!(WhileExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3159,9 +3323,10 @@ impl Translator<'_> { &mut self, node: &ast::WildcardPat, ) -> Option> { + pre_emit!(WildcardPat, self, node); let label = self.trap.emit(generated::WildcardPat { id: TrapId::Star }); self.emit_location(label, node); - emit_detached!(WildcardPat, self, node, label); + post_emit!(WildcardPat, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3169,6 +3334,7 @@ impl Translator<'_> { &mut self, node: &ast::YeetExpr, ) -> Option> { + pre_emit!(YeetExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -3180,7 +3346,7 @@ impl Translator<'_> { expr, }); self.emit_location(label, node); - emit_detached!(YeetExpr, self, node, label); + post_emit!(YeetExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } @@ -3188,6 +3354,7 @@ impl Translator<'_> { &mut self, node: &ast::YieldExpr, ) -> Option> { + pre_emit!(YieldExpr, self, node); if self.should_be_excluded(node) { return None; } @@ -3199,7 +3366,7 @@ impl Translator<'_> { expr, }); self.emit_location(label, node); - emit_detached!(YieldExpr, self, node, label); + post_emit!(YieldExpr, self, node, label); self.emit_tokens(node, label.into(), node.syntax().children_with_tokens()); Some(label) } From 31b48e18e62a365a1af5339a7b7d4e80629d611e Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 19 May 2025 11:30:28 +0200 Subject: [PATCH 41/86] Rust: fix `BadCtorInitialization` test --- .../security/CWE-696/BadCtorInitialization.ql | 3 +- .../CWE-696/BadCTorInitialization.expected | 108 +++++++++++------- .../test/query-tests/security/CWE-696/test.rs | 12 +- 3 files changed, 73 insertions(+), 50 deletions(-) diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql index 75946d89e11..cff84ed51d7 100644 --- a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql @@ -82,4 +82,5 @@ query predicate edges(PathElement pred, PathElement succ) { from CtorAttr source, StdCall sink where edges+(source, sink) select sink, source, sink, - "Call to " + sink.toString() + " in a function with the " + source.getWhichAttr() + " attribute." + "Call to " + sink.toString() + " from the standard library in a function with the " + + source.getWhichAttr() + " attribute." diff --git a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected index 9d8fc252471..3ac74a3cb13 100644 --- a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected +++ b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected @@ -1,49 +1,71 @@ #select -| test.rs:30:9:30:25 | ...::stdout(...) | test.rs:28:1:28:13 | Attr | test.rs:30:9:30:25 | ...::stdout(...) | Call to ...::stdout(...) in a function with the ctor attribute. | -| test.rs:35:9:35:25 | ...::stdout(...) | test.rs:33:1:33:13 | Attr | test.rs:35:9:35:25 | ...::stdout(...) | Call to ...::stdout(...) in a function with the dtor attribute. | -| test.rs:42:9:42:25 | ...::stdout(...) | test.rs:39:1:39:13 | Attr | test.rs:42:9:42:25 | ...::stdout(...) | Call to ...::stdout(...) in a function with the dtor attribute. | -| test.rs:52:9:52:16 | stdout(...) | test.rs:50:1:50:7 | Attr | test.rs:52:9:52:16 | stdout(...) | Call to stdout(...) in a function with the ctor attribute. | -| test.rs:57:9:57:16 | stderr(...) | test.rs:55:1:55:7 | Attr | test.rs:57:9:57:16 | stderr(...) | Call to stderr(...) in a function with the ctor attribute. | -| test.rs:62:14:62:28 | ...::_print(...) | test.rs:60:1:60:7 | Attr | test.rs:62:14:62:28 | ...::_print(...) | Call to ...::_print(...) in a function with the ctor attribute. | -| test.rs:68:9:68:24 | ...::stdin(...) | test.rs:65:1:65:7 | Attr | test.rs:68:9:68:24 | ...::stdin(...) | Call to ...::stdin(...) in a function with the ctor attribute. | -| test.rs:89:5:89:35 | ...::sleep(...) | test.rs:87:1:87:7 | Attr | test.rs:89:5:89:35 | ...::sleep(...) | Call to ...::sleep(...) in a function with the ctor attribute. | -| test.rs:96:5:96:23 | ...::exit(...) | test.rs:94:1:94:7 | Attr | test.rs:96:5:96:23 | ...::exit(...) | Call to ...::exit(...) in a function with the ctor attribute. | -| test.rs:125:9:125:16 | stderr(...) | test.rs:128:1:128:7 | Attr | test.rs:125:9:125:16 | stderr(...) | Call to stderr(...) in a function with the ctor attribute. | -| test.rs:125:9:125:16 | stderr(...) | test.rs:144:1:144:7 | Attr | test.rs:125:9:125:16 | stderr(...) | Call to stderr(...) in a function with the ctor attribute. | -| test.rs:125:9:125:16 | stderr(...) | test.rs:150:1:150:7 | Attr | test.rs:125:9:125:16 | stderr(...) | Call to stderr(...) in a function with the ctor attribute. | -| test.rs:125:9:125:44 | ... .write_all(...) | test.rs:128:1:128:7 | Attr | test.rs:125:9:125:44 | ... .write_all(...) | Call to ... .write_all(...) in a function with the ctor attribute. | -| test.rs:125:9:125:44 | ... .write_all(...) | test.rs:144:1:144:7 | Attr | test.rs:125:9:125:44 | ... .write_all(...) | Call to ... .write_all(...) in a function with the ctor attribute. | -| test.rs:125:9:125:44 | ... .write_all(...) | test.rs:150:1:150:7 | Attr | test.rs:125:9:125:44 | ... .write_all(...) | Call to ... .write_all(...) in a function with the ctor attribute. | -| test.rs:170:5:170:15 | ...::stdout(...) | test.rs:168:1:168:7 | Attr | test.rs:170:5:170:15 | ...::stdout(...) | Call to ...::stdout(...) in a function with the ctor attribute. | +| test.rs:30:9:30:24 | ...::stdout(...) | test.rs:28:1:28:13 | Attr | test.rs:30:9:30:24 | ...::stdout(...) | Call to ...::stdout(...) from the standard library in a function with the ctor attribute. | +| test.rs:30:9:30:48 | ... .write(...) | test.rs:28:1:28:13 | Attr | test.rs:30:9:30:48 | ... .write(...) | Call to ... .write(...) from the standard library in a function with the ctor attribute. | +| test.rs:35:9:35:24 | ...::stdout(...) | test.rs:33:1:33:13 | Attr | test.rs:35:9:35:24 | ...::stdout(...) | Call to ...::stdout(...) from the standard library in a function with the dtor attribute. | +| test.rs:35:9:35:48 | ... .write(...) | test.rs:33:1:33:13 | Attr | test.rs:35:9:35:48 | ... .write(...) | Call to ... .write(...) from the standard library in a function with the dtor attribute. | +| test.rs:42:9:42:24 | ...::stdout(...) | test.rs:39:1:39:13 | Attr | test.rs:42:9:42:24 | ...::stdout(...) | Call to ...::stdout(...) from the standard library in a function with the dtor attribute. | +| test.rs:42:9:42:48 | ... .write(...) | test.rs:39:1:39:13 | Attr | test.rs:42:9:42:48 | ... .write(...) | Call to ... .write(...) from the standard library in a function with the dtor attribute. | +| test.rs:52:9:52:15 | stdout(...) | test.rs:50:1:50:7 | Attr | test.rs:52:9:52:15 | stdout(...) | Call to stdout(...) from the standard library in a function with the ctor attribute. | +| test.rs:52:9:52:39 | ... .write(...) | test.rs:50:1:50:7 | Attr | test.rs:52:9:52:39 | ... .write(...) | Call to ... .write(...) from the standard library in a function with the ctor attribute. | +| test.rs:57:9:57:15 | stderr(...) | test.rs:55:1:55:7 | Attr | test.rs:57:9:57:15 | stderr(...) | Call to stderr(...) from the standard library in a function with the ctor attribute. | +| test.rs:57:9:57:43 | ... .write_all(...) | test.rs:55:1:55:7 | Attr | test.rs:57:9:57:43 | ... .write_all(...) | Call to ... .write_all(...) from the standard library in a function with the ctor attribute. | +| test.rs:62:14:62:28 | ...::_print(...) | test.rs:60:1:60:7 | Attr | test.rs:62:14:62:28 | ...::_print(...) | Call to ...::_print(...) from the standard library in a function with the ctor attribute. | +| test.rs:68:9:68:23 | ...::stdin(...) | test.rs:65:1:65:7 | Attr | test.rs:68:9:68:23 | ...::stdin(...) | Call to ...::stdin(...) from the standard library in a function with the ctor attribute. | +| test.rs:68:9:68:44 | ... .read_line(...) | test.rs:65:1:65:7 | Attr | test.rs:68:9:68:44 | ... .read_line(...) | Call to ... .read_line(...) from the standard library in a function with the ctor attribute. | +| test.rs:75:17:75:44 | ...::create(...) | test.rs:73:1:73:7 | Attr | test.rs:75:17:75:44 | ...::create(...) | Call to ...::create(...) from the standard library in a function with the ctor attribute. | +| test.rs:80:14:80:37 | ...::now(...) | test.rs:78:1:78:7 | Attr | test.rs:80:14:80:37 | ...::now(...) | Call to ...::now(...) from the standard library in a function with the ctor attribute. | +| test.rs:89:5:89:34 | ...::sleep(...) | test.rs:87:1:87:7 | Attr | test.rs:89:5:89:34 | ...::sleep(...) | Call to ...::sleep(...) from the standard library in a function with the ctor attribute. | +| test.rs:96:5:96:22 | ...::exit(...) | test.rs:94:1:94:7 | Attr | test.rs:96:5:96:22 | ...::exit(...) | Call to ...::exit(...) from the standard library in a function with the ctor attribute. | +| test.rs:125:9:125:16 | stderr(...) | test.rs:128:1:128:7 | Attr | test.rs:125:9:125:16 | stderr(...) | Call to stderr(...) from the standard library in a function with the ctor attribute. | +| test.rs:125:9:125:16 | stderr(...) | test.rs:144:1:144:7 | Attr | test.rs:125:9:125:16 | stderr(...) | Call to stderr(...) from the standard library in a function with the ctor attribute. | +| test.rs:125:9:125:16 | stderr(...) | test.rs:150:1:150:7 | Attr | test.rs:125:9:125:16 | stderr(...) | Call to stderr(...) from the standard library in a function with the ctor attribute. | +| test.rs:125:9:125:44 | ... .write_all(...) | test.rs:128:1:128:7 | Attr | test.rs:125:9:125:44 | ... .write_all(...) | Call to ... .write_all(...) from the standard library in a function with the ctor attribute. | +| test.rs:125:9:125:44 | ... .write_all(...) | test.rs:144:1:144:7 | Attr | test.rs:125:9:125:44 | ... .write_all(...) | Call to ... .write_all(...) from the standard library in a function with the ctor attribute. | +| test.rs:125:9:125:44 | ... .write_all(...) | test.rs:150:1:150:7 | Attr | test.rs:125:9:125:44 | ... .write_all(...) | Call to ... .write_all(...) from the standard library in a function with the ctor attribute. | +| test.rs:168:1:168:7 | ... .write(...) | test.rs:168:1:168:7 | Attr | test.rs:168:1:168:7 | ... .write(...) | Call to ... .write(...) from the standard library in a function with the ctor attribute. | +| test.rs:168:1:168:7 | ...::stdout(...) | test.rs:168:1:168:7 | Attr | test.rs:168:1:168:7 | ...::stdout(...) | Call to ...::stdout(...) from the standard library in a function with the ctor attribute. | edges -| test.rs:28:1:28:13 | Attr | test.rs:28:1:31:1 | fn bad1_1 | -| test.rs:28:1:31:1 | fn bad1_1 | test.rs:30:9:30:25 | ...::stdout(...) | -| test.rs:33:1:33:13 | Attr | test.rs:33:1:36:1 | fn bad1_2 | -| test.rs:33:1:36:1 | fn bad1_2 | test.rs:35:9:35:25 | ...::stdout(...) | -| test.rs:38:1:43:1 | fn bad1_3 | test.rs:42:9:42:25 | ...::stdout(...) | -| test.rs:39:1:39:13 | Attr | test.rs:38:1:43:1 | fn bad1_3 | -| test.rs:50:1:50:7 | Attr | test.rs:50:1:53:1 | fn bad2_1 | -| test.rs:50:1:53:1 | fn bad2_1 | test.rs:52:9:52:16 | stdout(...) | -| test.rs:55:1:55:7 | Attr | test.rs:55:1:58:1 | fn bad2_2 | -| test.rs:55:1:58:1 | fn bad2_2 | test.rs:57:9:57:16 | stderr(...) | -| test.rs:60:1:60:7 | Attr | test.rs:60:1:63:1 | fn bad2_3 | -| test.rs:60:1:63:1 | fn bad2_3 | test.rs:62:14:62:28 | ...::_print(...) | -| test.rs:65:1:65:7 | Attr | test.rs:65:1:69:1 | fn bad2_4 | -| test.rs:65:1:69:1 | fn bad2_4 | test.rs:68:9:68:24 | ...::stdin(...) | -| test.rs:87:1:87:7 | Attr | test.rs:87:1:90:1 | fn bad2_7 | -| test.rs:87:1:90:1 | fn bad2_7 | test.rs:89:5:89:35 | ...::sleep(...) | -| test.rs:94:1:94:7 | Attr | test.rs:94:1:97:1 | fn bad2_8 | -| test.rs:94:1:97:1 | fn bad2_8 | test.rs:96:5:96:23 | ...::exit(...) | +| test.rs:28:1:28:13 | Attr | test.rs:29:4:30:50 | fn bad1_1 | +| test.rs:29:4:30:50 | fn bad1_1 | test.rs:30:9:30:24 | ...::stdout(...) | +| test.rs:29:4:30:50 | fn bad1_1 | test.rs:30:9:30:48 | ... .write(...) | +| test.rs:33:1:33:13 | Attr | test.rs:34:4:35:50 | fn bad1_2 | +| test.rs:34:4:35:50 | fn bad1_2 | test.rs:35:9:35:24 | ...::stdout(...) | +| test.rs:34:4:35:50 | fn bad1_2 | test.rs:35:9:35:48 | ... .write(...) | +| test.rs:38:1:42:50 | fn bad1_3 | test.rs:42:9:42:24 | ...::stdout(...) | +| test.rs:38:1:42:50 | fn bad1_3 | test.rs:42:9:42:48 | ... .write(...) | +| test.rs:39:1:39:13 | Attr | test.rs:38:1:42:50 | fn bad1_3 | +| test.rs:50:1:50:7 | Attr | test.rs:51:4:52:41 | fn bad2_1 | +| test.rs:51:4:52:41 | fn bad2_1 | test.rs:52:9:52:15 | stdout(...) | +| test.rs:51:4:52:41 | fn bad2_1 | test.rs:52:9:52:39 | ... .write(...) | +| test.rs:55:1:55:7 | Attr | test.rs:56:4:57:45 | fn bad2_2 | +| test.rs:56:4:57:45 | fn bad2_2 | test.rs:57:9:57:15 | stderr(...) | +| test.rs:56:4:57:45 | fn bad2_2 | test.rs:57:9:57:43 | ... .write_all(...) | +| test.rs:60:1:60:7 | Attr | test.rs:61:4:62:30 | fn bad2_3 | +| test.rs:61:4:62:30 | fn bad2_3 | test.rs:62:14:62:28 | ...::_print(...) | +| test.rs:65:1:65:7 | Attr | test.rs:66:4:68:46 | fn bad2_4 | +| test.rs:66:4:68:46 | fn bad2_4 | test.rs:68:9:68:23 | ...::stdin(...) | +| test.rs:66:4:68:46 | fn bad2_4 | test.rs:68:9:68:44 | ... .read_line(...) | +| test.rs:73:1:73:7 | Attr | test.rs:74:4:75:55 | fn bad2_5 | +| test.rs:74:4:75:55 | fn bad2_5 | test.rs:75:17:75:44 | ...::create(...) | +| test.rs:78:1:78:7 | Attr | test.rs:79:4:80:39 | fn bad2_6 | +| test.rs:79:4:80:39 | fn bad2_6 | test.rs:80:14:80:37 | ...::now(...) | +| test.rs:87:1:87:7 | Attr | test.rs:88:4:89:36 | fn bad2_7 | +| test.rs:88:4:89:36 | fn bad2_7 | test.rs:89:5:89:34 | ...::sleep(...) | +| test.rs:94:1:94:7 | Attr | test.rs:95:4:96:24 | fn bad2_8 | +| test.rs:95:4:96:24 | fn bad2_8 | test.rs:96:5:96:22 | ...::exit(...) | | test.rs:124:1:126:1 | fn call_target3_1 | test.rs:125:9:125:16 | stderr(...) | | test.rs:124:1:126:1 | fn call_target3_1 | test.rs:125:9:125:44 | ... .write_all(...) | -| test.rs:128:1:128:7 | Attr | test.rs:128:1:131:1 | fn bad3_1 | -| test.rs:128:1:131:1 | fn bad3_1 | test.rs:130:5:130:20 | call_target3_1(...) | -| test.rs:130:5:130:20 | call_target3_1(...) | test.rs:124:1:126:1 | fn call_target3_1 | -| test.rs:144:1:144:7 | Attr | test.rs:144:1:148:1 | fn bad3_3 | +| test.rs:128:1:128:7 | Attr | test.rs:129:4:130:21 | fn bad3_1 | +| test.rs:129:4:130:21 | fn bad3_1 | test.rs:130:5:130:19 | call_target3_1(...) | +| test.rs:130:5:130:19 | call_target3_1(...) | test.rs:124:1:126:1 | fn call_target3_1 | +| test.rs:144:1:144:7 | Attr | test.rs:145:4:147:21 | fn bad3_3 | | test.rs:144:1:148:1 | fn bad3_3 | test.rs:146:5:146:20 | call_target3_1(...) | +| test.rs:145:4:147:21 | fn bad3_3 | test.rs:146:5:146:19 | call_target3_1(...) | +| test.rs:146:5:146:19 | call_target3_1(...) | test.rs:124:1:126:1 | fn call_target3_1 | | test.rs:146:5:146:20 | call_target3_1(...) | test.rs:124:1:126:1 | fn call_target3_1 | -| test.rs:150:1:150:7 | Attr | test.rs:150:1:153:1 | fn bad3_4 | -| test.rs:150:1:153:1 | fn bad3_4 | test.rs:152:5:152:12 | bad3_3(...) | -| test.rs:152:5:152:12 | bad3_3(...) | test.rs:144:1:148:1 | fn bad3_3 | -| test.rs:168:1:168:7 | Attr | test.rs:168:1:171:1 | fn bad4_1 | -| test.rs:168:1:171:1 | fn bad4_1 | test.rs:170:5:170:15 | ...::stdout(...) | +| test.rs:150:1:150:7 | Attr | test.rs:151:4:152:13 | fn bad3_4 | +| test.rs:151:4:152:13 | fn bad3_4 | test.rs:152:5:152:11 | bad3_3(...) | +| test.rs:152:5:152:11 | bad3_3(...) | test.rs:144:1:148:1 | fn bad3_3 | +| test.rs:168:1:168:7 | Attr | test.rs:169:4:170:16 | fn bad4_1 | +| test.rs:169:4:170:16 | fn bad4_1 | test.rs:168:1:168:7 | ... .write(...) | +| test.rs:169:4:170:16 | fn bad4_1 | test.rs:168:1:168:7 | ...::stdout(...) | diff --git a/rust/ql/test/query-tests/security/CWE-696/test.rs b/rust/ql/test/query-tests/security/CWE-696/test.rs index b23c06aa6a6..f589994d5d1 100644 --- a/rust/ql/test/query-tests/security/CWE-696/test.rs +++ b/rust/ql/test/query-tests/security/CWE-696/test.rs @@ -70,14 +70,14 @@ fn bad2_4() { use std::fs; -#[ctor] // $ MISSING: Source=source2_5 +#[ctor] // $ Source=source2_5 fn bad2_5() { - let _buff = fs::File::create("hello.txt").unwrap(); // $ MISSING: Alert[rust/ctor-initialization]=source2_5 + let _buff = fs::File::create("hello.txt").unwrap(); // $ Alert[rust/ctor-initialization]=source2_5 } -#[ctor] // $ MISSING: Source=source2_6 +#[ctor] // $ Source=source2_6 fn bad2_6() { - let _t = std::time::Instant::now(); // $ MISSING: Alert[rust/ctor-initialization]=source2_6 + let _t = std::time::Instant::now(); // $ Alert[rust/ctor-initialization]=source2_6 } use std::time::Duration; @@ -165,7 +165,7 @@ macro_rules! macro4_1 { }; } -#[ctor] // $ Source=source4_1 +#[ctor] // $ Alert[rust/ctor-initialization] fn bad4_1() { - macro4_1!(); // $ Alert[rust/ctor-initialization]=source4_1 + macro4_1!(); } From 5183d1610f81138638541bfff08afbeef6d87f23 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 19 May 2025 13:56:28 +0200 Subject: [PATCH 42/86] Rust: enhance macro expansion integration test --- .../macro-expansion/src/lib.rs | 7 ++++- .../macro-expansion/summary.expected | 16 +++++++++++ .../macro-expansion/summary.qlref | 1 + .../macro-expansion/test.expected | 28 +++++++++++-------- 4 files changed, 40 insertions(+), 12 deletions(-) create mode 100644 rust/ql/integration-tests/macro-expansion/summary.expected create mode 100644 rust/ql/integration-tests/macro-expansion/summary.qlref diff --git a/rust/ql/integration-tests/macro-expansion/src/lib.rs b/rust/ql/integration-tests/macro-expansion/src/lib.rs index 6d2d6037e5d..2007d3b111a 100644 --- a/rust/ql/integration-tests/macro-expansion/src/lib.rs +++ b/rust/ql/integration-tests/macro-expansion/src/lib.rs @@ -1,7 +1,12 @@ use macros::repeat; #[repeat(3)] -fn foo() {} +fn foo() { + println!("Hello, world!"); + + #[repeat(2)] + fn inner() {} +} #[repeat(2)] #[repeat(3)] diff --git a/rust/ql/integration-tests/macro-expansion/summary.expected b/rust/ql/integration-tests/macro-expansion/summary.expected new file mode 100644 index 00000000000..529d1736d02 --- /dev/null +++ b/rust/ql/integration-tests/macro-expansion/summary.expected @@ -0,0 +1,16 @@ +| Extraction errors | 0 | +| Extraction warnings | 0 | +| Files extracted - total | 2 | +| Files extracted - with errors | 0 | +| Files extracted - without errors | 2 | +| Files extracted - without errors % | 100 | +| Inconsistencies - AST | 0 | +| Inconsistencies - CFG | 0 | +| Inconsistencies - Path resolution | 0 | +| Inconsistencies - SSA | 0 | +| Inconsistencies - data flow | 0 | +| Lines of code extracted | 46 | +| Lines of user code extracted | 29 | +| Macro calls - resolved | 52 | +| Macro calls - total | 53 | +| Macro calls - unresolved | 1 | diff --git a/rust/ql/integration-tests/macro-expansion/summary.qlref b/rust/ql/integration-tests/macro-expansion/summary.qlref new file mode 100644 index 00000000000..926fc790391 --- /dev/null +++ b/rust/ql/integration-tests/macro-expansion/summary.qlref @@ -0,0 +1 @@ +queries/summary/SummaryStatsReduced.ql diff --git a/rust/ql/integration-tests/macro-expansion/test.expected b/rust/ql/integration-tests/macro-expansion/test.expected index 1247930bd22..83edecf5d5d 100644 --- a/rust/ql/integration-tests/macro-expansion/test.expected +++ b/rust/ql/integration-tests/macro-expansion/test.expected @@ -1,11 +1,17 @@ -| src/lib.rs:3:1:4:11 | fn foo | 0 | src/lib.rs:4:1:4:10 | fn foo_0 | -| src/lib.rs:3:1:4:11 | fn foo | 1 | src/lib.rs:4:1:4:10 | fn foo_1 | -| src/lib.rs:3:1:4:11 | fn foo | 2 | src/lib.rs:4:1:4:10 | fn foo_2 | -| src/lib.rs:6:1:8:11 | fn bar | 0 | src/lib.rs:7:1:8:10 | fn bar_0 | -| src/lib.rs:6:1:8:11 | fn bar | 1 | src/lib.rs:7:1:8:10 | fn bar_1 | -| src/lib.rs:7:1:8:10 | fn bar_0 | 0 | src/lib.rs:8:1:8:10 | fn bar_0_0 | -| src/lib.rs:7:1:8:10 | fn bar_0 | 1 | src/lib.rs:8:1:8:10 | fn bar_0_1 | -| src/lib.rs:7:1:8:10 | fn bar_0 | 2 | src/lib.rs:8:1:8:10 | fn bar_0_2 | -| src/lib.rs:7:1:8:10 | fn bar_1 | 0 | src/lib.rs:8:1:8:10 | fn bar_1_0 | -| src/lib.rs:7:1:8:10 | fn bar_1 | 1 | src/lib.rs:8:1:8:10 | fn bar_1_1 | -| src/lib.rs:7:1:8:10 | fn bar_1 | 2 | src/lib.rs:8:1:8:10 | fn bar_1_2 | +| src/lib.rs:3:1:9:1 | fn foo | 0 | src/lib.rs:4:1:8:16 | fn foo_0 | +| src/lib.rs:3:1:9:1 | fn foo | 1 | src/lib.rs:4:1:8:16 | fn foo_1 | +| src/lib.rs:3:1:9:1 | fn foo | 2 | src/lib.rs:4:1:8:16 | fn foo_2 | +| src/lib.rs:7:5:8:16 | fn inner | 0 | src/lib.rs:8:5:8:16 | fn inner_0 | +| src/lib.rs:7:5:8:16 | fn inner | 0 | src/lib.rs:8:5:8:16 | fn inner_0 | +| src/lib.rs:7:5:8:16 | fn inner | 0 | src/lib.rs:8:5:8:16 | fn inner_0 | +| src/lib.rs:7:5:8:16 | fn inner | 1 | src/lib.rs:8:5:8:16 | fn inner_1 | +| src/lib.rs:7:5:8:16 | fn inner | 1 | src/lib.rs:8:5:8:16 | fn inner_1 | +| src/lib.rs:7:5:8:16 | fn inner | 1 | src/lib.rs:8:5:8:16 | fn inner_1 | +| src/lib.rs:11:1:13:11 | fn bar | 0 | src/lib.rs:12:1:13:10 | fn bar_0 | +| src/lib.rs:11:1:13:11 | fn bar | 1 | src/lib.rs:12:1:13:10 | fn bar_1 | +| src/lib.rs:12:1:13:10 | fn bar_0 | 0 | src/lib.rs:13:1:13:10 | fn bar_0_0 | +| src/lib.rs:12:1:13:10 | fn bar_0 | 1 | src/lib.rs:13:1:13:10 | fn bar_0_1 | +| src/lib.rs:12:1:13:10 | fn bar_0 | 2 | src/lib.rs:13:1:13:10 | fn bar_0_2 | +| src/lib.rs:12:1:13:10 | fn bar_1 | 0 | src/lib.rs:13:1:13:10 | fn bar_1_0 | +| src/lib.rs:12:1:13:10 | fn bar_1 | 1 | src/lib.rs:13:1:13:10 | fn bar_1_1 | +| src/lib.rs:12:1:13:10 | fn bar_1 | 2 | src/lib.rs:13:1:13:10 | fn bar_1_2 | From 01e22b72668f17b2e4325481bf3cde0e77a16c3a Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 22 May 2025 11:47:33 +0200 Subject: [PATCH 43/86] Rust: remove wrong comment --- rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql | 1 - 1 file changed, 1 deletion(-) diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql index cff84ed51d7..80e1043a979 100644 --- a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql @@ -55,7 +55,6 @@ predicate edgesFwd(PathElement pred, PathElement succ) { ) ) or - // callable -> callable attribute macro expansion // [forwards reachable] callable -> enclosed call edgesFwd(_, pred) and pred = succ.(CallExprBase).getEnclosingCallable() From 5c294617c5096066c4ebc2bf575a5e61ea6f13f9 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 23 May 2025 14:43:18 +0200 Subject: [PATCH 44/86] Rust: update a comment --- rust/extractor/src/translate/base.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/extractor/src/translate/base.rs b/rust/extractor/src/translate/base.rs index d1cec34242c..a2f3101b75e 100644 --- a/rust/extractor/src/translate/base.rs +++ b/rust/extractor/src/translate/base.rs @@ -333,7 +333,7 @@ impl<'a> Translator<'a> { ) { if self.macro_context_depth > 0 { // we are in an attribute macro, don't emit anything: we would be failing to expand any - // way as rust-analyser now only expands in the context of an expansion + // way as from version 0.0.274 rust-analyser only expands in the context of an expansion return; } if let Some(expanded) = self From b800040c73550d188ef76c898575c7331889d99a Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Fri, 23 May 2025 15:49:12 +0200 Subject: [PATCH 45/86] C++: Add tests for various local Windows dataflow sources --- .../dataflow/dataflow-tests/TestBase.qll | 4 +++ .../dataflow/dataflow-tests/winmain.cpp | 9 ++++++ .../dataflow/external-models/windows.cpp | 31 +++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 cpp/ql/test/library-tests/dataflow/dataflow-tests/winmain.cpp create mode 100644 cpp/ql/test/library-tests/dataflow/external-models/windows.cpp diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/TestBase.qll b/cpp/ql/test/library-tests/dataflow/dataflow-tests/TestBase.qll index b9213a71549..e28d19133c7 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/TestBase.qll +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/TestBase.qll @@ -124,7 +124,11 @@ module IRTest { /** Common data flow configuration to be used by tests. */ module IRTestAllocationConfig implements DataFlow::ConfigSig { + private import semmle.code.cpp.security.FlowSources + predicate isSource(DataFlow::Node source) { + source instanceof FlowSource + or source.asExpr().(FunctionCall).getTarget().getName() = "source" or source.asIndirectExpr(1).(FunctionCall).getTarget().getName() = "indirect_source" diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/winmain.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/winmain.cpp new file mode 100644 index 00000000000..3db41088842 --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/winmain.cpp @@ -0,0 +1,9 @@ +void sink(char); +void sink(char*); + +int WinMain(void *hInstance, void *hPrevInstance, char *pCmdLine, int nCmdShow) { // $ ast-def=hInstance ast-def=hPrevInstance ast-def=pCmdLine ir-def=*hInstance ir-def=*hPrevInstance ir-def=*pCmdLine + sink(pCmdLine); + sink(*pCmdLine); // $ MISSING: ir + + return 0; +} diff --git a/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp b/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp new file mode 100644 index 00000000000..33f496be0f0 --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp @@ -0,0 +1,31 @@ +void sink(char); +void sink(char*); +void sink(char**); + +char* GetCommandLineA(); +char** CommandLineToArgvA(char*, int*); +char* GetEnvironmentStringsA(); +int GetEnvironmentVariableA(const char*, char*, int); + +void getCommandLine() { + char* cmd = GetCommandLineA(); + sink(cmd); + sink(*cmd); // $ MISSING: ir + + int argc; + char** argv = CommandLineToArgvA(cmd, &argc); + sink(argv); + sink(argv[1]); + sink(*argv[1]); // $ MISSING: ir +} + +void getEnvironment() { + char* env = GetEnvironmentStringsA(); + sink(env); + sink(*env); // $ MISSING: ir + + char buf[1024]; + GetEnvironmentVariableA("FOO", buf, sizeof(buf)); + sink(buf); + sink(*buf); // $ MISSING: ir +} From a77ddd7532e935720a9ccb9b38d30e7033b50d6a Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Thu, 22 May 2025 20:26:01 +0200 Subject: [PATCH 46/86] C++: Add Windows command line and environment models --- cpp/ql/lib/ext/Windows.model.yml | 20 +++++++++++++++++++ .../semmle/code/cpp/security/FlowSources.qll | 17 +++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 cpp/ql/lib/ext/Windows.model.yml diff --git a/cpp/ql/lib/ext/Windows.model.yml b/cpp/ql/lib/ext/Windows.model.yml new file mode 100644 index 00000000000..acac5f5fbf8 --- /dev/null +++ b/cpp/ql/lib/ext/Windows.model.yml @@ -0,0 +1,20 @@ + # partial model of windows system calls +extensions: + - addsTo: + pack: codeql/cpp-all + extensible: sourceModel + data: # namespace, type, subtypes, name, signature, ext, output, kind, provenance + # processenv.h + - ["", "", False, "GetCommandLineA", "", "", "ReturnValue[*]", "local", "manual"] + - ["", "", False, "GetCommandLineW", "", "", "ReturnValue[*]", "local", "manual"] + - ["", "", False, "GetEnvironmentStringsA", "", "", "ReturnValue[*]", "local", "manual"] + - ["", "", False, "GetEnvironmentStringsW", "", "", "ReturnValue[*]", "local", "manual"] + - ["", "", False, "GetEnvironmentVariableA", "", "", "Argument[*1]", "local", "manual"] + - ["", "", False, "GetEnvironmentVariableW", "", "", "Argument[*1]", "local", "manual"] + - addsTo: + pack: codeql/cpp-all + extensible: summaryModel + data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance + # shellapi.h + - ["", "", False, "CommandLineToArgvA", "", "", "Argument[*0]", "ReturnValue[**]", "taint", "manual"] + - ["", "", False, "CommandLineToArgvW", "", "", "Argument[*0]", "ReturnValue[**]", "taint", "manual"] diff --git a/cpp/ql/lib/semmle/code/cpp/security/FlowSources.qll b/cpp/ql/lib/semmle/code/cpp/security/FlowSources.qll index b5e94d4c046..eba6f9339ff 100644 --- a/cpp/ql/lib/semmle/code/cpp/security/FlowSources.qll +++ b/cpp/ql/lib/semmle/code/cpp/security/FlowSources.qll @@ -55,7 +55,7 @@ private class LocalModelSource extends LocalFlowSource { } /** - * A local data flow source that the `argv` parameter to `main` or `wmain`. + * A local data flow source that is the `argv` parameter to `main` or `wmain`. */ private class ArgvSource extends LocalFlowSource { ArgvSource() { @@ -69,6 +69,21 @@ private class ArgvSource extends LocalFlowSource { override string getSourceType() { result = "a command-line argument" } } +/** + * A local data flow source that is the `pCmdLine` parameter to `WinMain` or `wWinMain`. + */ +private class CmdLineSource extends LocalFlowSource { + CmdLineSource() { + exists(Function main, Parameter pCmdLine | + main.hasGlobalName(["WinMain", "wWinMain"]) and + main.getParameter(2) = pCmdLine and + this.asParameter(1) = pCmdLine + ) + } + + override string getSourceType() { result = "a command-line" } +} + /** * A remote data flow source that is defined through 'models as data'. */ From fbc96152872182eb3d9af74c5f8737c542fbe8b0 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Fri, 23 May 2025 16:03:47 +0200 Subject: [PATCH 47/86] C++: Update expected test results --- .../dataflow-tests/test-source-sink.expected | 1 + .../dataflow/dataflow-tests/winmain.cpp | 2 +- .../dataflow/external-models/flow.expected | 50 ++++++++++++++----- .../dataflow/external-models/sources.expected | 3 ++ .../dataflow/external-models/steps.expected | 1 + .../dataflow/external-models/windows.cpp | 8 +-- 6 files changed, 48 insertions(+), 17 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected index fa141b614ea..323ce2a4312 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected @@ -337,3 +337,4 @@ irFlow | true_upon_entry.cpp:70:11:70:16 | call to source | true_upon_entry.cpp:78:8:78:8 | x | | true_upon_entry.cpp:83:11:83:16 | call to source | true_upon_entry.cpp:86:8:86:8 | x | | true_upon_entry.cpp:98:11:98:16 | call to source | true_upon_entry.cpp:105:8:105:8 | x | +| winmain.cpp:4:57:4:64 | *pCmdLine | winmain.cpp:6:8:6:16 | * ... | diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/winmain.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/winmain.cpp index 3db41088842..3f267e1e81b 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/winmain.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/winmain.cpp @@ -3,7 +3,7 @@ void sink(char*); int WinMain(void *hInstance, void *hPrevInstance, char *pCmdLine, int nCmdShow) { // $ ast-def=hInstance ast-def=hPrevInstance ast-def=pCmdLine ir-def=*hInstance ir-def=*hPrevInstance ir-def=*pCmdLine sink(pCmdLine); - sink(*pCmdLine); // $ MISSING: ir + sink(*pCmdLine); // $ ir return 0; } diff --git a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected index 2eb0844862d..9992ca5a721 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected @@ -10,33 +10,44 @@ edges | asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:6 | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:10 | -| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:23489 | -| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:23490 | -| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:23491 | +| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:23497 | +| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:23498 | +| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:23499 | | test.cpp:7:47:7:52 | value2 | test.cpp:7:64:7:69 | value2 | provenance | | | test.cpp:7:64:7:69 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | provenance | | -| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:10:10:10:18 | call to ymlSource | provenance | Src:MaD:23487 | -| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:14:10:14:10 | x | provenance | Sink:MaD:23488 | +| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:10:10:10:18 | call to ymlSource | provenance | Src:MaD:23495 | +| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:14:10:14:10 | x | provenance | Sink:MaD:23496 | | test.cpp:10:10:10:18 | call to ymlSource | test.cpp:17:24:17:24 | x | provenance | | | test.cpp:10:10:10:18 | call to ymlSource | test.cpp:21:27:21:27 | x | provenance | | | test.cpp:10:10:10:18 | call to ymlSource | test.cpp:25:35:25:35 | x | provenance | | | test.cpp:10:10:10:18 | call to ymlSource | test.cpp:32:41:32:41 | x | provenance | | | test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | | -| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:18:10:18:10 | y | provenance | Sink:MaD:23488 | +| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:18:10:18:10 | y | provenance | Sink:MaD:23496 | | test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | provenance | | -| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:23489 | +| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:23497 | | test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | | -| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:22:10:22:10 | z | provenance | Sink:MaD:23488 | +| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:22:10:22:10 | z | provenance | Sink:MaD:23496 | | test.cpp:21:27:21:27 | x | test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | provenance | | -| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:23490 | +| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:23498 | | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | | -| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:26:10:26:11 | y2 | provenance | Sink:MaD:23488 | +| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:26:10:26:11 | y2 | provenance | Sink:MaD:23496 | | test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | provenance | | -| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:23491 | +| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:23499 | | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | provenance | | -| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:33:10:33:11 | z2 | provenance | Sink:MaD:23488 | +| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:33:10:33:11 | z2 | provenance | Sink:MaD:23496 | | test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | provenance | | | test.cpp:32:41:32:41 | x | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | provenance | | +| windows.cpp:6:8:6:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:6:8:6:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:331 | +| windows.cpp:11:15:11:29 | *call to GetCommandLineA | windows.cpp:11:15:11:29 | *call to GetCommandLineA | provenance | Src:MaD:325 | +| windows.cpp:11:15:11:29 | *call to GetCommandLineA | windows.cpp:13:8:13:11 | * ... | provenance | | +| windows.cpp:11:15:11:29 | *call to GetCommandLineA | windows.cpp:16:36:16:38 | *cmd | provenance | | +| windows.cpp:16:17:16:34 | **call to CommandLineToArgvA | windows.cpp:16:17:16:34 | **call to CommandLineToArgvA | provenance | | +| windows.cpp:16:17:16:34 | **call to CommandLineToArgvA | windows.cpp:19:8:19:15 | * ... | provenance | | +| windows.cpp:16:36:16:38 | *cmd | windows.cpp:6:8:6:25 | [summary param] *0 in CommandLineToArgvA | provenance | | +| windows.cpp:16:36:16:38 | *cmd | windows.cpp:16:17:16:34 | **call to CommandLineToArgvA | provenance | MaD:331 | +| windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | provenance | Src:MaD:327 | +| windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | windows.cpp:25:10:25:13 | * ... | provenance | | +| windows.cpp:28:36:28:38 | GetEnvironmentVariableA output argument | windows.cpp:30:10:30:13 | * ... | provenance | Src:MaD:329 | nodes | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | semmle.label | [summary param] *0 in buffer | | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | semmle.label | [summary] to write: ReturnValue in buffer | @@ -78,9 +89,24 @@ nodes | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | semmle.label | call to ymlStepGenerated_with_body | | test.cpp:32:41:32:41 | x | semmle.label | x | | test.cpp:33:10:33:11 | z2 | semmle.label | z2 | +| windows.cpp:6:8:6:25 | [summary param] *0 in CommandLineToArgvA | semmle.label | [summary param] *0 in CommandLineToArgvA | +| windows.cpp:6:8:6:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | semmle.label | [summary] to write: ReturnValue[**] in CommandLineToArgvA | +| windows.cpp:11:15:11:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA | +| windows.cpp:11:15:11:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA | +| windows.cpp:13:8:13:11 | * ... | semmle.label | * ... | +| windows.cpp:16:17:16:34 | **call to CommandLineToArgvA | semmle.label | **call to CommandLineToArgvA | +| windows.cpp:16:17:16:34 | **call to CommandLineToArgvA | semmle.label | **call to CommandLineToArgvA | +| windows.cpp:16:36:16:38 | *cmd | semmle.label | *cmd | +| windows.cpp:19:8:19:15 | * ... | semmle.label | * ... | +| windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | semmle.label | *call to GetEnvironmentStringsA | +| windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | semmle.label | *call to GetEnvironmentStringsA | +| windows.cpp:25:10:25:13 | * ... | semmle.label | * ... | +| windows.cpp:28:36:28:38 | GetEnvironmentVariableA output argument | semmle.label | GetEnvironmentVariableA output argument | +| windows.cpp:30:10:30:13 | * ... | semmle.label | * ... | subpaths | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | asio_streams.cpp:100:44:100:62 | call to buffer | | test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual | | test.cpp:21:27:21:27 | x | test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | test.cpp:21:10:21:25 | call to ymlStepGenerated | | test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | | test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | +| windows.cpp:16:36:16:38 | *cmd | windows.cpp:6:8:6:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:6:8:6:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | windows.cpp:16:17:16:34 | **call to CommandLineToArgvA | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/sources.expected b/cpp/ql/test/library-tests/dataflow/external-models/sources.expected index 3e71025e7ff..1c21bf85121 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/sources.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/sources.expected @@ -1,2 +1,5 @@ | asio_streams.cpp:87:34:87:44 | read_until output argument | remote | | test.cpp:10:10:10:18 | call to ymlSource | local | +| windows.cpp:11:15:11:29 | *call to GetCommandLineA | local | +| windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | local | +| windows.cpp:28:36:28:38 | GetEnvironmentVariableA output argument | local | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/steps.expected b/cpp/ql/test/library-tests/dataflow/external-models/steps.expected index aab2691cda1..ccdec4aefcb 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/steps.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/steps.expected @@ -5,3 +5,4 @@ | test.cpp:28:35:28:35 | 0 | test.cpp:28:11:28:33 | call to ymlStepManual_with_body | | test.cpp:32:38:32:38 | 0 | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | | test.cpp:35:38:35:38 | x | test.cpp:35:11:35:36 | call to ymlStepGenerated_with_body | +| windows.cpp:16:36:16:38 | *cmd | windows.cpp:16:17:16:34 | **call to CommandLineToArgvA | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp b/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp index 33f496be0f0..dfa055fa1e8 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp +++ b/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp @@ -10,22 +10,22 @@ int GetEnvironmentVariableA(const char*, char*, int); void getCommandLine() { char* cmd = GetCommandLineA(); sink(cmd); - sink(*cmd); // $ MISSING: ir + sink(*cmd); // $ ir int argc; char** argv = CommandLineToArgvA(cmd, &argc); sink(argv); sink(argv[1]); - sink(*argv[1]); // $ MISSING: ir + sink(*argv[1]); // $ ir } void getEnvironment() { char* env = GetEnvironmentStringsA(); sink(env); - sink(*env); // $ MISSING: ir + sink(*env); // $ ir char buf[1024]; GetEnvironmentVariableA("FOO", buf, sizeof(buf)); sink(buf); - sink(*buf); // $ MISSING: ir + sink(*buf); // $ ir } From 10f6e1ceb81be20b96d709d0a9d849052d81492b Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Fri, 23 May 2025 16:08:25 +0200 Subject: [PATCH 48/86] C++: Add change note --- cpp/ql/lib/change-notes/2025-05-23-windows-sources.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2025-05-23-windows-sources.md diff --git a/cpp/ql/lib/change-notes/2025-05-23-windows-sources.md b/cpp/ql/lib/change-notes/2025-05-23-windows-sources.md new file mode 100644 index 00000000000..e07dcbe8598 --- /dev/null +++ b/cpp/ql/lib/change-notes/2025-05-23-windows-sources.md @@ -0,0 +1,6 @@ +--- +category: feature +--- +* Added the `pCmdLine` arguments of `WinMain` and `wWinMain` as local flow sources. +* Added source models for `GetCommandLineA`, `GetCommandLineW`, `GetEnvironmentStringsA`, `GetEnvironmentStringsW`, `GetEnvironmentVariableA`, and `GetEnvironmentVariableW`. +* Added summary models for `CommandLineToArgvA` and `CommandLineToArgvW`. From e4d1b01361b3df52d9e096e3ae2de743ca3b67da Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Sat, 24 May 2025 08:56:33 +0200 Subject: [PATCH 49/86] Rust: Add type inference test with function call to trait method --- .../test/library-tests/type-inference/main.rs | 26 + .../type-inference/type-inference.expected | 3039 +++++++++-------- 2 files changed, 1554 insertions(+), 1511 deletions(-) diff --git a/rust/ql/test/library-tests/type-inference/main.rs b/rust/ql/test/library-tests/type-inference/main.rs index b33010e7b83..48964f9fb37 100644 --- a/rust/ql/test/library-tests/type-inference/main.rs +++ b/rust/ql/test/library-tests/type-inference/main.rs @@ -90,6 +90,32 @@ mod method_impl { } } +mod trait_impl { + #[derive(Debug)] + struct MyThing { + field: bool, + } + + trait MyTrait { + fn trait_method(self) -> B; + } + + impl MyTrait for MyThing { + // MyThing::trait_method + fn trait_method(self) -> bool { + self.field // $ fieldof=MyThing + } + } + + pub fn f() { + let x = MyThing { field: true }; + let a = x.trait_method(); // $ type=a:bool method=MyThing::trait_method + + let y = MyThing { field: false }; + let b = MyTrait::trait_method(y); // $ type=b:bool MISSING: method=MyThing::trait_method + } +} + mod method_non_parametric_impl { #[derive(Debug)] struct MyThing { diff --git a/rust/ql/test/library-tests/type-inference/type-inference.expected b/rust/ql/test/library-tests/type-inference/type-inference.expected index 4657df91cf3..8c3b8bc7d39 100644 --- a/rust/ql/test/library-tests/type-inference/type-inference.expected +++ b/rust/ql/test/library-tests/type-inference/type-inference.expected @@ -88,1520 +88,1537 @@ inferType | main.rs:88:9:88:14 | x.m1() | | main.rs:67:5:67:21 | Foo | | main.rs:89:9:89:9 | y | | main.rs:67:5:67:21 | Foo | | main.rs:89:9:89:14 | y.m2() | | main.rs:67:5:67:21 | Foo | -| main.rs:106:15:106:18 | SelfParam | | main.rs:94:5:97:5 | MyThing | -| main.rs:106:15:106:18 | SelfParam | A | main.rs:99:5:100:14 | S1 | -| main.rs:106:27:108:9 | { ... } | | main.rs:99:5:100:14 | S1 | -| main.rs:107:13:107:16 | self | | main.rs:94:5:97:5 | MyThing | -| main.rs:107:13:107:16 | self | A | main.rs:99:5:100:14 | S1 | -| main.rs:107:13:107:18 | self.a | | main.rs:99:5:100:14 | S1 | -| main.rs:113:15:113:18 | SelfParam | | main.rs:94:5:97:5 | MyThing | -| main.rs:113:15:113:18 | SelfParam | A | main.rs:101:5:102:14 | S2 | -| main.rs:113:29:115:9 | { ... } | | main.rs:94:5:97:5 | MyThing | -| main.rs:113:29:115:9 | { ... } | A | main.rs:101:5:102:14 | S2 | -| main.rs:114:13:114:30 | Self {...} | | main.rs:94:5:97:5 | MyThing | -| main.rs:114:13:114:30 | Self {...} | A | main.rs:101:5:102:14 | S2 | -| main.rs:114:23:114:26 | self | | main.rs:94:5:97:5 | MyThing | -| main.rs:114:23:114:26 | self | A | main.rs:101:5:102:14 | S2 | -| main.rs:114:23:114:28 | self.a | | main.rs:101:5:102:14 | S2 | -| main.rs:119:15:119:18 | SelfParam | | main.rs:94:5:97:5 | MyThing | -| main.rs:119:15:119:18 | SelfParam | A | main.rs:118:10:118:10 | T | -| main.rs:119:26:121:9 | { ... } | | main.rs:118:10:118:10 | T | -| main.rs:120:13:120:16 | self | | main.rs:94:5:97:5 | MyThing | -| main.rs:120:13:120:16 | self | A | main.rs:118:10:118:10 | T | -| main.rs:120:13:120:18 | self.a | | main.rs:118:10:118:10 | T | -| main.rs:125:13:125:13 | x | | main.rs:94:5:97:5 | MyThing | -| main.rs:125:13:125:13 | x | A | main.rs:99:5:100:14 | S1 | -| main.rs:125:17:125:33 | MyThing {...} | | main.rs:94:5:97:5 | MyThing | -| main.rs:125:17:125:33 | MyThing {...} | A | main.rs:99:5:100:14 | S1 | -| main.rs:125:30:125:31 | S1 | | main.rs:99:5:100:14 | S1 | -| main.rs:126:13:126:13 | y | | main.rs:94:5:97:5 | MyThing | -| main.rs:126:13:126:13 | y | A | main.rs:101:5:102:14 | S2 | -| main.rs:126:17:126:33 | MyThing {...} | | main.rs:94:5:97:5 | MyThing | -| main.rs:126:17:126:33 | MyThing {...} | A | main.rs:101:5:102:14 | S2 | -| main.rs:126:30:126:31 | S2 | | main.rs:101:5:102:14 | S2 | -| main.rs:129:18:129:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:129:26:129:26 | x | | main.rs:94:5:97:5 | MyThing | -| main.rs:129:26:129:26 | x | A | main.rs:99:5:100:14 | S1 | -| main.rs:129:26:129:28 | x.a | | main.rs:99:5:100:14 | S1 | -| main.rs:130:18:130:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:130:26:130:26 | y | | main.rs:94:5:97:5 | MyThing | -| main.rs:130:26:130:26 | y | A | main.rs:101:5:102:14 | S2 | -| main.rs:130:26:130:28 | y.a | | main.rs:101:5:102:14 | S2 | -| main.rs:132:18:132:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:132:26:132:26 | x | | main.rs:94:5:97:5 | MyThing | -| main.rs:132:26:132:26 | x | A | main.rs:99:5:100:14 | S1 | -| main.rs:132:26:132:31 | x.m1() | | main.rs:99:5:100:14 | S1 | -| main.rs:133:18:133:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:133:26:133:26 | y | | main.rs:94:5:97:5 | MyThing | -| main.rs:133:26:133:26 | y | A | main.rs:101:5:102:14 | S2 | -| main.rs:133:26:133:31 | y.m1() | | main.rs:94:5:97:5 | MyThing | -| main.rs:133:26:133:31 | y.m1() | A | main.rs:101:5:102:14 | S2 | -| main.rs:133:26:133:33 | ... .a | | main.rs:101:5:102:14 | S2 | -| main.rs:135:13:135:13 | x | | main.rs:94:5:97:5 | MyThing | -| main.rs:135:13:135:13 | x | A | main.rs:99:5:100:14 | S1 | -| main.rs:135:17:135:33 | MyThing {...} | | main.rs:94:5:97:5 | MyThing | -| main.rs:135:17:135:33 | MyThing {...} | A | main.rs:99:5:100:14 | S1 | -| main.rs:135:30:135:31 | S1 | | main.rs:99:5:100:14 | S1 | -| main.rs:136:13:136:13 | y | | main.rs:94:5:97:5 | MyThing | -| main.rs:136:13:136:13 | y | A | main.rs:101:5:102:14 | S2 | -| main.rs:136:17:136:33 | MyThing {...} | | main.rs:94:5:97:5 | MyThing | -| main.rs:136:17:136:33 | MyThing {...} | A | main.rs:101:5:102:14 | S2 | -| main.rs:136:30:136:31 | S2 | | main.rs:101:5:102:14 | S2 | -| main.rs:138:18:138:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:138:26:138:26 | x | | main.rs:94:5:97:5 | MyThing | -| main.rs:138:26:138:26 | x | A | main.rs:99:5:100:14 | S1 | -| main.rs:138:26:138:31 | x.m2() | | main.rs:99:5:100:14 | S1 | -| main.rs:139:18:139:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:139:26:139:26 | y | | main.rs:94:5:97:5 | MyThing | -| main.rs:139:26:139:26 | y | A | main.rs:101:5:102:14 | S2 | -| main.rs:139:26:139:31 | y.m2() | | main.rs:101:5:102:14 | S2 | -| main.rs:163:15:163:18 | SelfParam | | main.rs:162:5:171:5 | Self [trait MyTrait] | -| main.rs:165:15:165:18 | SelfParam | | main.rs:162:5:171:5 | Self [trait MyTrait] | -| main.rs:168:9:170:9 | { ... } | | main.rs:162:5:171:5 | Self [trait MyTrait] | -| main.rs:169:13:169:16 | self | | main.rs:162:5:171:5 | Self [trait MyTrait] | -| main.rs:175:16:175:19 | SelfParam | | main.rs:173:5:178:5 | Self [trait MyProduct] | -| main.rs:177:16:177:19 | SelfParam | | main.rs:173:5:178:5 | Self [trait MyProduct] | -| main.rs:180:43:180:43 | x | | main.rs:180:26:180:40 | T2 | -| main.rs:180:56:182:5 | { ... } | | main.rs:180:22:180:23 | T1 | -| main.rs:181:9:181:9 | x | | main.rs:180:26:180:40 | T2 | -| main.rs:181:9:181:14 | x.m1() | | main.rs:180:22:180:23 | T1 | -| main.rs:186:15:186:18 | SelfParam | | main.rs:144:5:147:5 | MyThing | -| main.rs:186:15:186:18 | SelfParam | A | main.rs:155:5:156:14 | S1 | -| main.rs:186:27:188:9 | { ... } | | main.rs:155:5:156:14 | S1 | -| main.rs:187:13:187:16 | self | | main.rs:144:5:147:5 | MyThing | -| main.rs:187:13:187:16 | self | A | main.rs:155:5:156:14 | S1 | -| main.rs:187:13:187:18 | self.a | | main.rs:155:5:156:14 | S1 | -| main.rs:193:15:193:18 | SelfParam | | main.rs:144:5:147:5 | MyThing | -| main.rs:193:15:193:18 | SelfParam | A | main.rs:157:5:158:14 | S2 | -| main.rs:193:29:195:9 | { ... } | | main.rs:144:5:147:5 | MyThing | -| main.rs:193:29:195:9 | { ... } | A | main.rs:157:5:158:14 | S2 | -| main.rs:194:13:194:30 | Self {...} | | main.rs:144:5:147:5 | MyThing | -| main.rs:194:13:194:30 | Self {...} | A | main.rs:157:5:158:14 | S2 | -| main.rs:194:23:194:26 | self | | main.rs:144:5:147:5 | MyThing | -| main.rs:194:23:194:26 | self | A | main.rs:157:5:158:14 | S2 | -| main.rs:194:23:194:28 | self.a | | main.rs:157:5:158:14 | S2 | -| main.rs:205:15:205:18 | SelfParam | | main.rs:144:5:147:5 | MyThing | -| main.rs:205:15:205:18 | SelfParam | A | main.rs:159:5:160:14 | S3 | -| main.rs:205:27:207:9 | { ... } | | main.rs:200:10:200:11 | TD | -| main.rs:206:13:206:25 | ...::default(...) | | main.rs:200:10:200:11 | TD | -| main.rs:212:15:212:18 | SelfParam | | main.rs:149:5:153:5 | MyPair | -| main.rs:212:15:212:18 | SelfParam | P1 | main.rs:210:10:210:10 | I | -| main.rs:212:15:212:18 | SelfParam | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:212:26:214:9 | { ... } | | main.rs:210:10:210:10 | I | -| main.rs:213:13:213:16 | self | | main.rs:149:5:153:5 | MyPair | -| main.rs:213:13:213:16 | self | P1 | main.rs:210:10:210:10 | I | -| main.rs:213:13:213:16 | self | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:213:13:213:19 | self.p1 | | main.rs:210:10:210:10 | I | -| main.rs:219:15:219:18 | SelfParam | | main.rs:149:5:153:5 | MyPair | -| main.rs:219:15:219:18 | SelfParam | P1 | main.rs:155:5:156:14 | S1 | -| main.rs:219:15:219:18 | SelfParam | P2 | main.rs:157:5:158:14 | S2 | -| main.rs:219:27:221:9 | { ... } | | main.rs:159:5:160:14 | S3 | -| main.rs:220:13:220:14 | S3 | | main.rs:159:5:160:14 | S3 | -| main.rs:226:15:226:18 | SelfParam | | main.rs:149:5:153:5 | MyPair | -| main.rs:226:15:226:18 | SelfParam | P1 | main.rs:144:5:147:5 | MyThing | -| main.rs:226:15:226:18 | SelfParam | P1.A | main.rs:224:10:224:11 | TT | -| main.rs:226:15:226:18 | SelfParam | P2 | main.rs:159:5:160:14 | S3 | -| main.rs:226:27:229:9 | { ... } | | main.rs:224:10:224:11 | TT | -| main.rs:227:17:227:21 | alpha | | main.rs:144:5:147:5 | MyThing | -| main.rs:227:17:227:21 | alpha | A | main.rs:224:10:224:11 | TT | -| main.rs:227:25:227:28 | self | | main.rs:149:5:153:5 | MyPair | -| main.rs:227:25:227:28 | self | P1 | main.rs:144:5:147:5 | MyThing | -| main.rs:227:25:227:28 | self | P1.A | main.rs:224:10:224:11 | TT | -| main.rs:227:25:227:28 | self | P2 | main.rs:159:5:160:14 | S3 | -| main.rs:227:25:227:31 | self.p1 | | main.rs:144:5:147:5 | MyThing | -| main.rs:227:25:227:31 | self.p1 | A | main.rs:224:10:224:11 | TT | -| main.rs:228:13:228:17 | alpha | | main.rs:144:5:147:5 | MyThing | -| main.rs:228:13:228:17 | alpha | A | main.rs:224:10:224:11 | TT | -| main.rs:228:13:228:19 | alpha.a | | main.rs:224:10:224:11 | TT | -| main.rs:235:16:235:19 | SelfParam | | main.rs:149:5:153:5 | MyPair | -| main.rs:235:16:235:19 | SelfParam | P1 | main.rs:233:10:233:10 | A | -| main.rs:235:16:235:19 | SelfParam | P2 | main.rs:233:10:233:10 | A | -| main.rs:235:27:237:9 | { ... } | | main.rs:233:10:233:10 | A | -| main.rs:236:13:236:16 | self | | main.rs:149:5:153:5 | MyPair | -| main.rs:236:13:236:16 | self | P1 | main.rs:233:10:233:10 | A | -| main.rs:236:13:236:16 | self | P2 | main.rs:233:10:233:10 | A | -| main.rs:236:13:236:19 | self.p1 | | main.rs:233:10:233:10 | A | -| main.rs:240:16:240:19 | SelfParam | | main.rs:149:5:153:5 | MyPair | -| main.rs:240:16:240:19 | SelfParam | P1 | main.rs:233:10:233:10 | A | -| main.rs:240:16:240:19 | SelfParam | P2 | main.rs:233:10:233:10 | A | -| main.rs:240:27:242:9 | { ... } | | main.rs:233:10:233:10 | A | -| main.rs:241:13:241:16 | self | | main.rs:149:5:153:5 | MyPair | -| main.rs:241:13:241:16 | self | P1 | main.rs:233:10:233:10 | A | -| main.rs:241:13:241:16 | self | P2 | main.rs:233:10:233:10 | A | -| main.rs:241:13:241:19 | self.p2 | | main.rs:233:10:233:10 | A | -| main.rs:248:16:248:19 | SelfParam | | main.rs:149:5:153:5 | MyPair | -| main.rs:248:16:248:19 | SelfParam | P1 | main.rs:157:5:158:14 | S2 | -| main.rs:248:16:248:19 | SelfParam | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:248:28:250:9 | { ... } | | main.rs:155:5:156:14 | S1 | -| main.rs:249:13:249:16 | self | | main.rs:149:5:153:5 | MyPair | -| main.rs:249:13:249:16 | self | P1 | main.rs:157:5:158:14 | S2 | -| main.rs:249:13:249:16 | self | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:249:13:249:19 | self.p2 | | main.rs:155:5:156:14 | S1 | -| main.rs:253:16:253:19 | SelfParam | | main.rs:149:5:153:5 | MyPair | -| main.rs:253:16:253:19 | SelfParam | P1 | main.rs:157:5:158:14 | S2 | -| main.rs:253:16:253:19 | SelfParam | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:253:28:255:9 | { ... } | | main.rs:157:5:158:14 | S2 | -| main.rs:254:13:254:16 | self | | main.rs:149:5:153:5 | MyPair | -| main.rs:254:13:254:16 | self | P1 | main.rs:157:5:158:14 | S2 | -| main.rs:254:13:254:16 | self | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:254:13:254:19 | self.p1 | | main.rs:157:5:158:14 | S2 | -| main.rs:258:46:258:46 | p | | main.rs:258:24:258:43 | P | -| main.rs:258:58:260:5 | { ... } | | main.rs:258:16:258:17 | V1 | -| main.rs:259:9:259:9 | p | | main.rs:258:24:258:43 | P | -| main.rs:259:9:259:15 | p.fst() | | main.rs:258:16:258:17 | V1 | -| main.rs:262:46:262:46 | p | | main.rs:262:24:262:43 | P | -| main.rs:262:58:264:5 | { ... } | | main.rs:262:20:262:21 | V2 | -| main.rs:263:9:263:9 | p | | main.rs:262:24:262:43 | P | -| main.rs:263:9:263:15 | p.snd() | | main.rs:262:20:262:21 | V2 | -| main.rs:266:54:266:54 | p | | main.rs:149:5:153:5 | MyPair | -| main.rs:266:54:266:54 | p | P1 | main.rs:266:20:266:21 | V0 | -| main.rs:266:54:266:54 | p | P2 | main.rs:266:32:266:51 | P | -| main.rs:266:78:268:5 | { ... } | | main.rs:266:24:266:25 | V1 | -| main.rs:267:9:267:9 | p | | main.rs:149:5:153:5 | MyPair | -| main.rs:267:9:267:9 | p | P1 | main.rs:266:20:266:21 | V0 | -| main.rs:267:9:267:9 | p | P2 | main.rs:266:32:266:51 | P | -| main.rs:267:9:267:12 | p.p2 | | main.rs:266:32:266:51 | P | -| main.rs:267:9:267:18 | ... .fst() | | main.rs:266:24:266:25 | V1 | -| main.rs:272:23:272:26 | SelfParam | | main.rs:270:5:273:5 | Self [trait ConvertTo] | -| main.rs:277:23:277:26 | SelfParam | | main.rs:275:10:275:23 | T | -| main.rs:277:35:279:9 | { ... } | | main.rs:155:5:156:14 | S1 | -| main.rs:278:13:278:16 | self | | main.rs:275:10:275:23 | T | -| main.rs:278:13:278:21 | self.m1() | | main.rs:155:5:156:14 | S1 | -| main.rs:282:41:282:45 | thing | | main.rs:282:23:282:38 | T | -| main.rs:282:57:284:5 | { ... } | | main.rs:282:19:282:20 | TS | -| main.rs:283:9:283:13 | thing | | main.rs:282:23:282:38 | T | -| main.rs:283:9:283:26 | thing.convert_to() | | main.rs:282:19:282:20 | TS | -| main.rs:286:56:286:60 | thing | | main.rs:286:39:286:53 | TP | -| main.rs:286:73:289:5 | { ... } | | main.rs:155:5:156:14 | S1 | -| main.rs:288:9:288:13 | thing | | main.rs:286:39:286:53 | TP | -| main.rs:288:9:288:26 | thing.convert_to() | | main.rs:155:5:156:14 | S1 | -| main.rs:292:13:292:20 | thing_s1 | | main.rs:144:5:147:5 | MyThing | -| main.rs:292:13:292:20 | thing_s1 | A | main.rs:155:5:156:14 | S1 | -| main.rs:292:24:292:40 | MyThing {...} | | main.rs:144:5:147:5 | MyThing | -| main.rs:292:24:292:40 | MyThing {...} | A | main.rs:155:5:156:14 | S1 | -| main.rs:292:37:292:38 | S1 | | main.rs:155:5:156:14 | S1 | -| main.rs:293:13:293:20 | thing_s2 | | main.rs:144:5:147:5 | MyThing | -| main.rs:293:13:293:20 | thing_s2 | A | main.rs:157:5:158:14 | S2 | -| main.rs:293:24:293:40 | MyThing {...} | | main.rs:144:5:147:5 | MyThing | -| main.rs:293:24:293:40 | MyThing {...} | A | main.rs:157:5:158:14 | S2 | -| main.rs:293:37:293:38 | S2 | | main.rs:157:5:158:14 | S2 | -| main.rs:294:13:294:20 | thing_s3 | | main.rs:144:5:147:5 | MyThing | -| main.rs:294:13:294:20 | thing_s3 | A | main.rs:159:5:160:14 | S3 | -| main.rs:294:24:294:40 | MyThing {...} | | main.rs:144:5:147:5 | MyThing | -| main.rs:294:24:294:40 | MyThing {...} | A | main.rs:159:5:160:14 | S3 | -| main.rs:294:37:294:38 | S3 | | main.rs:159:5:160:14 | S3 | -| main.rs:298:18:298:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:298:26:298:33 | thing_s1 | | main.rs:144:5:147:5 | MyThing | -| main.rs:298:26:298:33 | thing_s1 | A | main.rs:155:5:156:14 | S1 | -| main.rs:298:26:298:38 | thing_s1.m1() | | main.rs:155:5:156:14 | S1 | -| main.rs:299:18:299:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:299:26:299:33 | thing_s2 | | main.rs:144:5:147:5 | MyThing | -| main.rs:299:26:299:33 | thing_s2 | A | main.rs:157:5:158:14 | S2 | -| main.rs:299:26:299:38 | thing_s2.m1() | | main.rs:144:5:147:5 | MyThing | -| main.rs:299:26:299:38 | thing_s2.m1() | A | main.rs:157:5:158:14 | S2 | -| main.rs:299:26:299:40 | ... .a | | main.rs:157:5:158:14 | S2 | -| main.rs:300:13:300:14 | s3 | | main.rs:159:5:160:14 | S3 | -| main.rs:300:22:300:29 | thing_s3 | | main.rs:144:5:147:5 | MyThing | -| main.rs:300:22:300:29 | thing_s3 | A | main.rs:159:5:160:14 | S3 | -| main.rs:300:22:300:34 | thing_s3.m1() | | main.rs:159:5:160:14 | S3 | -| main.rs:301:18:301:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:301:26:301:27 | s3 | | main.rs:159:5:160:14 | S3 | -| main.rs:303:13:303:14 | p1 | | main.rs:149:5:153:5 | MyPair | -| main.rs:303:13:303:14 | p1 | P1 | main.rs:155:5:156:14 | S1 | -| main.rs:303:13:303:14 | p1 | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:303:18:303:42 | MyPair {...} | | main.rs:149:5:153:5 | MyPair | -| main.rs:303:18:303:42 | MyPair {...} | P1 | main.rs:155:5:156:14 | S1 | -| main.rs:303:18:303:42 | MyPair {...} | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:303:31:303:32 | S1 | | main.rs:155:5:156:14 | S1 | -| main.rs:303:39:303:40 | S1 | | main.rs:155:5:156:14 | S1 | -| main.rs:304:18:304:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:304:26:304:27 | p1 | | main.rs:149:5:153:5 | MyPair | -| main.rs:304:26:304:27 | p1 | P1 | main.rs:155:5:156:14 | S1 | -| main.rs:304:26:304:27 | p1 | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:304:26:304:32 | p1.m1() | | main.rs:155:5:156:14 | S1 | -| main.rs:306:13:306:14 | p2 | | main.rs:149:5:153:5 | MyPair | -| main.rs:306:13:306:14 | p2 | P1 | main.rs:155:5:156:14 | S1 | -| main.rs:306:13:306:14 | p2 | P2 | main.rs:157:5:158:14 | S2 | -| main.rs:306:18:306:42 | MyPair {...} | | main.rs:149:5:153:5 | MyPair | -| main.rs:306:18:306:42 | MyPair {...} | P1 | main.rs:155:5:156:14 | S1 | -| main.rs:306:18:306:42 | MyPair {...} | P2 | main.rs:157:5:158:14 | S2 | -| main.rs:306:31:306:32 | S1 | | main.rs:155:5:156:14 | S1 | -| main.rs:306:39:306:40 | S2 | | main.rs:157:5:158:14 | S2 | -| main.rs:307:18:307:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:307:26:307:27 | p2 | | main.rs:149:5:153:5 | MyPair | -| main.rs:307:26:307:27 | p2 | P1 | main.rs:155:5:156:14 | S1 | -| main.rs:307:26:307:27 | p2 | P2 | main.rs:157:5:158:14 | S2 | -| main.rs:307:26:307:32 | p2.m1() | | main.rs:159:5:160:14 | S3 | -| main.rs:309:13:309:14 | p3 | | main.rs:149:5:153:5 | MyPair | -| main.rs:309:13:309:14 | p3 | P1 | main.rs:144:5:147:5 | MyThing | -| main.rs:309:13:309:14 | p3 | P1.A | main.rs:155:5:156:14 | S1 | -| main.rs:309:13:309:14 | p3 | P2 | main.rs:159:5:160:14 | S3 | -| main.rs:309:18:312:9 | MyPair {...} | | main.rs:149:5:153:5 | MyPair | -| main.rs:309:18:312:9 | MyPair {...} | P1 | main.rs:144:5:147:5 | MyThing | -| main.rs:309:18:312:9 | MyPair {...} | P1.A | main.rs:155:5:156:14 | S1 | -| main.rs:309:18:312:9 | MyPair {...} | P2 | main.rs:159:5:160:14 | S3 | -| main.rs:310:17:310:33 | MyThing {...} | | main.rs:144:5:147:5 | MyThing | -| main.rs:310:17:310:33 | MyThing {...} | A | main.rs:155:5:156:14 | S1 | -| main.rs:310:30:310:31 | S1 | | main.rs:155:5:156:14 | S1 | -| main.rs:311:17:311:18 | S3 | | main.rs:159:5:160:14 | S3 | -| main.rs:313:18:313:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:313:26:313:27 | p3 | | main.rs:149:5:153:5 | MyPair | -| main.rs:313:26:313:27 | p3 | P1 | main.rs:144:5:147:5 | MyThing | -| main.rs:313:26:313:27 | p3 | P1.A | main.rs:155:5:156:14 | S1 | -| main.rs:313:26:313:27 | p3 | P2 | main.rs:159:5:160:14 | S3 | -| main.rs:313:26:313:32 | p3.m1() | | main.rs:155:5:156:14 | S1 | -| main.rs:316:13:316:13 | a | | main.rs:149:5:153:5 | MyPair | -| main.rs:316:13:316:13 | a | P1 | main.rs:155:5:156:14 | S1 | -| main.rs:316:13:316:13 | a | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:316:17:316:41 | MyPair {...} | | main.rs:149:5:153:5 | MyPair | -| main.rs:316:17:316:41 | MyPair {...} | P1 | main.rs:155:5:156:14 | S1 | -| main.rs:316:17:316:41 | MyPair {...} | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:316:30:316:31 | S1 | | main.rs:155:5:156:14 | S1 | -| main.rs:316:38:316:39 | S1 | | main.rs:155:5:156:14 | S1 | -| main.rs:317:13:317:13 | x | | main.rs:155:5:156:14 | S1 | -| main.rs:317:17:317:17 | a | | main.rs:149:5:153:5 | MyPair | -| main.rs:317:17:317:17 | a | P1 | main.rs:155:5:156:14 | S1 | -| main.rs:317:17:317:17 | a | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:317:17:317:23 | a.fst() | | main.rs:155:5:156:14 | S1 | -| main.rs:318:18:318:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:318:26:318:26 | x | | main.rs:155:5:156:14 | S1 | -| main.rs:319:13:319:13 | y | | main.rs:155:5:156:14 | S1 | -| main.rs:319:17:319:17 | a | | main.rs:149:5:153:5 | MyPair | -| main.rs:319:17:319:17 | a | P1 | main.rs:155:5:156:14 | S1 | -| main.rs:319:17:319:17 | a | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:319:17:319:23 | a.snd() | | main.rs:155:5:156:14 | S1 | -| main.rs:320:18:320:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:320:26:320:26 | y | | main.rs:155:5:156:14 | S1 | -| main.rs:326:13:326:13 | b | | main.rs:149:5:153:5 | MyPair | -| main.rs:326:13:326:13 | b | P1 | main.rs:157:5:158:14 | S2 | -| main.rs:326:13:326:13 | b | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:326:17:326:41 | MyPair {...} | | main.rs:149:5:153:5 | MyPair | -| main.rs:326:17:326:41 | MyPair {...} | P1 | main.rs:157:5:158:14 | S2 | -| main.rs:326:17:326:41 | MyPair {...} | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:326:30:326:31 | S2 | | main.rs:157:5:158:14 | S2 | -| main.rs:326:38:326:39 | S1 | | main.rs:155:5:156:14 | S1 | -| main.rs:327:13:327:13 | x | | main.rs:155:5:156:14 | S1 | -| main.rs:327:17:327:17 | b | | main.rs:149:5:153:5 | MyPair | -| main.rs:327:17:327:17 | b | P1 | main.rs:157:5:158:14 | S2 | -| main.rs:327:17:327:17 | b | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:327:17:327:23 | b.fst() | | main.rs:155:5:156:14 | S1 | -| main.rs:328:18:328:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:328:26:328:26 | x | | main.rs:155:5:156:14 | S1 | -| main.rs:329:13:329:13 | y | | main.rs:157:5:158:14 | S2 | -| main.rs:329:17:329:17 | b | | main.rs:149:5:153:5 | MyPair | -| main.rs:329:17:329:17 | b | P1 | main.rs:157:5:158:14 | S2 | -| main.rs:329:17:329:17 | b | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:329:17:329:23 | b.snd() | | main.rs:157:5:158:14 | S2 | +| main.rs:100:25:100:28 | SelfParam | | main.rs:99:5:101:5 | Self [trait MyTrait] | +| main.rs:105:25:105:28 | SelfParam | | main.rs:94:5:97:5 | MyThing | +| main.rs:105:39:107:9 | { ... } | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:106:13:106:16 | self | | main.rs:94:5:97:5 | MyThing | +| main.rs:106:13:106:22 | self.field | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:111:13:111:13 | x | | main.rs:94:5:97:5 | MyThing | +| main.rs:111:17:111:39 | MyThing {...} | | main.rs:94:5:97:5 | MyThing | +| main.rs:111:34:111:37 | true | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:112:13:112:13 | a | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:112:17:112:17 | x | | main.rs:94:5:97:5 | MyThing | +| main.rs:112:17:112:32 | x.trait_method() | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:114:13:114:13 | y | | main.rs:94:5:97:5 | MyThing | +| main.rs:114:17:114:40 | MyThing {...} | | main.rs:94:5:97:5 | MyThing | +| main.rs:114:34:114:38 | false | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:115:13:115:13 | b | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:115:17:115:40 | ...::trait_method(...) | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:115:39:115:39 | y | | main.rs:94:5:97:5 | MyThing | +| main.rs:132:15:132:18 | SelfParam | | main.rs:120:5:123:5 | MyThing | +| main.rs:132:15:132:18 | SelfParam | A | main.rs:125:5:126:14 | S1 | +| main.rs:132:27:134:9 | { ... } | | main.rs:125:5:126:14 | S1 | +| main.rs:133:13:133:16 | self | | main.rs:120:5:123:5 | MyThing | +| main.rs:133:13:133:16 | self | A | main.rs:125:5:126:14 | S1 | +| main.rs:133:13:133:18 | self.a | | main.rs:125:5:126:14 | S1 | +| main.rs:139:15:139:18 | SelfParam | | main.rs:120:5:123:5 | MyThing | +| main.rs:139:15:139:18 | SelfParam | A | main.rs:127:5:128:14 | S2 | +| main.rs:139:29:141:9 | { ... } | | main.rs:120:5:123:5 | MyThing | +| main.rs:139:29:141:9 | { ... } | A | main.rs:127:5:128:14 | S2 | +| main.rs:140:13:140:30 | Self {...} | | main.rs:120:5:123:5 | MyThing | +| main.rs:140:13:140:30 | Self {...} | A | main.rs:127:5:128:14 | S2 | +| main.rs:140:23:140:26 | self | | main.rs:120:5:123:5 | MyThing | +| main.rs:140:23:140:26 | self | A | main.rs:127:5:128:14 | S2 | +| main.rs:140:23:140:28 | self.a | | main.rs:127:5:128:14 | S2 | +| main.rs:145:15:145:18 | SelfParam | | main.rs:120:5:123:5 | MyThing | +| main.rs:145:15:145:18 | SelfParam | A | main.rs:144:10:144:10 | T | +| main.rs:145:26:147:9 | { ... } | | main.rs:144:10:144:10 | T | +| main.rs:146:13:146:16 | self | | main.rs:120:5:123:5 | MyThing | +| main.rs:146:13:146:16 | self | A | main.rs:144:10:144:10 | T | +| main.rs:146:13:146:18 | self.a | | main.rs:144:10:144:10 | T | +| main.rs:151:13:151:13 | x | | main.rs:120:5:123:5 | MyThing | +| main.rs:151:13:151:13 | x | A | main.rs:125:5:126:14 | S1 | +| main.rs:151:17:151:33 | MyThing {...} | | main.rs:120:5:123:5 | MyThing | +| main.rs:151:17:151:33 | MyThing {...} | A | main.rs:125:5:126:14 | S1 | +| main.rs:151:30:151:31 | S1 | | main.rs:125:5:126:14 | S1 | +| main.rs:152:13:152:13 | y | | main.rs:120:5:123:5 | MyThing | +| main.rs:152:13:152:13 | y | A | main.rs:127:5:128:14 | S2 | +| main.rs:152:17:152:33 | MyThing {...} | | main.rs:120:5:123:5 | MyThing | +| main.rs:152:17:152:33 | MyThing {...} | A | main.rs:127:5:128:14 | S2 | +| main.rs:152:30:152:31 | S2 | | main.rs:127:5:128:14 | S2 | +| main.rs:155:18:155:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:155:26:155:26 | x | | main.rs:120:5:123:5 | MyThing | +| main.rs:155:26:155:26 | x | A | main.rs:125:5:126:14 | S1 | +| main.rs:155:26:155:28 | x.a | | main.rs:125:5:126:14 | S1 | +| main.rs:156:18:156:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:156:26:156:26 | y | | main.rs:120:5:123:5 | MyThing | +| main.rs:156:26:156:26 | y | A | main.rs:127:5:128:14 | S2 | +| main.rs:156:26:156:28 | y.a | | main.rs:127:5:128:14 | S2 | +| main.rs:158:18:158:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:158:26:158:26 | x | | main.rs:120:5:123:5 | MyThing | +| main.rs:158:26:158:26 | x | A | main.rs:125:5:126:14 | S1 | +| main.rs:158:26:158:31 | x.m1() | | main.rs:125:5:126:14 | S1 | +| main.rs:159:18:159:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:159:26:159:26 | y | | main.rs:120:5:123:5 | MyThing | +| main.rs:159:26:159:26 | y | A | main.rs:127:5:128:14 | S2 | +| main.rs:159:26:159:31 | y.m1() | | main.rs:120:5:123:5 | MyThing | +| main.rs:159:26:159:31 | y.m1() | A | main.rs:127:5:128:14 | S2 | +| main.rs:159:26:159:33 | ... .a | | main.rs:127:5:128:14 | S2 | +| main.rs:161:13:161:13 | x | | main.rs:120:5:123:5 | MyThing | +| main.rs:161:13:161:13 | x | A | main.rs:125:5:126:14 | S1 | +| main.rs:161:17:161:33 | MyThing {...} | | main.rs:120:5:123:5 | MyThing | +| main.rs:161:17:161:33 | MyThing {...} | A | main.rs:125:5:126:14 | S1 | +| main.rs:161:30:161:31 | S1 | | main.rs:125:5:126:14 | S1 | +| main.rs:162:13:162:13 | y | | main.rs:120:5:123:5 | MyThing | +| main.rs:162:13:162:13 | y | A | main.rs:127:5:128:14 | S2 | +| main.rs:162:17:162:33 | MyThing {...} | | main.rs:120:5:123:5 | MyThing | +| main.rs:162:17:162:33 | MyThing {...} | A | main.rs:127:5:128:14 | S2 | +| main.rs:162:30:162:31 | S2 | | main.rs:127:5:128:14 | S2 | +| main.rs:164:18:164:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:164:26:164:26 | x | | main.rs:120:5:123:5 | MyThing | +| main.rs:164:26:164:26 | x | A | main.rs:125:5:126:14 | S1 | +| main.rs:164:26:164:31 | x.m2() | | main.rs:125:5:126:14 | S1 | +| main.rs:165:18:165:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:165:26:165:26 | y | | main.rs:120:5:123:5 | MyThing | +| main.rs:165:26:165:26 | y | A | main.rs:127:5:128:14 | S2 | +| main.rs:165:26:165:31 | y.m2() | | main.rs:127:5:128:14 | S2 | +| main.rs:189:15:189:18 | SelfParam | | main.rs:188:5:197:5 | Self [trait MyTrait] | +| main.rs:191:15:191:18 | SelfParam | | main.rs:188:5:197:5 | Self [trait MyTrait] | +| main.rs:194:9:196:9 | { ... } | | main.rs:188:5:197:5 | Self [trait MyTrait] | +| main.rs:195:13:195:16 | self | | main.rs:188:5:197:5 | Self [trait MyTrait] | +| main.rs:201:16:201:19 | SelfParam | | main.rs:199:5:204:5 | Self [trait MyProduct] | +| main.rs:203:16:203:19 | SelfParam | | main.rs:199:5:204:5 | Self [trait MyProduct] | +| main.rs:206:43:206:43 | x | | main.rs:206:26:206:40 | T2 | +| main.rs:206:56:208:5 | { ... } | | main.rs:206:22:206:23 | T1 | +| main.rs:207:9:207:9 | x | | main.rs:206:26:206:40 | T2 | +| main.rs:207:9:207:14 | x.m1() | | main.rs:206:22:206:23 | T1 | +| main.rs:212:15:212:18 | SelfParam | | main.rs:170:5:173:5 | MyThing | +| main.rs:212:15:212:18 | SelfParam | A | main.rs:181:5:182:14 | S1 | +| main.rs:212:27:214:9 | { ... } | | main.rs:181:5:182:14 | S1 | +| main.rs:213:13:213:16 | self | | main.rs:170:5:173:5 | MyThing | +| main.rs:213:13:213:16 | self | A | main.rs:181:5:182:14 | S1 | +| main.rs:213:13:213:18 | self.a | | main.rs:181:5:182:14 | S1 | +| main.rs:219:15:219:18 | SelfParam | | main.rs:170:5:173:5 | MyThing | +| main.rs:219:15:219:18 | SelfParam | A | main.rs:183:5:184:14 | S2 | +| main.rs:219:29:221:9 | { ... } | | main.rs:170:5:173:5 | MyThing | +| main.rs:219:29:221:9 | { ... } | A | main.rs:183:5:184:14 | S2 | +| main.rs:220:13:220:30 | Self {...} | | main.rs:170:5:173:5 | MyThing | +| main.rs:220:13:220:30 | Self {...} | A | main.rs:183:5:184:14 | S2 | +| main.rs:220:23:220:26 | self | | main.rs:170:5:173:5 | MyThing | +| main.rs:220:23:220:26 | self | A | main.rs:183:5:184:14 | S2 | +| main.rs:220:23:220:28 | self.a | | main.rs:183:5:184:14 | S2 | +| main.rs:231:15:231:18 | SelfParam | | main.rs:170:5:173:5 | MyThing | +| main.rs:231:15:231:18 | SelfParam | A | main.rs:185:5:186:14 | S3 | +| main.rs:231:27:233:9 | { ... } | | main.rs:226:10:226:11 | TD | +| main.rs:232:13:232:25 | ...::default(...) | | main.rs:226:10:226:11 | TD | +| main.rs:238:15:238:18 | SelfParam | | main.rs:175:5:179:5 | MyPair | +| main.rs:238:15:238:18 | SelfParam | P1 | main.rs:236:10:236:10 | I | +| main.rs:238:15:238:18 | SelfParam | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:238:26:240:9 | { ... } | | main.rs:236:10:236:10 | I | +| main.rs:239:13:239:16 | self | | main.rs:175:5:179:5 | MyPair | +| main.rs:239:13:239:16 | self | P1 | main.rs:236:10:236:10 | I | +| main.rs:239:13:239:16 | self | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:239:13:239:19 | self.p1 | | main.rs:236:10:236:10 | I | +| main.rs:245:15:245:18 | SelfParam | | main.rs:175:5:179:5 | MyPair | +| main.rs:245:15:245:18 | SelfParam | P1 | main.rs:181:5:182:14 | S1 | +| main.rs:245:15:245:18 | SelfParam | P2 | main.rs:183:5:184:14 | S2 | +| main.rs:245:27:247:9 | { ... } | | main.rs:185:5:186:14 | S3 | +| main.rs:246:13:246:14 | S3 | | main.rs:185:5:186:14 | S3 | +| main.rs:252:15:252:18 | SelfParam | | main.rs:175:5:179:5 | MyPair | +| main.rs:252:15:252:18 | SelfParam | P1 | main.rs:170:5:173:5 | MyThing | +| main.rs:252:15:252:18 | SelfParam | P1.A | main.rs:250:10:250:11 | TT | +| main.rs:252:15:252:18 | SelfParam | P2 | main.rs:185:5:186:14 | S3 | +| main.rs:252:27:255:9 | { ... } | | main.rs:250:10:250:11 | TT | +| main.rs:253:17:253:21 | alpha | | main.rs:170:5:173:5 | MyThing | +| main.rs:253:17:253:21 | alpha | A | main.rs:250:10:250:11 | TT | +| main.rs:253:25:253:28 | self | | main.rs:175:5:179:5 | MyPair | +| main.rs:253:25:253:28 | self | P1 | main.rs:170:5:173:5 | MyThing | +| main.rs:253:25:253:28 | self | P1.A | main.rs:250:10:250:11 | TT | +| main.rs:253:25:253:28 | self | P2 | main.rs:185:5:186:14 | S3 | +| main.rs:253:25:253:31 | self.p1 | | main.rs:170:5:173:5 | MyThing | +| main.rs:253:25:253:31 | self.p1 | A | main.rs:250:10:250:11 | TT | +| main.rs:254:13:254:17 | alpha | | main.rs:170:5:173:5 | MyThing | +| main.rs:254:13:254:17 | alpha | A | main.rs:250:10:250:11 | TT | +| main.rs:254:13:254:19 | alpha.a | | main.rs:250:10:250:11 | TT | +| main.rs:261:16:261:19 | SelfParam | | main.rs:175:5:179:5 | MyPair | +| main.rs:261:16:261:19 | SelfParam | P1 | main.rs:259:10:259:10 | A | +| main.rs:261:16:261:19 | SelfParam | P2 | main.rs:259:10:259:10 | A | +| main.rs:261:27:263:9 | { ... } | | main.rs:259:10:259:10 | A | +| main.rs:262:13:262:16 | self | | main.rs:175:5:179:5 | MyPair | +| main.rs:262:13:262:16 | self | P1 | main.rs:259:10:259:10 | A | +| main.rs:262:13:262:16 | self | P2 | main.rs:259:10:259:10 | A | +| main.rs:262:13:262:19 | self.p1 | | main.rs:259:10:259:10 | A | +| main.rs:266:16:266:19 | SelfParam | | main.rs:175:5:179:5 | MyPair | +| main.rs:266:16:266:19 | SelfParam | P1 | main.rs:259:10:259:10 | A | +| main.rs:266:16:266:19 | SelfParam | P2 | main.rs:259:10:259:10 | A | +| main.rs:266:27:268:9 | { ... } | | main.rs:259:10:259:10 | A | +| main.rs:267:13:267:16 | self | | main.rs:175:5:179:5 | MyPair | +| main.rs:267:13:267:16 | self | P1 | main.rs:259:10:259:10 | A | +| main.rs:267:13:267:16 | self | P2 | main.rs:259:10:259:10 | A | +| main.rs:267:13:267:19 | self.p2 | | main.rs:259:10:259:10 | A | +| main.rs:274:16:274:19 | SelfParam | | main.rs:175:5:179:5 | MyPair | +| main.rs:274:16:274:19 | SelfParam | P1 | main.rs:183:5:184:14 | S2 | +| main.rs:274:16:274:19 | SelfParam | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:274:28:276:9 | { ... } | | main.rs:181:5:182:14 | S1 | +| main.rs:275:13:275:16 | self | | main.rs:175:5:179:5 | MyPair | +| main.rs:275:13:275:16 | self | P1 | main.rs:183:5:184:14 | S2 | +| main.rs:275:13:275:16 | self | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:275:13:275:19 | self.p2 | | main.rs:181:5:182:14 | S1 | +| main.rs:279:16:279:19 | SelfParam | | main.rs:175:5:179:5 | MyPair | +| main.rs:279:16:279:19 | SelfParam | P1 | main.rs:183:5:184:14 | S2 | +| main.rs:279:16:279:19 | SelfParam | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:279:28:281:9 | { ... } | | main.rs:183:5:184:14 | S2 | +| main.rs:280:13:280:16 | self | | main.rs:175:5:179:5 | MyPair | +| main.rs:280:13:280:16 | self | P1 | main.rs:183:5:184:14 | S2 | +| main.rs:280:13:280:16 | self | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:280:13:280:19 | self.p1 | | main.rs:183:5:184:14 | S2 | +| main.rs:284:46:284:46 | p | | main.rs:284:24:284:43 | P | +| main.rs:284:58:286:5 | { ... } | | main.rs:284:16:284:17 | V1 | +| main.rs:285:9:285:9 | p | | main.rs:284:24:284:43 | P | +| main.rs:285:9:285:15 | p.fst() | | main.rs:284:16:284:17 | V1 | +| main.rs:288:46:288:46 | p | | main.rs:288:24:288:43 | P | +| main.rs:288:58:290:5 | { ... } | | main.rs:288:20:288:21 | V2 | +| main.rs:289:9:289:9 | p | | main.rs:288:24:288:43 | P | +| main.rs:289:9:289:15 | p.snd() | | main.rs:288:20:288:21 | V2 | +| main.rs:292:54:292:54 | p | | main.rs:175:5:179:5 | MyPair | +| main.rs:292:54:292:54 | p | P1 | main.rs:292:20:292:21 | V0 | +| main.rs:292:54:292:54 | p | P2 | main.rs:292:32:292:51 | P | +| main.rs:292:78:294:5 | { ... } | | main.rs:292:24:292:25 | V1 | +| main.rs:293:9:293:9 | p | | main.rs:175:5:179:5 | MyPair | +| main.rs:293:9:293:9 | p | P1 | main.rs:292:20:292:21 | V0 | +| main.rs:293:9:293:9 | p | P2 | main.rs:292:32:292:51 | P | +| main.rs:293:9:293:12 | p.p2 | | main.rs:292:32:292:51 | P | +| main.rs:293:9:293:18 | ... .fst() | | main.rs:292:24:292:25 | V1 | +| main.rs:298:23:298:26 | SelfParam | | main.rs:296:5:299:5 | Self [trait ConvertTo] | +| main.rs:303:23:303:26 | SelfParam | | main.rs:301:10:301:23 | T | +| main.rs:303:35:305:9 | { ... } | | main.rs:181:5:182:14 | S1 | +| main.rs:304:13:304:16 | self | | main.rs:301:10:301:23 | T | +| main.rs:304:13:304:21 | self.m1() | | main.rs:181:5:182:14 | S1 | +| main.rs:308:41:308:45 | thing | | main.rs:308:23:308:38 | T | +| main.rs:308:57:310:5 | { ... } | | main.rs:308:19:308:20 | TS | +| main.rs:309:9:309:13 | thing | | main.rs:308:23:308:38 | T | +| main.rs:309:9:309:26 | thing.convert_to() | | main.rs:308:19:308:20 | TS | +| main.rs:312:56:312:60 | thing | | main.rs:312:39:312:53 | TP | +| main.rs:312:73:315:5 | { ... } | | main.rs:181:5:182:14 | S1 | +| main.rs:314:9:314:13 | thing | | main.rs:312:39:312:53 | TP | +| main.rs:314:9:314:26 | thing.convert_to() | | main.rs:181:5:182:14 | S1 | +| main.rs:318:13:318:20 | thing_s1 | | main.rs:170:5:173:5 | MyThing | +| main.rs:318:13:318:20 | thing_s1 | A | main.rs:181:5:182:14 | S1 | +| main.rs:318:24:318:40 | MyThing {...} | | main.rs:170:5:173:5 | MyThing | +| main.rs:318:24:318:40 | MyThing {...} | A | main.rs:181:5:182:14 | S1 | +| main.rs:318:37:318:38 | S1 | | main.rs:181:5:182:14 | S1 | +| main.rs:319:13:319:20 | thing_s2 | | main.rs:170:5:173:5 | MyThing | +| main.rs:319:13:319:20 | thing_s2 | A | main.rs:183:5:184:14 | S2 | +| main.rs:319:24:319:40 | MyThing {...} | | main.rs:170:5:173:5 | MyThing | +| main.rs:319:24:319:40 | MyThing {...} | A | main.rs:183:5:184:14 | S2 | +| main.rs:319:37:319:38 | S2 | | main.rs:183:5:184:14 | S2 | +| main.rs:320:13:320:20 | thing_s3 | | main.rs:170:5:173:5 | MyThing | +| main.rs:320:13:320:20 | thing_s3 | A | main.rs:185:5:186:14 | S3 | +| main.rs:320:24:320:40 | MyThing {...} | | main.rs:170:5:173:5 | MyThing | +| main.rs:320:24:320:40 | MyThing {...} | A | main.rs:185:5:186:14 | S3 | +| main.rs:320:37:320:38 | S3 | | main.rs:185:5:186:14 | S3 | +| main.rs:324:18:324:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:324:26:324:33 | thing_s1 | | main.rs:170:5:173:5 | MyThing | +| main.rs:324:26:324:33 | thing_s1 | A | main.rs:181:5:182:14 | S1 | +| main.rs:324:26:324:38 | thing_s1.m1() | | main.rs:181:5:182:14 | S1 | +| main.rs:325:18:325:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:325:26:325:33 | thing_s2 | | main.rs:170:5:173:5 | MyThing | +| main.rs:325:26:325:33 | thing_s2 | A | main.rs:183:5:184:14 | S2 | +| main.rs:325:26:325:38 | thing_s2.m1() | | main.rs:170:5:173:5 | MyThing | +| main.rs:325:26:325:38 | thing_s2.m1() | A | main.rs:183:5:184:14 | S2 | +| main.rs:325:26:325:40 | ... .a | | main.rs:183:5:184:14 | S2 | +| main.rs:326:13:326:14 | s3 | | main.rs:185:5:186:14 | S3 | +| main.rs:326:22:326:29 | thing_s3 | | main.rs:170:5:173:5 | MyThing | +| main.rs:326:22:326:29 | thing_s3 | A | main.rs:185:5:186:14 | S3 | +| main.rs:326:22:326:34 | thing_s3.m1() | | main.rs:185:5:186:14 | S3 | +| main.rs:327:18:327:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:327:26:327:27 | s3 | | main.rs:185:5:186:14 | S3 | +| main.rs:329:13:329:14 | p1 | | main.rs:175:5:179:5 | MyPair | +| main.rs:329:13:329:14 | p1 | P1 | main.rs:181:5:182:14 | S1 | +| main.rs:329:13:329:14 | p1 | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:329:18:329:42 | MyPair {...} | | main.rs:175:5:179:5 | MyPair | +| main.rs:329:18:329:42 | MyPair {...} | P1 | main.rs:181:5:182:14 | S1 | +| main.rs:329:18:329:42 | MyPair {...} | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:329:31:329:32 | S1 | | main.rs:181:5:182:14 | S1 | +| main.rs:329:39:329:40 | S1 | | main.rs:181:5:182:14 | S1 | | main.rs:330:18:330:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:330:26:330:26 | y | | main.rs:157:5:158:14 | S2 | -| main.rs:334:13:334:13 | x | | main.rs:155:5:156:14 | S1 | -| main.rs:334:17:334:39 | call_trait_m1(...) | | main.rs:155:5:156:14 | S1 | -| main.rs:334:31:334:38 | thing_s1 | | main.rs:144:5:147:5 | MyThing | -| main.rs:334:31:334:38 | thing_s1 | A | main.rs:155:5:156:14 | S1 | -| main.rs:335:18:335:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:335:26:335:26 | x | | main.rs:155:5:156:14 | S1 | -| main.rs:336:13:336:13 | y | | main.rs:144:5:147:5 | MyThing | -| main.rs:336:13:336:13 | y | A | main.rs:157:5:158:14 | S2 | -| main.rs:336:17:336:39 | call_trait_m1(...) | | main.rs:144:5:147:5 | MyThing | -| main.rs:336:17:336:39 | call_trait_m1(...) | A | main.rs:157:5:158:14 | S2 | -| main.rs:336:31:336:38 | thing_s2 | | main.rs:144:5:147:5 | MyThing | -| main.rs:336:31:336:38 | thing_s2 | A | main.rs:157:5:158:14 | S2 | -| main.rs:337:18:337:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:337:26:337:26 | y | | main.rs:144:5:147:5 | MyThing | -| main.rs:337:26:337:26 | y | A | main.rs:157:5:158:14 | S2 | -| main.rs:337:26:337:28 | y.a | | main.rs:157:5:158:14 | S2 | -| main.rs:340:13:340:13 | a | | main.rs:149:5:153:5 | MyPair | -| main.rs:340:13:340:13 | a | P1 | main.rs:155:5:156:14 | S1 | -| main.rs:340:13:340:13 | a | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:340:17:340:41 | MyPair {...} | | main.rs:149:5:153:5 | MyPair | -| main.rs:340:17:340:41 | MyPair {...} | P1 | main.rs:155:5:156:14 | S1 | -| main.rs:340:17:340:41 | MyPair {...} | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:340:30:340:31 | S1 | | main.rs:155:5:156:14 | S1 | -| main.rs:340:38:340:39 | S1 | | main.rs:155:5:156:14 | S1 | -| main.rs:341:13:341:13 | x | | main.rs:155:5:156:14 | S1 | -| main.rs:341:17:341:26 | get_fst(...) | | main.rs:155:5:156:14 | S1 | -| main.rs:341:25:341:25 | a | | main.rs:149:5:153:5 | MyPair | -| main.rs:341:25:341:25 | a | P1 | main.rs:155:5:156:14 | S1 | -| main.rs:341:25:341:25 | a | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:342:18:342:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:342:26:342:26 | x | | main.rs:155:5:156:14 | S1 | -| main.rs:343:13:343:13 | y | | main.rs:155:5:156:14 | S1 | -| main.rs:343:17:343:26 | get_snd(...) | | main.rs:155:5:156:14 | S1 | -| main.rs:343:25:343:25 | a | | main.rs:149:5:153:5 | MyPair | -| main.rs:343:25:343:25 | a | P1 | main.rs:155:5:156:14 | S1 | -| main.rs:343:25:343:25 | a | P2 | main.rs:155:5:156:14 | S1 | +| main.rs:330:26:330:27 | p1 | | main.rs:175:5:179:5 | MyPair | +| main.rs:330:26:330:27 | p1 | P1 | main.rs:181:5:182:14 | S1 | +| main.rs:330:26:330:27 | p1 | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:330:26:330:32 | p1.m1() | | main.rs:181:5:182:14 | S1 | +| main.rs:332:13:332:14 | p2 | | main.rs:175:5:179:5 | MyPair | +| main.rs:332:13:332:14 | p2 | P1 | main.rs:181:5:182:14 | S1 | +| main.rs:332:13:332:14 | p2 | P2 | main.rs:183:5:184:14 | S2 | +| main.rs:332:18:332:42 | MyPair {...} | | main.rs:175:5:179:5 | MyPair | +| main.rs:332:18:332:42 | MyPair {...} | P1 | main.rs:181:5:182:14 | S1 | +| main.rs:332:18:332:42 | MyPair {...} | P2 | main.rs:183:5:184:14 | S2 | +| main.rs:332:31:332:32 | S1 | | main.rs:181:5:182:14 | S1 | +| main.rs:332:39:332:40 | S2 | | main.rs:183:5:184:14 | S2 | +| main.rs:333:18:333:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:333:26:333:27 | p2 | | main.rs:175:5:179:5 | MyPair | +| main.rs:333:26:333:27 | p2 | P1 | main.rs:181:5:182:14 | S1 | +| main.rs:333:26:333:27 | p2 | P2 | main.rs:183:5:184:14 | S2 | +| main.rs:333:26:333:32 | p2.m1() | | main.rs:185:5:186:14 | S3 | +| main.rs:335:13:335:14 | p3 | | main.rs:175:5:179:5 | MyPair | +| main.rs:335:13:335:14 | p3 | P1 | main.rs:170:5:173:5 | MyThing | +| main.rs:335:13:335:14 | p3 | P1.A | main.rs:181:5:182:14 | S1 | +| main.rs:335:13:335:14 | p3 | P2 | main.rs:185:5:186:14 | S3 | +| main.rs:335:18:338:9 | MyPair {...} | | main.rs:175:5:179:5 | MyPair | +| main.rs:335:18:338:9 | MyPair {...} | P1 | main.rs:170:5:173:5 | MyThing | +| main.rs:335:18:338:9 | MyPair {...} | P1.A | main.rs:181:5:182:14 | S1 | +| main.rs:335:18:338:9 | MyPair {...} | P2 | main.rs:185:5:186:14 | S3 | +| main.rs:336:17:336:33 | MyThing {...} | | main.rs:170:5:173:5 | MyThing | +| main.rs:336:17:336:33 | MyThing {...} | A | main.rs:181:5:182:14 | S1 | +| main.rs:336:30:336:31 | S1 | | main.rs:181:5:182:14 | S1 | +| main.rs:337:17:337:18 | S3 | | main.rs:185:5:186:14 | S3 | +| main.rs:339:18:339:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:339:26:339:27 | p3 | | main.rs:175:5:179:5 | MyPair | +| main.rs:339:26:339:27 | p3 | P1 | main.rs:170:5:173:5 | MyThing | +| main.rs:339:26:339:27 | p3 | P1.A | main.rs:181:5:182:14 | S1 | +| main.rs:339:26:339:27 | p3 | P2 | main.rs:185:5:186:14 | S3 | +| main.rs:339:26:339:32 | p3.m1() | | main.rs:181:5:182:14 | S1 | +| main.rs:342:13:342:13 | a | | main.rs:175:5:179:5 | MyPair | +| main.rs:342:13:342:13 | a | P1 | main.rs:181:5:182:14 | S1 | +| main.rs:342:13:342:13 | a | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:342:17:342:41 | MyPair {...} | | main.rs:175:5:179:5 | MyPair | +| main.rs:342:17:342:41 | MyPair {...} | P1 | main.rs:181:5:182:14 | S1 | +| main.rs:342:17:342:41 | MyPair {...} | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:342:30:342:31 | S1 | | main.rs:181:5:182:14 | S1 | +| main.rs:342:38:342:39 | S1 | | main.rs:181:5:182:14 | S1 | +| main.rs:343:13:343:13 | x | | main.rs:181:5:182:14 | S1 | +| main.rs:343:17:343:17 | a | | main.rs:175:5:179:5 | MyPair | +| main.rs:343:17:343:17 | a | P1 | main.rs:181:5:182:14 | S1 | +| main.rs:343:17:343:17 | a | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:343:17:343:23 | a.fst() | | main.rs:181:5:182:14 | S1 | | main.rs:344:18:344:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:344:26:344:26 | y | | main.rs:155:5:156:14 | S1 | -| main.rs:347:13:347:13 | b | | main.rs:149:5:153:5 | MyPair | -| main.rs:347:13:347:13 | b | P1 | main.rs:157:5:158:14 | S2 | -| main.rs:347:13:347:13 | b | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:347:17:347:41 | MyPair {...} | | main.rs:149:5:153:5 | MyPair | -| main.rs:347:17:347:41 | MyPair {...} | P1 | main.rs:157:5:158:14 | S2 | -| main.rs:347:17:347:41 | MyPair {...} | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:347:30:347:31 | S2 | | main.rs:157:5:158:14 | S2 | -| main.rs:347:38:347:39 | S1 | | main.rs:155:5:156:14 | S1 | -| main.rs:348:13:348:13 | x | | main.rs:155:5:156:14 | S1 | -| main.rs:348:17:348:26 | get_fst(...) | | main.rs:155:5:156:14 | S1 | -| main.rs:348:25:348:25 | b | | main.rs:149:5:153:5 | MyPair | -| main.rs:348:25:348:25 | b | P1 | main.rs:157:5:158:14 | S2 | -| main.rs:348:25:348:25 | b | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:349:18:349:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:349:26:349:26 | x | | main.rs:155:5:156:14 | S1 | -| main.rs:350:13:350:13 | y | | main.rs:157:5:158:14 | S2 | -| main.rs:350:17:350:26 | get_snd(...) | | main.rs:157:5:158:14 | S2 | -| main.rs:350:25:350:25 | b | | main.rs:149:5:153:5 | MyPair | -| main.rs:350:25:350:25 | b | P1 | main.rs:157:5:158:14 | S2 | -| main.rs:350:25:350:25 | b | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:351:18:351:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:351:26:351:26 | y | | main.rs:157:5:158:14 | S2 | -| main.rs:353:13:353:13 | c | | main.rs:149:5:153:5 | MyPair | -| main.rs:353:13:353:13 | c | P1 | main.rs:159:5:160:14 | S3 | -| main.rs:353:13:353:13 | c | P2 | main.rs:149:5:153:5 | MyPair | -| main.rs:353:13:353:13 | c | P2.P1 | main.rs:157:5:158:14 | S2 | -| main.rs:353:13:353:13 | c | P2.P2 | main.rs:155:5:156:14 | S1 | -| main.rs:353:17:356:9 | MyPair {...} | | main.rs:149:5:153:5 | MyPair | -| main.rs:353:17:356:9 | MyPair {...} | P1 | main.rs:159:5:160:14 | S3 | -| main.rs:353:17:356:9 | MyPair {...} | P2 | main.rs:149:5:153:5 | MyPair | -| main.rs:353:17:356:9 | MyPair {...} | P2.P1 | main.rs:157:5:158:14 | S2 | -| main.rs:353:17:356:9 | MyPair {...} | P2.P2 | main.rs:155:5:156:14 | S1 | -| main.rs:354:17:354:18 | S3 | | main.rs:159:5:160:14 | S3 | -| main.rs:355:17:355:41 | MyPair {...} | | main.rs:149:5:153:5 | MyPair | -| main.rs:355:17:355:41 | MyPair {...} | P1 | main.rs:157:5:158:14 | S2 | -| main.rs:355:17:355:41 | MyPair {...} | P2 | main.rs:155:5:156:14 | S1 | -| main.rs:355:30:355:31 | S2 | | main.rs:157:5:158:14 | S2 | -| main.rs:355:38:355:39 | S1 | | main.rs:155:5:156:14 | S1 | -| main.rs:357:13:357:13 | x | | main.rs:155:5:156:14 | S1 | -| main.rs:357:17:357:30 | get_snd_fst(...) | | main.rs:155:5:156:14 | S1 | -| main.rs:357:29:357:29 | c | | main.rs:149:5:153:5 | MyPair | -| main.rs:357:29:357:29 | c | P1 | main.rs:159:5:160:14 | S3 | -| main.rs:357:29:357:29 | c | P2 | main.rs:149:5:153:5 | MyPair | -| main.rs:357:29:357:29 | c | P2.P1 | main.rs:157:5:158:14 | S2 | -| main.rs:357:29:357:29 | c | P2.P2 | main.rs:155:5:156:14 | S1 | -| main.rs:359:13:359:17 | thing | | main.rs:144:5:147:5 | MyThing | -| main.rs:359:13:359:17 | thing | A | main.rs:155:5:156:14 | S1 | -| main.rs:359:21:359:37 | MyThing {...} | | main.rs:144:5:147:5 | MyThing | -| main.rs:359:21:359:37 | MyThing {...} | A | main.rs:155:5:156:14 | S1 | -| main.rs:359:34:359:35 | S1 | | main.rs:155:5:156:14 | S1 | -| main.rs:360:17:360:21 | thing | | main.rs:144:5:147:5 | MyThing | -| main.rs:360:17:360:21 | thing | A | main.rs:155:5:156:14 | S1 | -| main.rs:361:13:361:13 | j | | main.rs:155:5:156:14 | S1 | -| main.rs:361:17:361:33 | convert_to(...) | | main.rs:155:5:156:14 | S1 | -| main.rs:361:28:361:32 | thing | | main.rs:144:5:147:5 | MyThing | -| main.rs:361:28:361:32 | thing | A | main.rs:155:5:156:14 | S1 | -| main.rs:370:26:370:29 | SelfParam | | main.rs:369:5:373:5 | Self [trait OverlappingTrait] | -| main.rs:372:28:372:31 | SelfParam | | main.rs:369:5:373:5 | Self [trait OverlappingTrait] | -| main.rs:372:34:372:35 | s1 | | main.rs:366:5:367:14 | S1 | -| main.rs:377:26:377:29 | SelfParam | | main.rs:366:5:367:14 | S1 | -| main.rs:377:38:379:9 | { ... } | | main.rs:366:5:367:14 | S1 | -| main.rs:378:20:378:31 | "not called" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:382:28:382:31 | SelfParam | | main.rs:366:5:367:14 | S1 | -| main.rs:382:34:382:35 | s1 | | main.rs:366:5:367:14 | S1 | -| main.rs:382:48:384:9 | { ... } | | main.rs:366:5:367:14 | S1 | -| main.rs:383:20:383:31 | "not called" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:389:26:389:29 | SelfParam | | main.rs:366:5:367:14 | S1 | -| main.rs:389:38:391:9 | { ... } | | main.rs:366:5:367:14 | S1 | -| main.rs:390:13:390:16 | self | | main.rs:366:5:367:14 | S1 | -| main.rs:394:28:394:31 | SelfParam | | main.rs:366:5:367:14 | S1 | -| main.rs:394:40:396:9 | { ... } | | main.rs:366:5:367:14 | S1 | -| main.rs:395:13:395:16 | self | | main.rs:366:5:367:14 | S1 | -| main.rs:400:13:400:13 | x | | main.rs:366:5:367:14 | S1 | -| main.rs:400:17:400:18 | S1 | | main.rs:366:5:367:14 | S1 | -| main.rs:401:18:401:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:401:26:401:26 | x | | main.rs:366:5:367:14 | S1 | -| main.rs:401:26:401:42 | x.common_method() | | main.rs:366:5:367:14 | S1 | -| main.rs:402:18:402:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:402:26:402:26 | x | | main.rs:366:5:367:14 | S1 | -| main.rs:402:26:402:44 | x.common_method_2() | | main.rs:366:5:367:14 | S1 | -| main.rs:419:19:419:22 | SelfParam | | main.rs:417:5:420:5 | Self [trait FirstTrait] | -| main.rs:424:19:424:22 | SelfParam | | main.rs:422:5:425:5 | Self [trait SecondTrait] | -| main.rs:427:64:427:64 | x | | main.rs:427:45:427:61 | T | -| main.rs:429:13:429:14 | s1 | | main.rs:427:35:427:42 | I | -| main.rs:429:18:429:18 | x | | main.rs:427:45:427:61 | T | -| main.rs:429:18:429:27 | x.method() | | main.rs:427:35:427:42 | I | -| main.rs:430:18:430:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:430:26:430:27 | s1 | | main.rs:427:35:427:42 | I | -| main.rs:433:65:433:65 | x | | main.rs:433:46:433:62 | T | -| main.rs:435:13:435:14 | s2 | | main.rs:433:36:433:43 | I | -| main.rs:435:18:435:18 | x | | main.rs:433:46:433:62 | T | -| main.rs:435:18:435:27 | x.method() | | main.rs:433:36:433:43 | I | -| main.rs:436:18:436:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:436:26:436:27 | s2 | | main.rs:433:36:433:43 | I | -| main.rs:439:49:439:49 | x | | main.rs:439:30:439:46 | T | -| main.rs:440:13:440:13 | s | | main.rs:409:5:410:14 | S1 | -| main.rs:440:17:440:17 | x | | main.rs:439:30:439:46 | T | -| main.rs:440:17:440:26 | x.method() | | main.rs:409:5:410:14 | S1 | -| main.rs:441:18:441:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:441:26:441:26 | s | | main.rs:409:5:410:14 | S1 | -| main.rs:444:53:444:53 | x | | main.rs:444:34:444:50 | T | -| main.rs:445:13:445:13 | s | | main.rs:409:5:410:14 | S1 | -| main.rs:445:17:445:17 | x | | main.rs:444:34:444:50 | T | -| main.rs:445:17:445:26 | x.method() | | main.rs:409:5:410:14 | S1 | -| main.rs:446:18:446:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:446:26:446:26 | s | | main.rs:409:5:410:14 | S1 | -| main.rs:450:16:450:19 | SelfParam | | main.rs:449:5:453:5 | Self [trait Pair] | -| main.rs:452:16:452:19 | SelfParam | | main.rs:449:5:453:5 | Self [trait Pair] | -| main.rs:455:58:455:58 | x | | main.rs:455:41:455:55 | T | -| main.rs:455:64:455:64 | y | | main.rs:455:41:455:55 | T | -| main.rs:457:13:457:14 | s1 | | main.rs:409:5:410:14 | S1 | -| main.rs:457:18:457:18 | x | | main.rs:455:41:455:55 | T | -| main.rs:457:18:457:24 | x.fst() | | main.rs:409:5:410:14 | S1 | -| main.rs:458:13:458:14 | s2 | | main.rs:412:5:413:14 | S2 | -| main.rs:458:18:458:18 | y | | main.rs:455:41:455:55 | T | -| main.rs:458:18:458:24 | y.snd() | | main.rs:412:5:413:14 | S2 | -| main.rs:459:18:459:29 | "{:?}, {:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:459:32:459:33 | s1 | | main.rs:409:5:410:14 | S1 | -| main.rs:459:36:459:37 | s2 | | main.rs:412:5:413:14 | S2 | -| main.rs:462:69:462:69 | x | | main.rs:462:52:462:66 | T | -| main.rs:462:75:462:75 | y | | main.rs:462:52:462:66 | T | -| main.rs:464:13:464:14 | s1 | | main.rs:409:5:410:14 | S1 | -| main.rs:464:18:464:18 | x | | main.rs:462:52:462:66 | T | -| main.rs:464:18:464:24 | x.fst() | | main.rs:409:5:410:14 | S1 | -| main.rs:465:13:465:14 | s2 | | main.rs:462:41:462:49 | T2 | -| main.rs:465:18:465:18 | y | | main.rs:462:52:462:66 | T | -| main.rs:465:18:465:24 | y.snd() | | main.rs:462:41:462:49 | T2 | -| main.rs:466:18:466:29 | "{:?}, {:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:466:32:466:33 | s1 | | main.rs:409:5:410:14 | S1 | -| main.rs:466:36:466:37 | s2 | | main.rs:462:41:462:49 | T2 | -| main.rs:482:15:482:18 | SelfParam | | main.rs:481:5:490:5 | Self [trait MyTrait] | -| main.rs:484:15:484:18 | SelfParam | | main.rs:481:5:490:5 | Self [trait MyTrait] | -| main.rs:487:9:489:9 | { ... } | | main.rs:481:19:481:19 | A | -| main.rs:488:13:488:16 | self | | main.rs:481:5:490:5 | Self [trait MyTrait] | -| main.rs:488:13:488:21 | self.m1() | | main.rs:481:19:481:19 | A | -| main.rs:493:43:493:43 | x | | main.rs:493:26:493:40 | T2 | -| main.rs:493:56:495:5 | { ... } | | main.rs:493:22:493:23 | T1 | -| main.rs:494:9:494:9 | x | | main.rs:493:26:493:40 | T2 | -| main.rs:494:9:494:14 | x.m1() | | main.rs:493:22:493:23 | T1 | -| main.rs:498:49:498:49 | x | | main.rs:471:5:474:5 | MyThing | -| main.rs:498:49:498:49 | x | T | main.rs:498:32:498:46 | T2 | -| main.rs:498:71:500:5 | { ... } | | main.rs:498:28:498:29 | T1 | -| main.rs:499:9:499:9 | x | | main.rs:471:5:474:5 | MyThing | -| main.rs:499:9:499:9 | x | T | main.rs:498:32:498:46 | T2 | -| main.rs:499:9:499:11 | x.a | | main.rs:498:32:498:46 | T2 | -| main.rs:499:9:499:16 | ... .m1() | | main.rs:498:28:498:29 | T1 | -| main.rs:503:15:503:18 | SelfParam | | main.rs:471:5:474:5 | MyThing | -| main.rs:503:15:503:18 | SelfParam | T | main.rs:502:10:502:10 | T | -| main.rs:503:26:505:9 | { ... } | | main.rs:502:10:502:10 | T | -| main.rs:504:13:504:16 | self | | main.rs:471:5:474:5 | MyThing | -| main.rs:504:13:504:16 | self | T | main.rs:502:10:502:10 | T | -| main.rs:504:13:504:18 | self.a | | main.rs:502:10:502:10 | T | -| main.rs:509:13:509:13 | x | | main.rs:471:5:474:5 | MyThing | -| main.rs:509:13:509:13 | x | T | main.rs:476:5:477:14 | S1 | -| main.rs:509:17:509:33 | MyThing {...} | | main.rs:471:5:474:5 | MyThing | -| main.rs:509:17:509:33 | MyThing {...} | T | main.rs:476:5:477:14 | S1 | -| main.rs:509:30:509:31 | S1 | | main.rs:476:5:477:14 | S1 | -| main.rs:510:13:510:13 | y | | main.rs:471:5:474:5 | MyThing | -| main.rs:510:13:510:13 | y | T | main.rs:478:5:479:14 | S2 | -| main.rs:510:17:510:33 | MyThing {...} | | main.rs:471:5:474:5 | MyThing | -| main.rs:510:17:510:33 | MyThing {...} | T | main.rs:478:5:479:14 | S2 | -| main.rs:510:30:510:31 | S2 | | main.rs:478:5:479:14 | S2 | -| main.rs:512:18:512:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:512:26:512:26 | x | | main.rs:471:5:474:5 | MyThing | -| main.rs:512:26:512:26 | x | T | main.rs:476:5:477:14 | S1 | -| main.rs:512:26:512:31 | x.m1() | | main.rs:476:5:477:14 | S1 | -| main.rs:513:18:513:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:513:26:513:26 | y | | main.rs:471:5:474:5 | MyThing | -| main.rs:513:26:513:26 | y | T | main.rs:478:5:479:14 | S2 | -| main.rs:513:26:513:31 | y.m1() | | main.rs:478:5:479:14 | S2 | -| main.rs:515:13:515:13 | x | | main.rs:471:5:474:5 | MyThing | -| main.rs:515:13:515:13 | x | T | main.rs:476:5:477:14 | S1 | -| main.rs:515:17:515:33 | MyThing {...} | | main.rs:471:5:474:5 | MyThing | -| main.rs:515:17:515:33 | MyThing {...} | T | main.rs:476:5:477:14 | S1 | -| main.rs:515:30:515:31 | S1 | | main.rs:476:5:477:14 | S1 | -| main.rs:516:13:516:13 | y | | main.rs:471:5:474:5 | MyThing | -| main.rs:516:13:516:13 | y | T | main.rs:478:5:479:14 | S2 | -| main.rs:516:17:516:33 | MyThing {...} | | main.rs:471:5:474:5 | MyThing | -| main.rs:516:17:516:33 | MyThing {...} | T | main.rs:478:5:479:14 | S2 | -| main.rs:516:30:516:31 | S2 | | main.rs:478:5:479:14 | S2 | -| main.rs:518:18:518:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:518:26:518:26 | x | | main.rs:471:5:474:5 | MyThing | -| main.rs:518:26:518:26 | x | T | main.rs:476:5:477:14 | S1 | -| main.rs:518:26:518:31 | x.m2() | | main.rs:476:5:477:14 | S1 | -| main.rs:519:18:519:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:519:26:519:26 | y | | main.rs:471:5:474:5 | MyThing | -| main.rs:519:26:519:26 | y | T | main.rs:478:5:479:14 | S2 | -| main.rs:519:26:519:31 | y.m2() | | main.rs:478:5:479:14 | S2 | -| main.rs:521:13:521:14 | x2 | | main.rs:471:5:474:5 | MyThing | -| main.rs:521:13:521:14 | x2 | T | main.rs:476:5:477:14 | S1 | -| main.rs:521:18:521:34 | MyThing {...} | | main.rs:471:5:474:5 | MyThing | -| main.rs:521:18:521:34 | MyThing {...} | T | main.rs:476:5:477:14 | S1 | -| main.rs:521:31:521:32 | S1 | | main.rs:476:5:477:14 | S1 | -| main.rs:522:13:522:14 | y2 | | main.rs:471:5:474:5 | MyThing | -| main.rs:522:13:522:14 | y2 | T | main.rs:478:5:479:14 | S2 | -| main.rs:522:18:522:34 | MyThing {...} | | main.rs:471:5:474:5 | MyThing | -| main.rs:522:18:522:34 | MyThing {...} | T | main.rs:478:5:479:14 | S2 | -| main.rs:522:31:522:32 | S2 | | main.rs:478:5:479:14 | S2 | -| main.rs:524:18:524:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:524:26:524:42 | call_trait_m1(...) | | main.rs:476:5:477:14 | S1 | -| main.rs:524:40:524:41 | x2 | | main.rs:471:5:474:5 | MyThing | -| main.rs:524:40:524:41 | x2 | T | main.rs:476:5:477:14 | S1 | -| main.rs:525:18:525:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:525:26:525:42 | call_trait_m1(...) | | main.rs:478:5:479:14 | S2 | -| main.rs:525:40:525:41 | y2 | | main.rs:471:5:474:5 | MyThing | -| main.rs:525:40:525:41 | y2 | T | main.rs:478:5:479:14 | S2 | -| main.rs:527:13:527:14 | x3 | | main.rs:471:5:474:5 | MyThing | -| main.rs:527:13:527:14 | x3 | T | main.rs:471:5:474:5 | MyThing | -| main.rs:527:13:527:14 | x3 | T.T | main.rs:476:5:477:14 | S1 | -| main.rs:527:18:529:9 | MyThing {...} | | main.rs:471:5:474:5 | MyThing | -| main.rs:527:18:529:9 | MyThing {...} | T | main.rs:471:5:474:5 | MyThing | -| main.rs:527:18:529:9 | MyThing {...} | T.T | main.rs:476:5:477:14 | S1 | -| main.rs:528:16:528:32 | MyThing {...} | | main.rs:471:5:474:5 | MyThing | -| main.rs:528:16:528:32 | MyThing {...} | T | main.rs:476:5:477:14 | S1 | -| main.rs:528:29:528:30 | S1 | | main.rs:476:5:477:14 | S1 | -| main.rs:530:13:530:14 | y3 | | main.rs:471:5:474:5 | MyThing | -| main.rs:530:13:530:14 | y3 | T | main.rs:471:5:474:5 | MyThing | -| main.rs:530:13:530:14 | y3 | T.T | main.rs:478:5:479:14 | S2 | -| main.rs:530:18:532:9 | MyThing {...} | | main.rs:471:5:474:5 | MyThing | -| main.rs:530:18:532:9 | MyThing {...} | T | main.rs:471:5:474:5 | MyThing | -| main.rs:530:18:532:9 | MyThing {...} | T.T | main.rs:478:5:479:14 | S2 | -| main.rs:531:16:531:32 | MyThing {...} | | main.rs:471:5:474:5 | MyThing | -| main.rs:531:16:531:32 | MyThing {...} | T | main.rs:478:5:479:14 | S2 | -| main.rs:531:29:531:30 | S2 | | main.rs:478:5:479:14 | S2 | -| main.rs:534:13:534:13 | a | | main.rs:476:5:477:14 | S1 | -| main.rs:534:17:534:39 | call_trait_thing_m1(...) | | main.rs:476:5:477:14 | S1 | -| main.rs:534:37:534:38 | x3 | | main.rs:471:5:474:5 | MyThing | -| main.rs:534:37:534:38 | x3 | T | main.rs:471:5:474:5 | MyThing | -| main.rs:534:37:534:38 | x3 | T.T | main.rs:476:5:477:14 | S1 | -| main.rs:535:18:535:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:535:26:535:26 | a | | main.rs:476:5:477:14 | S1 | -| main.rs:536:13:536:13 | b | | main.rs:478:5:479:14 | S2 | -| main.rs:536:17:536:39 | call_trait_thing_m1(...) | | main.rs:478:5:479:14 | S2 | -| main.rs:536:37:536:38 | y3 | | main.rs:471:5:474:5 | MyThing | -| main.rs:536:37:536:38 | y3 | T | main.rs:471:5:474:5 | MyThing | -| main.rs:536:37:536:38 | y3 | T.T | main.rs:478:5:479:14 | S2 | -| main.rs:537:18:537:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:537:26:537:26 | b | | main.rs:478:5:479:14 | S2 | -| main.rs:548:19:548:22 | SelfParam | | main.rs:542:5:545:5 | Wrapper | -| main.rs:548:19:548:22 | SelfParam | A | main.rs:547:10:547:10 | A | -| main.rs:548:30:550:9 | { ... } | | main.rs:547:10:547:10 | A | -| main.rs:549:13:549:16 | self | | main.rs:542:5:545:5 | Wrapper | -| main.rs:549:13:549:16 | self | A | main.rs:547:10:547:10 | A | -| main.rs:549:13:549:22 | self.field | | main.rs:547:10:547:10 | A | -| main.rs:557:15:557:18 | SelfParam | | main.rs:553:5:567:5 | Self [trait MyTrait] | -| main.rs:559:15:559:18 | SelfParam | | main.rs:553:5:567:5 | Self [trait MyTrait] | -| main.rs:563:9:566:9 | { ... } | | main.rs:554:9:554:28 | AssociatedType | -| main.rs:564:13:564:16 | self | | main.rs:553:5:567:5 | Self [trait MyTrait] | -| main.rs:564:13:564:21 | self.m1() | | main.rs:554:9:554:28 | AssociatedType | -| main.rs:565:13:565:43 | ...::default(...) | | main.rs:554:9:554:28 | AssociatedType | -| main.rs:573:19:573:23 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:573:19:573:23 | SelfParam | &T | main.rs:569:5:579:5 | Self [trait MyTraitAssoc2] | -| main.rs:573:26:573:26 | a | | main.rs:573:16:573:16 | A | -| main.rs:575:22:575:26 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:575:22:575:26 | SelfParam | &T | main.rs:569:5:579:5 | Self [trait MyTraitAssoc2] | -| main.rs:575:29:575:29 | a | | main.rs:575:19:575:19 | A | -| main.rs:575:35:575:35 | b | | main.rs:575:19:575:19 | A | -| main.rs:575:75:578:9 | { ... } | | main.rs:570:9:570:52 | GenericAssociatedType | -| main.rs:576:13:576:16 | self | | file://:0:0:0:0 | & | -| main.rs:576:13:576:16 | self | &T | main.rs:569:5:579:5 | Self [trait MyTraitAssoc2] | -| main.rs:576:13:576:23 | self.put(...) | | main.rs:570:9:570:52 | GenericAssociatedType | -| main.rs:576:22:576:22 | a | | main.rs:575:19:575:19 | A | -| main.rs:577:13:577:16 | self | | file://:0:0:0:0 | & | -| main.rs:577:13:577:16 | self | &T | main.rs:569:5:579:5 | Self [trait MyTraitAssoc2] | -| main.rs:577:13:577:23 | self.put(...) | | main.rs:570:9:570:52 | GenericAssociatedType | -| main.rs:577:22:577:22 | b | | main.rs:575:19:575:19 | A | -| main.rs:586:21:586:25 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:586:21:586:25 | SelfParam | &T | main.rs:581:5:591:5 | Self [trait TraitMultipleAssoc] | -| main.rs:588:20:588:24 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:588:20:588:24 | SelfParam | &T | main.rs:581:5:591:5 | Self [trait TraitMultipleAssoc] | -| main.rs:590:20:590:24 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:590:20:590:24 | SelfParam | &T | main.rs:581:5:591:5 | Self [trait TraitMultipleAssoc] | -| main.rs:606:15:606:18 | SelfParam | | main.rs:593:5:594:13 | S | -| main.rs:606:45:608:9 | { ... } | | main.rs:599:5:600:14 | AT | -| main.rs:607:13:607:14 | AT | | main.rs:599:5:600:14 | AT | -| main.rs:616:19:616:23 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:616:19:616:23 | SelfParam | &T | main.rs:593:5:594:13 | S | -| main.rs:616:26:616:26 | a | | main.rs:616:16:616:16 | A | -| main.rs:616:46:618:9 | { ... } | | main.rs:542:5:545:5 | Wrapper | -| main.rs:616:46:618:9 | { ... } | A | main.rs:616:16:616:16 | A | -| main.rs:617:13:617:32 | Wrapper {...} | | main.rs:542:5:545:5 | Wrapper | -| main.rs:617:13:617:32 | Wrapper {...} | A | main.rs:616:16:616:16 | A | -| main.rs:617:30:617:30 | a | | main.rs:616:16:616:16 | A | -| main.rs:625:15:625:18 | SelfParam | | main.rs:596:5:597:14 | S2 | -| main.rs:625:45:627:9 | { ... } | | main.rs:542:5:545:5 | Wrapper | -| main.rs:625:45:627:9 | { ... } | A | main.rs:596:5:597:14 | S2 | -| main.rs:626:13:626:35 | Wrapper {...} | | main.rs:542:5:545:5 | Wrapper | -| main.rs:626:13:626:35 | Wrapper {...} | A | main.rs:596:5:597:14 | S2 | -| main.rs:626:30:626:33 | self | | main.rs:596:5:597:14 | S2 | -| main.rs:632:30:634:9 | { ... } | | main.rs:542:5:545:5 | Wrapper | -| main.rs:632:30:634:9 | { ... } | A | main.rs:596:5:597:14 | S2 | -| main.rs:633:13:633:33 | Wrapper {...} | | main.rs:542:5:545:5 | Wrapper | -| main.rs:633:13:633:33 | Wrapper {...} | A | main.rs:596:5:597:14 | S2 | -| main.rs:633:30:633:31 | S2 | | main.rs:596:5:597:14 | S2 | -| main.rs:638:22:638:26 | thing | | main.rs:638:10:638:19 | T | -| main.rs:639:9:639:13 | thing | | main.rs:638:10:638:19 | T | -| main.rs:646:21:646:25 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:646:21:646:25 | SelfParam | &T | main.rs:599:5:600:14 | AT | -| main.rs:646:34:648:9 | { ... } | | main.rs:599:5:600:14 | AT | -| main.rs:647:13:647:14 | AT | | main.rs:599:5:600:14 | AT | -| main.rs:650:20:650:24 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:650:20:650:24 | SelfParam | &T | main.rs:599:5:600:14 | AT | -| main.rs:650:43:652:9 | { ... } | | main.rs:593:5:594:13 | S | -| main.rs:651:13:651:13 | S | | main.rs:593:5:594:13 | S | -| main.rs:654:20:654:24 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:654:20:654:24 | SelfParam | &T | main.rs:599:5:600:14 | AT | -| main.rs:654:43:656:9 | { ... } | | main.rs:596:5:597:14 | S2 | -| main.rs:655:13:655:14 | S2 | | main.rs:596:5:597:14 | S2 | -| main.rs:660:13:660:14 | x1 | | main.rs:593:5:594:13 | S | -| main.rs:660:18:660:18 | S | | main.rs:593:5:594:13 | S | -| main.rs:662:18:662:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:662:26:662:27 | x1 | | main.rs:593:5:594:13 | S | -| main.rs:662:26:662:32 | x1.m1() | | main.rs:599:5:600:14 | AT | -| main.rs:664:13:664:14 | x2 | | main.rs:593:5:594:13 | S | -| main.rs:664:18:664:18 | S | | main.rs:593:5:594:13 | S | -| main.rs:666:13:666:13 | y | | main.rs:599:5:600:14 | AT | -| main.rs:666:17:666:18 | x2 | | main.rs:593:5:594:13 | S | -| main.rs:666:17:666:23 | x2.m2() | | main.rs:599:5:600:14 | AT | -| main.rs:667:18:667:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:667:26:667:26 | y | | main.rs:599:5:600:14 | AT | -| main.rs:669:13:669:14 | x3 | | main.rs:593:5:594:13 | S | -| main.rs:669:18:669:18 | S | | main.rs:593:5:594:13 | S | -| main.rs:671:18:671:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:671:26:671:27 | x3 | | main.rs:593:5:594:13 | S | -| main.rs:671:26:671:34 | x3.put(...) | | main.rs:542:5:545:5 | Wrapper | -| main.rs:671:26:671:34 | x3.put(...) | A | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:671:26:671:43 | ... .unwrap() | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:671:33:671:33 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:674:18:674:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:674:26:674:27 | x3 | | main.rs:593:5:594:13 | S | -| main.rs:674:36:674:36 | 2 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:674:39:674:39 | 3 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:676:20:676:20 | S | | main.rs:593:5:594:13 | S | -| main.rs:677:18:677:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:679:13:679:14 | x5 | | main.rs:596:5:597:14 | S2 | -| main.rs:679:18:679:19 | S2 | | main.rs:596:5:597:14 | S2 | -| main.rs:680:18:680:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:680:26:680:27 | x5 | | main.rs:596:5:597:14 | S2 | -| main.rs:680:26:680:32 | x5.m1() | | main.rs:542:5:545:5 | Wrapper | -| main.rs:680:26:680:32 | x5.m1() | A | main.rs:596:5:597:14 | S2 | -| main.rs:681:13:681:14 | x6 | | main.rs:596:5:597:14 | S2 | -| main.rs:681:18:681:19 | S2 | | main.rs:596:5:597:14 | S2 | -| main.rs:682:18:682:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:682:26:682:27 | x6 | | main.rs:596:5:597:14 | S2 | -| main.rs:682:26:682:32 | x6.m2() | | main.rs:542:5:545:5 | Wrapper | -| main.rs:682:26:682:32 | x6.m2() | A | main.rs:596:5:597:14 | S2 | -| main.rs:684:13:684:22 | assoc_zero | | main.rs:599:5:600:14 | AT | -| main.rs:684:26:684:27 | AT | | main.rs:599:5:600:14 | AT | -| main.rs:684:26:684:38 | AT.get_zero() | | main.rs:599:5:600:14 | AT | -| main.rs:685:13:685:21 | assoc_one | | main.rs:593:5:594:13 | S | -| main.rs:685:25:685:26 | AT | | main.rs:599:5:600:14 | AT | -| main.rs:685:25:685:36 | AT.get_one() | | main.rs:593:5:594:13 | S | -| main.rs:686:13:686:21 | assoc_two | | main.rs:596:5:597:14 | S2 | -| main.rs:686:25:686:26 | AT | | main.rs:599:5:600:14 | AT | -| main.rs:686:25:686:36 | AT.get_two() | | main.rs:596:5:597:14 | S2 | -| main.rs:703:15:703:18 | SelfParam | | main.rs:691:5:695:5 | MyEnum | -| main.rs:703:15:703:18 | SelfParam | A | main.rs:702:10:702:10 | T | -| main.rs:703:26:708:9 | { ... } | | main.rs:702:10:702:10 | T | -| main.rs:704:13:707:13 | match self { ... } | | main.rs:702:10:702:10 | T | -| main.rs:704:19:704:22 | self | | main.rs:691:5:695:5 | MyEnum | -| main.rs:704:19:704:22 | self | A | main.rs:702:10:702:10 | T | -| main.rs:705:28:705:28 | a | | main.rs:702:10:702:10 | T | -| main.rs:705:34:705:34 | a | | main.rs:702:10:702:10 | T | -| main.rs:706:30:706:30 | a | | main.rs:702:10:702:10 | T | -| main.rs:706:37:706:37 | a | | main.rs:702:10:702:10 | T | -| main.rs:712:13:712:13 | x | | main.rs:691:5:695:5 | MyEnum | -| main.rs:712:13:712:13 | x | A | main.rs:697:5:698:14 | S1 | -| main.rs:712:17:712:30 | ...::C1(...) | | main.rs:691:5:695:5 | MyEnum | -| main.rs:712:17:712:30 | ...::C1(...) | A | main.rs:697:5:698:14 | S1 | -| main.rs:712:28:712:29 | S1 | | main.rs:697:5:698:14 | S1 | -| main.rs:713:13:713:13 | y | | main.rs:691:5:695:5 | MyEnum | -| main.rs:713:13:713:13 | y | A | main.rs:699:5:700:14 | S2 | -| main.rs:713:17:713:36 | ...::C2 {...} | | main.rs:691:5:695:5 | MyEnum | -| main.rs:713:17:713:36 | ...::C2 {...} | A | main.rs:699:5:700:14 | S2 | -| main.rs:713:33:713:34 | S2 | | main.rs:699:5:700:14 | S2 | -| main.rs:715:18:715:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:715:26:715:26 | x | | main.rs:691:5:695:5 | MyEnum | -| main.rs:715:26:715:26 | x | A | main.rs:697:5:698:14 | S1 | -| main.rs:715:26:715:31 | x.m1() | | main.rs:697:5:698:14 | S1 | -| main.rs:716:18:716:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:716:26:716:26 | y | | main.rs:691:5:695:5 | MyEnum | -| main.rs:716:26:716:26 | y | A | main.rs:699:5:700:14 | S2 | -| main.rs:716:26:716:31 | y.m1() | | main.rs:699:5:700:14 | S2 | -| main.rs:738:15:738:18 | SelfParam | | main.rs:736:5:739:5 | Self [trait MyTrait1] | -| main.rs:742:15:742:18 | SelfParam | | main.rs:741:5:752:5 | Self [trait MyTrait2] | -| main.rs:745:9:751:9 | { ... } | | main.rs:741:20:741:22 | Tr2 | -| main.rs:746:13:750:13 | if ... {...} else {...} | | main.rs:741:20:741:22 | Tr2 | -| main.rs:746:16:746:16 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:746:20:746:20 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:746:24:746:24 | 2 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:746:26:748:13 | { ... } | | main.rs:741:20:741:22 | Tr2 | -| main.rs:747:17:747:20 | self | | main.rs:741:5:752:5 | Self [trait MyTrait2] | -| main.rs:747:17:747:25 | self.m1() | | main.rs:741:20:741:22 | Tr2 | -| main.rs:748:20:750:13 | { ... } | | main.rs:741:20:741:22 | Tr2 | -| main.rs:749:17:749:30 | ...::m1(...) | | main.rs:741:20:741:22 | Tr2 | -| main.rs:749:26:749:29 | self | | main.rs:741:5:752:5 | Self [trait MyTrait2] | -| main.rs:755:15:755:18 | SelfParam | | main.rs:754:5:765:5 | Self [trait MyTrait3] | -| main.rs:758:9:764:9 | { ... } | | main.rs:754:20:754:22 | Tr3 | -| main.rs:759:13:763:13 | if ... {...} else {...} | | main.rs:754:20:754:22 | Tr3 | -| main.rs:759:16:759:16 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:759:20:759:20 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:759:24:759:24 | 2 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:759:26:761:13 | { ... } | | main.rs:754:20:754:22 | Tr3 | -| main.rs:760:17:760:20 | self | | main.rs:754:5:765:5 | Self [trait MyTrait3] | -| main.rs:760:17:760:25 | self.m2() | | main.rs:721:5:724:5 | MyThing | -| main.rs:760:17:760:25 | self.m2() | A | main.rs:754:20:754:22 | Tr3 | -| main.rs:760:17:760:27 | ... .a | | main.rs:754:20:754:22 | Tr3 | -| main.rs:761:20:763:13 | { ... } | | main.rs:754:20:754:22 | Tr3 | -| main.rs:762:17:762:30 | ...::m2(...) | | main.rs:721:5:724:5 | MyThing | -| main.rs:762:17:762:30 | ...::m2(...) | A | main.rs:754:20:754:22 | Tr3 | -| main.rs:762:17:762:32 | ... .a | | main.rs:754:20:754:22 | Tr3 | -| main.rs:762:26:762:29 | self | | main.rs:754:5:765:5 | Self [trait MyTrait3] | -| main.rs:769:15:769:18 | SelfParam | | main.rs:721:5:724:5 | MyThing | -| main.rs:769:15:769:18 | SelfParam | A | main.rs:767:10:767:10 | T | -| main.rs:769:26:771:9 | { ... } | | main.rs:767:10:767:10 | T | -| main.rs:770:13:770:16 | self | | main.rs:721:5:724:5 | MyThing | -| main.rs:770:13:770:16 | self | A | main.rs:767:10:767:10 | T | -| main.rs:770:13:770:18 | self.a | | main.rs:767:10:767:10 | T | -| main.rs:778:15:778:18 | SelfParam | | main.rs:726:5:729:5 | MyThing2 | -| main.rs:778:15:778:18 | SelfParam | A | main.rs:776:10:776:10 | T | -| main.rs:778:35:780:9 | { ... } | | main.rs:721:5:724:5 | MyThing | -| main.rs:778:35:780:9 | { ... } | A | main.rs:776:10:776:10 | T | -| main.rs:779:13:779:33 | MyThing {...} | | main.rs:721:5:724:5 | MyThing | -| main.rs:779:13:779:33 | MyThing {...} | A | main.rs:776:10:776:10 | T | -| main.rs:779:26:779:29 | self | | main.rs:726:5:729:5 | MyThing2 | -| main.rs:779:26:779:29 | self | A | main.rs:776:10:776:10 | T | -| main.rs:779:26:779:31 | self.a | | main.rs:776:10:776:10 | T | -| main.rs:787:44:787:44 | x | | main.rs:787:26:787:41 | T2 | -| main.rs:787:57:789:5 | { ... } | | main.rs:787:22:787:23 | T1 | -| main.rs:788:9:788:9 | x | | main.rs:787:26:787:41 | T2 | -| main.rs:788:9:788:14 | x.m1() | | main.rs:787:22:787:23 | T1 | -| main.rs:791:56:791:56 | x | | main.rs:791:39:791:53 | T | -| main.rs:793:13:793:13 | a | | main.rs:721:5:724:5 | MyThing | -| main.rs:793:13:793:13 | a | A | main.rs:731:5:732:14 | S1 | -| main.rs:793:17:793:17 | x | | main.rs:791:39:791:53 | T | -| main.rs:793:17:793:22 | x.m1() | | main.rs:721:5:724:5 | MyThing | -| main.rs:793:17:793:22 | x.m1() | A | main.rs:731:5:732:14 | S1 | -| main.rs:794:18:794:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:794:26:794:26 | a | | main.rs:721:5:724:5 | MyThing | -| main.rs:794:26:794:26 | a | A | main.rs:731:5:732:14 | S1 | -| main.rs:798:13:798:13 | x | | main.rs:721:5:724:5 | MyThing | -| main.rs:798:13:798:13 | x | A | main.rs:731:5:732:14 | S1 | -| main.rs:798:17:798:33 | MyThing {...} | | main.rs:721:5:724:5 | MyThing | -| main.rs:798:17:798:33 | MyThing {...} | A | main.rs:731:5:732:14 | S1 | -| main.rs:798:30:798:31 | S1 | | main.rs:731:5:732:14 | S1 | -| main.rs:799:13:799:13 | y | | main.rs:721:5:724:5 | MyThing | -| main.rs:799:13:799:13 | y | A | main.rs:733:5:734:14 | S2 | -| main.rs:799:17:799:33 | MyThing {...} | | main.rs:721:5:724:5 | MyThing | -| main.rs:799:17:799:33 | MyThing {...} | A | main.rs:733:5:734:14 | S2 | -| main.rs:799:30:799:31 | S2 | | main.rs:733:5:734:14 | S2 | -| main.rs:801:18:801:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:801:26:801:26 | x | | main.rs:721:5:724:5 | MyThing | -| main.rs:801:26:801:26 | x | A | main.rs:731:5:732:14 | S1 | -| main.rs:801:26:801:31 | x.m1() | | main.rs:731:5:732:14 | S1 | -| main.rs:802:18:802:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:802:26:802:26 | y | | main.rs:721:5:724:5 | MyThing | -| main.rs:802:26:802:26 | y | A | main.rs:733:5:734:14 | S2 | -| main.rs:802:26:802:31 | y.m1() | | main.rs:733:5:734:14 | S2 | -| main.rs:804:13:804:13 | x | | main.rs:721:5:724:5 | MyThing | -| main.rs:804:13:804:13 | x | A | main.rs:731:5:732:14 | S1 | -| main.rs:804:17:804:33 | MyThing {...} | | main.rs:721:5:724:5 | MyThing | -| main.rs:804:17:804:33 | MyThing {...} | A | main.rs:731:5:732:14 | S1 | -| main.rs:804:30:804:31 | S1 | | main.rs:731:5:732:14 | S1 | -| main.rs:805:13:805:13 | y | | main.rs:721:5:724:5 | MyThing | -| main.rs:805:13:805:13 | y | A | main.rs:733:5:734:14 | S2 | -| main.rs:805:17:805:33 | MyThing {...} | | main.rs:721:5:724:5 | MyThing | -| main.rs:805:17:805:33 | MyThing {...} | A | main.rs:733:5:734:14 | S2 | -| main.rs:805:30:805:31 | S2 | | main.rs:733:5:734:14 | S2 | -| main.rs:807:18:807:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:807:26:807:26 | x | | main.rs:721:5:724:5 | MyThing | -| main.rs:807:26:807:26 | x | A | main.rs:731:5:732:14 | S1 | -| main.rs:807:26:807:31 | x.m2() | | main.rs:731:5:732:14 | S1 | -| main.rs:808:18:808:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:808:26:808:26 | y | | main.rs:721:5:724:5 | MyThing | -| main.rs:808:26:808:26 | y | A | main.rs:733:5:734:14 | S2 | -| main.rs:808:26:808:31 | y.m2() | | main.rs:733:5:734:14 | S2 | -| main.rs:810:13:810:13 | x | | main.rs:726:5:729:5 | MyThing2 | -| main.rs:810:13:810:13 | x | A | main.rs:731:5:732:14 | S1 | -| main.rs:810:17:810:34 | MyThing2 {...} | | main.rs:726:5:729:5 | MyThing2 | -| main.rs:810:17:810:34 | MyThing2 {...} | A | main.rs:731:5:732:14 | S1 | -| main.rs:810:31:810:32 | S1 | | main.rs:731:5:732:14 | S1 | -| main.rs:811:13:811:13 | y | | main.rs:726:5:729:5 | MyThing2 | -| main.rs:811:13:811:13 | y | A | main.rs:733:5:734:14 | S2 | -| main.rs:811:17:811:34 | MyThing2 {...} | | main.rs:726:5:729:5 | MyThing2 | -| main.rs:811:17:811:34 | MyThing2 {...} | A | main.rs:733:5:734:14 | S2 | -| main.rs:811:31:811:32 | S2 | | main.rs:733:5:734:14 | S2 | -| main.rs:813:18:813:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:813:26:813:26 | x | | main.rs:726:5:729:5 | MyThing2 | -| main.rs:813:26:813:26 | x | A | main.rs:731:5:732:14 | S1 | -| main.rs:813:26:813:31 | x.m3() | | main.rs:731:5:732:14 | S1 | -| main.rs:814:18:814:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:814:26:814:26 | y | | main.rs:726:5:729:5 | MyThing2 | -| main.rs:814:26:814:26 | y | A | main.rs:733:5:734:14 | S2 | -| main.rs:814:26:814:31 | y.m3() | | main.rs:733:5:734:14 | S2 | -| main.rs:816:13:816:13 | x | | main.rs:721:5:724:5 | MyThing | -| main.rs:816:13:816:13 | x | A | main.rs:731:5:732:14 | S1 | -| main.rs:816:17:816:33 | MyThing {...} | | main.rs:721:5:724:5 | MyThing | -| main.rs:816:17:816:33 | MyThing {...} | A | main.rs:731:5:732:14 | S1 | -| main.rs:816:30:816:31 | S1 | | main.rs:731:5:732:14 | S1 | -| main.rs:817:13:817:13 | s | | main.rs:731:5:732:14 | S1 | -| main.rs:817:17:817:32 | call_trait_m1(...) | | main.rs:731:5:732:14 | S1 | -| main.rs:817:31:817:31 | x | | main.rs:721:5:724:5 | MyThing | -| main.rs:817:31:817:31 | x | A | main.rs:731:5:732:14 | S1 | -| main.rs:819:13:819:13 | x | | main.rs:726:5:729:5 | MyThing2 | -| main.rs:819:13:819:13 | x | A | main.rs:733:5:734:14 | S2 | -| main.rs:819:17:819:34 | MyThing2 {...} | | main.rs:726:5:729:5 | MyThing2 | -| main.rs:819:17:819:34 | MyThing2 {...} | A | main.rs:733:5:734:14 | S2 | -| main.rs:819:31:819:32 | S2 | | main.rs:733:5:734:14 | S2 | -| main.rs:820:13:820:13 | s | | main.rs:721:5:724:5 | MyThing | -| main.rs:820:13:820:13 | s | A | main.rs:733:5:734:14 | S2 | -| main.rs:820:17:820:32 | call_trait_m1(...) | | main.rs:721:5:724:5 | MyThing | -| main.rs:820:17:820:32 | call_trait_m1(...) | A | main.rs:733:5:734:14 | S2 | -| main.rs:820:31:820:31 | x | | main.rs:726:5:729:5 | MyThing2 | -| main.rs:820:31:820:31 | x | A | main.rs:733:5:734:14 | S2 | -| main.rs:838:22:838:22 | x | | file://:0:0:0:0 | & | -| main.rs:838:22:838:22 | x | &T | main.rs:838:11:838:19 | T | -| main.rs:838:35:840:5 | { ... } | | file://:0:0:0:0 | & | -| main.rs:838:35:840:5 | { ... } | &T | main.rs:838:11:838:19 | T | -| main.rs:839:9:839:9 | x | | file://:0:0:0:0 | & | -| main.rs:839:9:839:9 | x | &T | main.rs:838:11:838:19 | T | -| main.rs:843:17:843:20 | SelfParam | | main.rs:828:5:829:14 | S1 | -| main.rs:843:29:845:9 | { ... } | | main.rs:831:5:832:14 | S2 | -| main.rs:844:13:844:14 | S2 | | main.rs:831:5:832:14 | S2 | -| main.rs:848:21:848:21 | x | | main.rs:848:13:848:14 | T1 | -| main.rs:851:5:853:5 | { ... } | | main.rs:848:17:848:18 | T2 | -| main.rs:852:9:852:9 | x | | main.rs:848:13:848:14 | T1 | -| main.rs:852:9:852:16 | x.into() | | main.rs:848:17:848:18 | T2 | -| main.rs:856:13:856:13 | x | | main.rs:828:5:829:14 | S1 | -| main.rs:856:17:856:18 | S1 | | main.rs:828:5:829:14 | S1 | -| main.rs:857:18:857:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:857:26:857:31 | id(...) | | file://:0:0:0:0 | & | -| main.rs:857:26:857:31 | id(...) | &T | main.rs:828:5:829:14 | S1 | -| main.rs:857:29:857:30 | &x | | file://:0:0:0:0 | & | -| main.rs:857:29:857:30 | &x | &T | main.rs:828:5:829:14 | S1 | -| main.rs:857:30:857:30 | x | | main.rs:828:5:829:14 | S1 | -| main.rs:859:13:859:13 | x | | main.rs:828:5:829:14 | S1 | -| main.rs:859:17:859:18 | S1 | | main.rs:828:5:829:14 | S1 | -| main.rs:860:18:860:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:860:26:860:37 | id::<...>(...) | | file://:0:0:0:0 | & | -| main.rs:860:26:860:37 | id::<...>(...) | &T | main.rs:828:5:829:14 | S1 | -| main.rs:860:35:860:36 | &x | | file://:0:0:0:0 | & | -| main.rs:860:35:860:36 | &x | &T | main.rs:828:5:829:14 | S1 | -| main.rs:860:36:860:36 | x | | main.rs:828:5:829:14 | S1 | -| main.rs:862:13:862:13 | x | | main.rs:828:5:829:14 | S1 | -| main.rs:862:17:862:18 | S1 | | main.rs:828:5:829:14 | S1 | -| main.rs:863:18:863:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:863:26:863:44 | id::<...>(...) | | file://:0:0:0:0 | & | -| main.rs:863:26:863:44 | id::<...>(...) | &T | main.rs:828:5:829:14 | S1 | -| main.rs:863:42:863:43 | &x | | file://:0:0:0:0 | & | -| main.rs:863:42:863:43 | &x | &T | main.rs:828:5:829:14 | S1 | -| main.rs:863:43:863:43 | x | | main.rs:828:5:829:14 | S1 | -| main.rs:865:13:865:13 | x | | main.rs:828:5:829:14 | S1 | -| main.rs:865:17:865:18 | S1 | | main.rs:828:5:829:14 | S1 | -| main.rs:866:9:866:25 | into::<...>(...) | | main.rs:831:5:832:14 | S2 | -| main.rs:866:24:866:24 | x | | main.rs:828:5:829:14 | S1 | -| main.rs:868:13:868:13 | x | | main.rs:828:5:829:14 | S1 | -| main.rs:868:17:868:18 | S1 | | main.rs:828:5:829:14 | S1 | -| main.rs:869:13:869:13 | y | | main.rs:831:5:832:14 | S2 | -| main.rs:869:21:869:27 | into(...) | | main.rs:831:5:832:14 | S2 | -| main.rs:869:26:869:26 | x | | main.rs:828:5:829:14 | S1 | -| main.rs:883:22:883:25 | SelfParam | | main.rs:874:5:880:5 | PairOption | -| main.rs:883:22:883:25 | SelfParam | Fst | main.rs:882:10:882:12 | Fst | -| main.rs:883:22:883:25 | SelfParam | Snd | main.rs:882:15:882:17 | Snd | -| main.rs:883:35:890:9 | { ... } | | main.rs:882:15:882:17 | Snd | -| main.rs:884:13:889:13 | match self { ... } | | main.rs:882:15:882:17 | Snd | -| main.rs:884:19:884:22 | self | | main.rs:874:5:880:5 | PairOption | -| main.rs:884:19:884:22 | self | Fst | main.rs:882:10:882:12 | Fst | -| main.rs:884:19:884:22 | self | Snd | main.rs:882:15:882:17 | Snd | -| main.rs:885:43:885:82 | MacroExpr | | main.rs:882:15:882:17 | Snd | -| main.rs:885:50:885:81 | "PairNone has no second elemen... | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:886:43:886:81 | MacroExpr | | main.rs:882:15:882:17 | Snd | -| main.rs:886:50:886:80 | "PairFst has no second element... | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:887:37:887:39 | snd | | main.rs:882:15:882:17 | Snd | -| main.rs:887:45:887:47 | snd | | main.rs:882:15:882:17 | Snd | -| main.rs:888:41:888:43 | snd | | main.rs:882:15:882:17 | Snd | -| main.rs:888:49:888:51 | snd | | main.rs:882:15:882:17 | Snd | -| main.rs:914:10:914:10 | t | | main.rs:874:5:880:5 | PairOption | -| main.rs:914:10:914:10 | t | Fst | main.rs:896:5:897:14 | S2 | -| main.rs:914:10:914:10 | t | Snd | main.rs:874:5:880:5 | PairOption | -| main.rs:914:10:914:10 | t | Snd.Fst | main.rs:896:5:897:14 | S2 | -| main.rs:914:10:914:10 | t | Snd.Snd | main.rs:899:5:900:14 | S3 | -| main.rs:915:13:915:13 | x | | main.rs:899:5:900:14 | S3 | -| main.rs:915:17:915:17 | t | | main.rs:874:5:880:5 | PairOption | -| main.rs:915:17:915:17 | t | Fst | main.rs:896:5:897:14 | S2 | -| main.rs:915:17:915:17 | t | Snd | main.rs:874:5:880:5 | PairOption | -| main.rs:915:17:915:17 | t | Snd.Fst | main.rs:896:5:897:14 | S2 | -| main.rs:915:17:915:17 | t | Snd.Snd | main.rs:899:5:900:14 | S3 | -| main.rs:915:17:915:29 | t.unwrapSnd() | | main.rs:874:5:880:5 | PairOption | -| main.rs:915:17:915:29 | t.unwrapSnd() | Fst | main.rs:896:5:897:14 | S2 | -| main.rs:915:17:915:29 | t.unwrapSnd() | Snd | main.rs:899:5:900:14 | S3 | -| main.rs:915:17:915:41 | ... .unwrapSnd() | | main.rs:899:5:900:14 | S3 | -| main.rs:916:18:916:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:916:26:916:26 | x | | main.rs:899:5:900:14 | S3 | -| main.rs:921:13:921:14 | p1 | | main.rs:874:5:880:5 | PairOption | -| main.rs:921:13:921:14 | p1 | Fst | main.rs:893:5:894:14 | S1 | -| main.rs:921:13:921:14 | p1 | Snd | main.rs:896:5:897:14 | S2 | -| main.rs:921:26:921:53 | ...::PairBoth(...) | | main.rs:874:5:880:5 | PairOption | -| main.rs:921:26:921:53 | ...::PairBoth(...) | Fst | main.rs:893:5:894:14 | S1 | -| main.rs:921:26:921:53 | ...::PairBoth(...) | Snd | main.rs:896:5:897:14 | S2 | -| main.rs:921:47:921:48 | S1 | | main.rs:893:5:894:14 | S1 | -| main.rs:921:51:921:52 | S2 | | main.rs:896:5:897:14 | S2 | -| main.rs:922:18:922:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:922:26:922:27 | p1 | | main.rs:874:5:880:5 | PairOption | -| main.rs:922:26:922:27 | p1 | Fst | main.rs:893:5:894:14 | S1 | -| main.rs:922:26:922:27 | p1 | Snd | main.rs:896:5:897:14 | S2 | -| main.rs:925:13:925:14 | p2 | | main.rs:874:5:880:5 | PairOption | -| main.rs:925:13:925:14 | p2 | Fst | main.rs:893:5:894:14 | S1 | -| main.rs:925:13:925:14 | p2 | Snd | main.rs:896:5:897:14 | S2 | -| main.rs:925:26:925:47 | ...::PairNone(...) | | main.rs:874:5:880:5 | PairOption | -| main.rs:925:26:925:47 | ...::PairNone(...) | Fst | main.rs:893:5:894:14 | S1 | -| main.rs:925:26:925:47 | ...::PairNone(...) | Snd | main.rs:896:5:897:14 | S2 | -| main.rs:926:18:926:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:926:26:926:27 | p2 | | main.rs:874:5:880:5 | PairOption | -| main.rs:926:26:926:27 | p2 | Fst | main.rs:893:5:894:14 | S1 | -| main.rs:926:26:926:27 | p2 | Snd | main.rs:896:5:897:14 | S2 | -| main.rs:929:13:929:14 | p3 | | main.rs:874:5:880:5 | PairOption | -| main.rs:929:13:929:14 | p3 | Fst | main.rs:896:5:897:14 | S2 | -| main.rs:929:13:929:14 | p3 | Snd | main.rs:899:5:900:14 | S3 | -| main.rs:929:34:929:56 | ...::PairSnd(...) | | main.rs:874:5:880:5 | PairOption | -| main.rs:929:34:929:56 | ...::PairSnd(...) | Fst | main.rs:896:5:897:14 | S2 | -| main.rs:929:34:929:56 | ...::PairSnd(...) | Snd | main.rs:899:5:900:14 | S3 | -| main.rs:929:54:929:55 | S3 | | main.rs:899:5:900:14 | S3 | -| main.rs:930:18:930:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:930:26:930:27 | p3 | | main.rs:874:5:880:5 | PairOption | -| main.rs:930:26:930:27 | p3 | Fst | main.rs:896:5:897:14 | S2 | -| main.rs:930:26:930:27 | p3 | Snd | main.rs:899:5:900:14 | S3 | -| main.rs:933:13:933:14 | p3 | | main.rs:874:5:880:5 | PairOption | -| main.rs:933:13:933:14 | p3 | Fst | main.rs:896:5:897:14 | S2 | -| main.rs:933:13:933:14 | p3 | Snd | main.rs:899:5:900:14 | S3 | -| main.rs:933:35:933:56 | ...::PairNone(...) | | main.rs:874:5:880:5 | PairOption | -| main.rs:933:35:933:56 | ...::PairNone(...) | Fst | main.rs:896:5:897:14 | S2 | -| main.rs:933:35:933:56 | ...::PairNone(...) | Snd | main.rs:899:5:900:14 | S3 | -| main.rs:934:18:934:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:934:26:934:27 | p3 | | main.rs:874:5:880:5 | PairOption | -| main.rs:934:26:934:27 | p3 | Fst | main.rs:896:5:897:14 | S2 | -| main.rs:934:26:934:27 | p3 | Snd | main.rs:899:5:900:14 | S3 | -| main.rs:936:11:936:54 | ...::PairSnd(...) | | main.rs:874:5:880:5 | PairOption | -| main.rs:936:11:936:54 | ...::PairSnd(...) | Fst | main.rs:896:5:897:14 | S2 | -| main.rs:936:11:936:54 | ...::PairSnd(...) | Snd | main.rs:874:5:880:5 | PairOption | -| main.rs:936:11:936:54 | ...::PairSnd(...) | Snd.Fst | main.rs:896:5:897:14 | S2 | -| main.rs:936:11:936:54 | ...::PairSnd(...) | Snd.Snd | main.rs:899:5:900:14 | S3 | -| main.rs:936:31:936:53 | ...::PairSnd(...) | | main.rs:874:5:880:5 | PairOption | -| main.rs:936:31:936:53 | ...::PairSnd(...) | Fst | main.rs:896:5:897:14 | S2 | -| main.rs:936:31:936:53 | ...::PairSnd(...) | Snd | main.rs:899:5:900:14 | S3 | -| main.rs:936:51:936:52 | S3 | | main.rs:899:5:900:14 | S3 | -| main.rs:949:16:949:24 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:949:16:949:24 | SelfParam | &T | main.rs:947:5:954:5 | Self [trait MyTrait] | -| main.rs:949:27:949:31 | value | | main.rs:947:19:947:19 | S | -| main.rs:951:21:951:29 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:951:21:951:29 | SelfParam | &T | main.rs:947:5:954:5 | Self [trait MyTrait] | -| main.rs:951:32:951:36 | value | | main.rs:947:19:947:19 | S | -| main.rs:952:13:952:16 | self | | file://:0:0:0:0 | & | -| main.rs:952:13:952:16 | self | &T | main.rs:947:5:954:5 | Self [trait MyTrait] | -| main.rs:952:22:952:26 | value | | main.rs:947:19:947:19 | S | -| main.rs:958:16:958:24 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:958:16:958:24 | SelfParam | &T | main.rs:941:5:945:5 | MyOption | -| main.rs:958:16:958:24 | SelfParam | &T.T | main.rs:956:10:956:10 | T | -| main.rs:958:27:958:31 | value | | main.rs:956:10:956:10 | T | -| main.rs:962:26:964:9 | { ... } | | main.rs:941:5:945:5 | MyOption | -| main.rs:962:26:964:9 | { ... } | T | main.rs:961:10:961:10 | T | -| main.rs:963:13:963:30 | ...::MyNone(...) | | main.rs:941:5:945:5 | MyOption | -| main.rs:963:13:963:30 | ...::MyNone(...) | T | main.rs:961:10:961:10 | T | -| main.rs:968:20:968:23 | SelfParam | | main.rs:941:5:945:5 | MyOption | -| main.rs:968:20:968:23 | SelfParam | T | main.rs:941:5:945:5 | MyOption | -| main.rs:968:20:968:23 | SelfParam | T.T | main.rs:967:10:967:10 | T | -| main.rs:968:41:973:9 | { ... } | | main.rs:941:5:945:5 | MyOption | -| main.rs:968:41:973:9 | { ... } | T | main.rs:967:10:967:10 | T | -| main.rs:969:13:972:13 | match self { ... } | | main.rs:941:5:945:5 | MyOption | -| main.rs:969:13:972:13 | match self { ... } | T | main.rs:967:10:967:10 | T | -| main.rs:969:19:969:22 | self | | main.rs:941:5:945:5 | MyOption | -| main.rs:969:19:969:22 | self | T | main.rs:941:5:945:5 | MyOption | -| main.rs:969:19:969:22 | self | T.T | main.rs:967:10:967:10 | T | -| main.rs:970:39:970:56 | ...::MyNone(...) | | main.rs:941:5:945:5 | MyOption | -| main.rs:970:39:970:56 | ...::MyNone(...) | T | main.rs:967:10:967:10 | T | -| main.rs:971:34:971:34 | x | | main.rs:941:5:945:5 | MyOption | -| main.rs:971:34:971:34 | x | T | main.rs:967:10:967:10 | T | -| main.rs:971:40:971:40 | x | | main.rs:941:5:945:5 | MyOption | -| main.rs:971:40:971:40 | x | T | main.rs:967:10:967:10 | T | -| main.rs:980:13:980:14 | x1 | | main.rs:941:5:945:5 | MyOption | -| main.rs:980:18:980:37 | ...::new(...) | | main.rs:941:5:945:5 | MyOption | -| main.rs:981:18:981:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:981:26:981:27 | x1 | | main.rs:941:5:945:5 | MyOption | -| main.rs:983:13:983:18 | mut x2 | | main.rs:941:5:945:5 | MyOption | -| main.rs:983:13:983:18 | mut x2 | T | main.rs:976:5:977:13 | S | -| main.rs:983:22:983:36 | ...::new(...) | | main.rs:941:5:945:5 | MyOption | -| main.rs:983:22:983:36 | ...::new(...) | T | main.rs:976:5:977:13 | S | -| main.rs:984:9:984:10 | x2 | | main.rs:941:5:945:5 | MyOption | -| main.rs:984:9:984:10 | x2 | T | main.rs:976:5:977:13 | S | -| main.rs:984:16:984:16 | S | | main.rs:976:5:977:13 | S | -| main.rs:985:18:985:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:985:26:985:27 | x2 | | main.rs:941:5:945:5 | MyOption | -| main.rs:985:26:985:27 | x2 | T | main.rs:976:5:977:13 | S | -| main.rs:987:13:987:18 | mut x3 | | main.rs:941:5:945:5 | MyOption | -| main.rs:987:22:987:36 | ...::new(...) | | main.rs:941:5:945:5 | MyOption | -| main.rs:988:9:988:10 | x3 | | main.rs:941:5:945:5 | MyOption | -| main.rs:988:21:988:21 | S | | main.rs:976:5:977:13 | S | -| main.rs:989:18:989:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:989:26:989:27 | x3 | | main.rs:941:5:945:5 | MyOption | -| main.rs:991:13:991:18 | mut x4 | | main.rs:941:5:945:5 | MyOption | -| main.rs:991:13:991:18 | mut x4 | T | main.rs:976:5:977:13 | S | -| main.rs:991:22:991:36 | ...::new(...) | | main.rs:941:5:945:5 | MyOption | -| main.rs:991:22:991:36 | ...::new(...) | T | main.rs:976:5:977:13 | S | -| main.rs:992:23:992:29 | &mut x4 | | file://:0:0:0:0 | & | -| main.rs:992:23:992:29 | &mut x4 | &T | main.rs:941:5:945:5 | MyOption | -| main.rs:992:23:992:29 | &mut x4 | &T.T | main.rs:976:5:977:13 | S | -| main.rs:992:28:992:29 | x4 | | main.rs:941:5:945:5 | MyOption | -| main.rs:992:28:992:29 | x4 | T | main.rs:976:5:977:13 | S | -| main.rs:992:32:992:32 | S | | main.rs:976:5:977:13 | S | -| main.rs:993:18:993:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:993:26:993:27 | x4 | | main.rs:941:5:945:5 | MyOption | -| main.rs:993:26:993:27 | x4 | T | main.rs:976:5:977:13 | S | -| main.rs:995:13:995:14 | x5 | | main.rs:941:5:945:5 | MyOption | -| main.rs:995:13:995:14 | x5 | T | main.rs:941:5:945:5 | MyOption | -| main.rs:995:13:995:14 | x5 | T.T | main.rs:976:5:977:13 | S | -| main.rs:995:18:995:58 | ...::MySome(...) | | main.rs:941:5:945:5 | MyOption | -| main.rs:995:18:995:58 | ...::MySome(...) | T | main.rs:941:5:945:5 | MyOption | -| main.rs:995:18:995:58 | ...::MySome(...) | T.T | main.rs:976:5:977:13 | S | -| main.rs:995:35:995:57 | ...::MyNone(...) | | main.rs:941:5:945:5 | MyOption | -| main.rs:995:35:995:57 | ...::MyNone(...) | T | main.rs:976:5:977:13 | S | -| main.rs:996:18:996:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:996:26:996:27 | x5 | | main.rs:941:5:945:5 | MyOption | -| main.rs:996:26:996:27 | x5 | T | main.rs:941:5:945:5 | MyOption | -| main.rs:996:26:996:27 | x5 | T.T | main.rs:976:5:977:13 | S | -| main.rs:996:26:996:37 | x5.flatten() | | main.rs:941:5:945:5 | MyOption | -| main.rs:996:26:996:37 | x5.flatten() | T | main.rs:976:5:977:13 | S | -| main.rs:998:13:998:14 | x6 | | main.rs:941:5:945:5 | MyOption | -| main.rs:998:13:998:14 | x6 | T | main.rs:941:5:945:5 | MyOption | -| main.rs:998:13:998:14 | x6 | T.T | main.rs:976:5:977:13 | S | -| main.rs:998:18:998:58 | ...::MySome(...) | | main.rs:941:5:945:5 | MyOption | -| main.rs:998:18:998:58 | ...::MySome(...) | T | main.rs:941:5:945:5 | MyOption | -| main.rs:998:18:998:58 | ...::MySome(...) | T.T | main.rs:976:5:977:13 | S | -| main.rs:998:35:998:57 | ...::MyNone(...) | | main.rs:941:5:945:5 | MyOption | -| main.rs:998:35:998:57 | ...::MyNone(...) | T | main.rs:976:5:977:13 | S | -| main.rs:999:18:999:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:999:26:999:61 | ...::flatten(...) | | main.rs:941:5:945:5 | MyOption | -| main.rs:999:26:999:61 | ...::flatten(...) | T | main.rs:976:5:977:13 | S | -| main.rs:999:59:999:60 | x6 | | main.rs:941:5:945:5 | MyOption | -| main.rs:999:59:999:60 | x6 | T | main.rs:941:5:945:5 | MyOption | -| main.rs:999:59:999:60 | x6 | T.T | main.rs:976:5:977:13 | S | -| main.rs:1001:13:1001:19 | from_if | | main.rs:941:5:945:5 | MyOption | -| main.rs:1001:13:1001:19 | from_if | T | main.rs:976:5:977:13 | S | -| main.rs:1001:23:1005:9 | if ... {...} else {...} | | main.rs:941:5:945:5 | MyOption | -| main.rs:1001:23:1005:9 | if ... {...} else {...} | T | main.rs:976:5:977:13 | S | -| main.rs:1001:26:1001:26 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1001:30:1001:30 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1001:34:1001:34 | 2 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1001:36:1003:9 | { ... } | | main.rs:941:5:945:5 | MyOption | -| main.rs:1001:36:1003:9 | { ... } | T | main.rs:976:5:977:13 | S | -| main.rs:1002:13:1002:30 | ...::MyNone(...) | | main.rs:941:5:945:5 | MyOption | -| main.rs:1002:13:1002:30 | ...::MyNone(...) | T | main.rs:976:5:977:13 | S | -| main.rs:1003:16:1005:9 | { ... } | | main.rs:941:5:945:5 | MyOption | -| main.rs:1003:16:1005:9 | { ... } | T | main.rs:976:5:977:13 | S | -| main.rs:1004:13:1004:31 | ...::MySome(...) | | main.rs:941:5:945:5 | MyOption | -| main.rs:1004:13:1004:31 | ...::MySome(...) | T | main.rs:976:5:977:13 | S | -| main.rs:1004:30:1004:30 | S | | main.rs:976:5:977:13 | S | -| main.rs:1006:18:1006:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:1006:26:1006:32 | from_if | | main.rs:941:5:945:5 | MyOption | -| main.rs:1006:26:1006:32 | from_if | T | main.rs:976:5:977:13 | S | -| main.rs:1008:13:1008:22 | from_match | | main.rs:941:5:945:5 | MyOption | -| main.rs:1008:13:1008:22 | from_match | T | main.rs:976:5:977:13 | S | -| main.rs:1008:26:1011:9 | match ... { ... } | | main.rs:941:5:945:5 | MyOption | -| main.rs:1008:26:1011:9 | match ... { ... } | T | main.rs:976:5:977:13 | S | -| main.rs:1008:32:1008:32 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1008:36:1008:36 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1008:40:1008:40 | 2 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1009:13:1009:16 | true | | file:///BUILTINS/types.rs:3:1:5:16 | bool | -| main.rs:1009:21:1009:38 | ...::MyNone(...) | | main.rs:941:5:945:5 | MyOption | -| main.rs:1009:21:1009:38 | ...::MyNone(...) | T | main.rs:976:5:977:13 | S | -| main.rs:1010:13:1010:17 | false | | file:///BUILTINS/types.rs:3:1:5:16 | bool | -| main.rs:1010:22:1010:40 | ...::MySome(...) | | main.rs:941:5:945:5 | MyOption | -| main.rs:1010:22:1010:40 | ...::MySome(...) | T | main.rs:976:5:977:13 | S | -| main.rs:1010:39:1010:39 | S | | main.rs:976:5:977:13 | S | -| main.rs:1012:18:1012:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:1012:26:1012:35 | from_match | | main.rs:941:5:945:5 | MyOption | -| main.rs:1012:26:1012:35 | from_match | T | main.rs:976:5:977:13 | S | -| main.rs:1014:13:1014:21 | from_loop | | main.rs:941:5:945:5 | MyOption | -| main.rs:1014:13:1014:21 | from_loop | T | main.rs:976:5:977:13 | S | -| main.rs:1014:25:1019:9 | loop { ... } | | main.rs:941:5:945:5 | MyOption | -| main.rs:1014:25:1019:9 | loop { ... } | T | main.rs:976:5:977:13 | S | -| main.rs:1015:16:1015:16 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1015:20:1015:20 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1015:24:1015:24 | 2 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1016:23:1016:40 | ...::MyNone(...) | | main.rs:941:5:945:5 | MyOption | -| main.rs:1016:23:1016:40 | ...::MyNone(...) | T | main.rs:976:5:977:13 | S | -| main.rs:1018:19:1018:37 | ...::MySome(...) | | main.rs:941:5:945:5 | MyOption | -| main.rs:1018:19:1018:37 | ...::MySome(...) | T | main.rs:976:5:977:13 | S | -| main.rs:1018:36:1018:36 | S | | main.rs:976:5:977:13 | S | -| main.rs:1020:18:1020:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:1020:26:1020:34 | from_loop | | main.rs:941:5:945:5 | MyOption | -| main.rs:1020:26:1020:34 | from_loop | T | main.rs:976:5:977:13 | S | -| main.rs:1033:15:1033:18 | SelfParam | | main.rs:1026:5:1027:19 | S | -| main.rs:1033:15:1033:18 | SelfParam | T | main.rs:1032:10:1032:10 | T | -| main.rs:1033:26:1035:9 | { ... } | | main.rs:1032:10:1032:10 | T | -| main.rs:1034:13:1034:16 | self | | main.rs:1026:5:1027:19 | S | -| main.rs:1034:13:1034:16 | self | T | main.rs:1032:10:1032:10 | T | -| main.rs:1034:13:1034:18 | self.0 | | main.rs:1032:10:1032:10 | T | -| main.rs:1037:15:1037:19 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:1037:15:1037:19 | SelfParam | &T | main.rs:1026:5:1027:19 | S | -| main.rs:1037:15:1037:19 | SelfParam | &T.T | main.rs:1032:10:1032:10 | T | -| main.rs:1037:28:1039:9 | { ... } | | file://:0:0:0:0 | & | -| main.rs:1037:28:1039:9 | { ... } | &T | main.rs:1032:10:1032:10 | T | -| main.rs:1038:13:1038:19 | &... | | file://:0:0:0:0 | & | -| main.rs:1038:13:1038:19 | &... | &T | main.rs:1032:10:1032:10 | T | -| main.rs:1038:14:1038:17 | self | | file://:0:0:0:0 | & | -| main.rs:1038:14:1038:17 | self | &T | main.rs:1026:5:1027:19 | S | -| main.rs:1038:14:1038:17 | self | &T.T | main.rs:1032:10:1032:10 | T | -| main.rs:1038:14:1038:19 | self.0 | | main.rs:1032:10:1032:10 | T | -| main.rs:1041:15:1041:25 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:1041:15:1041:25 | SelfParam | &T | main.rs:1026:5:1027:19 | S | -| main.rs:1041:15:1041:25 | SelfParam | &T.T | main.rs:1032:10:1032:10 | T | -| main.rs:1041:34:1043:9 | { ... } | | file://:0:0:0:0 | & | -| main.rs:1041:34:1043:9 | { ... } | &T | main.rs:1032:10:1032:10 | T | -| main.rs:1042:13:1042:19 | &... | | file://:0:0:0:0 | & | -| main.rs:1042:13:1042:19 | &... | &T | main.rs:1032:10:1032:10 | T | -| main.rs:1042:14:1042:17 | self | | file://:0:0:0:0 | & | -| main.rs:1042:14:1042:17 | self | &T | main.rs:1026:5:1027:19 | S | -| main.rs:1042:14:1042:17 | self | &T.T | main.rs:1032:10:1032:10 | T | -| main.rs:1042:14:1042:19 | self.0 | | main.rs:1032:10:1032:10 | T | -| main.rs:1047:13:1047:14 | x1 | | main.rs:1026:5:1027:19 | S | -| main.rs:1047:13:1047:14 | x1 | T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1047:18:1047:22 | S(...) | | main.rs:1026:5:1027:19 | S | -| main.rs:1047:18:1047:22 | S(...) | T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1047:20:1047:21 | S2 | | main.rs:1029:5:1030:14 | S2 | -| main.rs:1048:18:1048:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:1048:26:1048:27 | x1 | | main.rs:1026:5:1027:19 | S | -| main.rs:1048:26:1048:27 | x1 | T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1048:26:1048:32 | x1.m1() | | main.rs:1029:5:1030:14 | S2 | -| main.rs:1050:13:1050:14 | x2 | | main.rs:1026:5:1027:19 | S | -| main.rs:1050:13:1050:14 | x2 | T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1050:18:1050:22 | S(...) | | main.rs:1026:5:1027:19 | S | -| main.rs:1050:18:1050:22 | S(...) | T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1050:20:1050:21 | S2 | | main.rs:1029:5:1030:14 | S2 | -| main.rs:1052:18:1052:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:1052:26:1052:27 | x2 | | main.rs:1026:5:1027:19 | S | -| main.rs:1052:26:1052:27 | x2 | T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1052:26:1052:32 | x2.m2() | | file://:0:0:0:0 | & | -| main.rs:1052:26:1052:32 | x2.m2() | &T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1053:18:1053:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:1053:26:1053:27 | x2 | | main.rs:1026:5:1027:19 | S | -| main.rs:1053:26:1053:27 | x2 | T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1053:26:1053:32 | x2.m3() | | file://:0:0:0:0 | & | -| main.rs:1053:26:1053:32 | x2.m3() | &T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1055:13:1055:14 | x3 | | main.rs:1026:5:1027:19 | S | -| main.rs:1055:13:1055:14 | x3 | T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1055:18:1055:22 | S(...) | | main.rs:1026:5:1027:19 | S | -| main.rs:1055:18:1055:22 | S(...) | T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1055:20:1055:21 | S2 | | main.rs:1029:5:1030:14 | S2 | -| main.rs:1057:18:1057:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:1057:26:1057:41 | ...::m2(...) | | file://:0:0:0:0 | & | -| main.rs:1057:26:1057:41 | ...::m2(...) | &T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1057:38:1057:40 | &x3 | | file://:0:0:0:0 | & | -| main.rs:1057:38:1057:40 | &x3 | &T | main.rs:1026:5:1027:19 | S | -| main.rs:1057:38:1057:40 | &x3 | &T.T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1057:39:1057:40 | x3 | | main.rs:1026:5:1027:19 | S | -| main.rs:1057:39:1057:40 | x3 | T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1058:18:1058:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:1058:26:1058:41 | ...::m3(...) | | file://:0:0:0:0 | & | -| main.rs:1058:26:1058:41 | ...::m3(...) | &T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1058:38:1058:40 | &x3 | | file://:0:0:0:0 | & | -| main.rs:1058:38:1058:40 | &x3 | &T | main.rs:1026:5:1027:19 | S | -| main.rs:1058:38:1058:40 | &x3 | &T.T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1058:39:1058:40 | x3 | | main.rs:1026:5:1027:19 | S | -| main.rs:1058:39:1058:40 | x3 | T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1060:13:1060:14 | x4 | | file://:0:0:0:0 | & | -| main.rs:1060:13:1060:14 | x4 | &T | main.rs:1026:5:1027:19 | S | -| main.rs:1060:13:1060:14 | x4 | &T.T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1060:18:1060:23 | &... | | file://:0:0:0:0 | & | -| main.rs:1060:18:1060:23 | &... | &T | main.rs:1026:5:1027:19 | S | -| main.rs:1060:18:1060:23 | &... | &T.T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1060:19:1060:23 | S(...) | | main.rs:1026:5:1027:19 | S | -| main.rs:1060:19:1060:23 | S(...) | T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1060:21:1060:22 | S2 | | main.rs:1029:5:1030:14 | S2 | -| main.rs:1062:18:1062:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:1062:26:1062:27 | x4 | | file://:0:0:0:0 | & | -| main.rs:1062:26:1062:27 | x4 | &T | main.rs:1026:5:1027:19 | S | -| main.rs:1062:26:1062:27 | x4 | &T.T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1062:26:1062:32 | x4.m2() | | file://:0:0:0:0 | & | -| main.rs:1062:26:1062:32 | x4.m2() | &T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1063:18:1063:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:1063:26:1063:27 | x4 | | file://:0:0:0:0 | & | -| main.rs:1063:26:1063:27 | x4 | &T | main.rs:1026:5:1027:19 | S | -| main.rs:1063:26:1063:27 | x4 | &T.T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1063:26:1063:32 | x4.m3() | | file://:0:0:0:0 | & | -| main.rs:1063:26:1063:32 | x4.m3() | &T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1065:13:1065:14 | x5 | | file://:0:0:0:0 | & | -| main.rs:1065:13:1065:14 | x5 | &T | main.rs:1026:5:1027:19 | S | -| main.rs:1065:13:1065:14 | x5 | &T.T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1065:18:1065:23 | &... | | file://:0:0:0:0 | & | -| main.rs:1065:18:1065:23 | &... | &T | main.rs:1026:5:1027:19 | S | -| main.rs:1065:18:1065:23 | &... | &T.T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1065:19:1065:23 | S(...) | | main.rs:1026:5:1027:19 | S | -| main.rs:1065:19:1065:23 | S(...) | T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1065:21:1065:22 | S2 | | main.rs:1029:5:1030:14 | S2 | -| main.rs:1067:18:1067:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:1067:26:1067:27 | x5 | | file://:0:0:0:0 | & | -| main.rs:1067:26:1067:27 | x5 | &T | main.rs:1026:5:1027:19 | S | -| main.rs:1067:26:1067:27 | x5 | &T.T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1067:26:1067:32 | x5.m1() | | main.rs:1029:5:1030:14 | S2 | -| main.rs:1068:18:1068:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:1068:26:1068:27 | x5 | | file://:0:0:0:0 | & | -| main.rs:1068:26:1068:27 | x5 | &T | main.rs:1026:5:1027:19 | S | -| main.rs:1068:26:1068:27 | x5 | &T.T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1068:26:1068:29 | x5.0 | | main.rs:1029:5:1030:14 | S2 | -| main.rs:1070:13:1070:14 | x6 | | file://:0:0:0:0 | & | -| main.rs:1070:13:1070:14 | x6 | &T | main.rs:1026:5:1027:19 | S | -| main.rs:1070:13:1070:14 | x6 | &T.T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1070:18:1070:23 | &... | | file://:0:0:0:0 | & | -| main.rs:1070:18:1070:23 | &... | &T | main.rs:1026:5:1027:19 | S | -| main.rs:1070:18:1070:23 | &... | &T.T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1070:19:1070:23 | S(...) | | main.rs:1026:5:1027:19 | S | -| main.rs:1070:19:1070:23 | S(...) | T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1070:21:1070:22 | S2 | | main.rs:1029:5:1030:14 | S2 | -| main.rs:1072:18:1072:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:1072:26:1072:30 | (...) | | main.rs:1026:5:1027:19 | S | -| main.rs:1072:26:1072:30 | (...) | T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1072:26:1072:35 | ... .m1() | | main.rs:1029:5:1030:14 | S2 | -| main.rs:1072:27:1072:29 | * ... | | main.rs:1026:5:1027:19 | S | -| main.rs:1072:27:1072:29 | * ... | T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1072:28:1072:29 | x6 | | file://:0:0:0:0 | & | -| main.rs:1072:28:1072:29 | x6 | &T | main.rs:1026:5:1027:19 | S | -| main.rs:1072:28:1072:29 | x6 | &T.T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1074:13:1074:14 | x7 | | main.rs:1026:5:1027:19 | S | -| main.rs:1074:13:1074:14 | x7 | T | file://:0:0:0:0 | & | -| main.rs:1074:13:1074:14 | x7 | T.&T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1074:18:1074:23 | S(...) | | main.rs:1026:5:1027:19 | S | -| main.rs:1074:18:1074:23 | S(...) | T | file://:0:0:0:0 | & | -| main.rs:1074:18:1074:23 | S(...) | T.&T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1074:20:1074:22 | &S2 | | file://:0:0:0:0 | & | -| main.rs:1074:20:1074:22 | &S2 | &T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1074:21:1074:22 | S2 | | main.rs:1029:5:1030:14 | S2 | -| main.rs:1077:13:1077:13 | t | | file://:0:0:0:0 | & | -| main.rs:1077:13:1077:13 | t | &T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1077:17:1077:18 | x7 | | main.rs:1026:5:1027:19 | S | -| main.rs:1077:17:1077:18 | x7 | T | file://:0:0:0:0 | & | -| main.rs:1077:17:1077:18 | x7 | T.&T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1077:17:1077:23 | x7.m1() | | file://:0:0:0:0 | & | -| main.rs:1077:17:1077:23 | x7.m1() | &T | main.rs:1029:5:1030:14 | S2 | +| main.rs:344:26:344:26 | x | | main.rs:181:5:182:14 | S1 | +| main.rs:345:13:345:13 | y | | main.rs:181:5:182:14 | S1 | +| main.rs:345:17:345:17 | a | | main.rs:175:5:179:5 | MyPair | +| main.rs:345:17:345:17 | a | P1 | main.rs:181:5:182:14 | S1 | +| main.rs:345:17:345:17 | a | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:345:17:345:23 | a.snd() | | main.rs:181:5:182:14 | S1 | +| main.rs:346:18:346:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:346:26:346:26 | y | | main.rs:181:5:182:14 | S1 | +| main.rs:352:13:352:13 | b | | main.rs:175:5:179:5 | MyPair | +| main.rs:352:13:352:13 | b | P1 | main.rs:183:5:184:14 | S2 | +| main.rs:352:13:352:13 | b | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:352:17:352:41 | MyPair {...} | | main.rs:175:5:179:5 | MyPair | +| main.rs:352:17:352:41 | MyPair {...} | P1 | main.rs:183:5:184:14 | S2 | +| main.rs:352:17:352:41 | MyPair {...} | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:352:30:352:31 | S2 | | main.rs:183:5:184:14 | S2 | +| main.rs:352:38:352:39 | S1 | | main.rs:181:5:182:14 | S1 | +| main.rs:353:13:353:13 | x | | main.rs:181:5:182:14 | S1 | +| main.rs:353:17:353:17 | b | | main.rs:175:5:179:5 | MyPair | +| main.rs:353:17:353:17 | b | P1 | main.rs:183:5:184:14 | S2 | +| main.rs:353:17:353:17 | b | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:353:17:353:23 | b.fst() | | main.rs:181:5:182:14 | S1 | +| main.rs:354:18:354:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:354:26:354:26 | x | | main.rs:181:5:182:14 | S1 | +| main.rs:355:13:355:13 | y | | main.rs:183:5:184:14 | S2 | +| main.rs:355:17:355:17 | b | | main.rs:175:5:179:5 | MyPair | +| main.rs:355:17:355:17 | b | P1 | main.rs:183:5:184:14 | S2 | +| main.rs:355:17:355:17 | b | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:355:17:355:23 | b.snd() | | main.rs:183:5:184:14 | S2 | +| main.rs:356:18:356:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:356:26:356:26 | y | | main.rs:183:5:184:14 | S2 | +| main.rs:360:13:360:13 | x | | main.rs:181:5:182:14 | S1 | +| main.rs:360:17:360:39 | call_trait_m1(...) | | main.rs:181:5:182:14 | S1 | +| main.rs:360:31:360:38 | thing_s1 | | main.rs:170:5:173:5 | MyThing | +| main.rs:360:31:360:38 | thing_s1 | A | main.rs:181:5:182:14 | S1 | +| main.rs:361:18:361:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:361:26:361:26 | x | | main.rs:181:5:182:14 | S1 | +| main.rs:362:13:362:13 | y | | main.rs:170:5:173:5 | MyThing | +| main.rs:362:13:362:13 | y | A | main.rs:183:5:184:14 | S2 | +| main.rs:362:17:362:39 | call_trait_m1(...) | | main.rs:170:5:173:5 | MyThing | +| main.rs:362:17:362:39 | call_trait_m1(...) | A | main.rs:183:5:184:14 | S2 | +| main.rs:362:31:362:38 | thing_s2 | | main.rs:170:5:173:5 | MyThing | +| main.rs:362:31:362:38 | thing_s2 | A | main.rs:183:5:184:14 | S2 | +| main.rs:363:18:363:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:363:26:363:26 | y | | main.rs:170:5:173:5 | MyThing | +| main.rs:363:26:363:26 | y | A | main.rs:183:5:184:14 | S2 | +| main.rs:363:26:363:28 | y.a | | main.rs:183:5:184:14 | S2 | +| main.rs:366:13:366:13 | a | | main.rs:175:5:179:5 | MyPair | +| main.rs:366:13:366:13 | a | P1 | main.rs:181:5:182:14 | S1 | +| main.rs:366:13:366:13 | a | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:366:17:366:41 | MyPair {...} | | main.rs:175:5:179:5 | MyPair | +| main.rs:366:17:366:41 | MyPair {...} | P1 | main.rs:181:5:182:14 | S1 | +| main.rs:366:17:366:41 | MyPair {...} | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:366:30:366:31 | S1 | | main.rs:181:5:182:14 | S1 | +| main.rs:366:38:366:39 | S1 | | main.rs:181:5:182:14 | S1 | +| main.rs:367:13:367:13 | x | | main.rs:181:5:182:14 | S1 | +| main.rs:367:17:367:26 | get_fst(...) | | main.rs:181:5:182:14 | S1 | +| main.rs:367:25:367:25 | a | | main.rs:175:5:179:5 | MyPair | +| main.rs:367:25:367:25 | a | P1 | main.rs:181:5:182:14 | S1 | +| main.rs:367:25:367:25 | a | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:368:18:368:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:368:26:368:26 | x | | main.rs:181:5:182:14 | S1 | +| main.rs:369:13:369:13 | y | | main.rs:181:5:182:14 | S1 | +| main.rs:369:17:369:26 | get_snd(...) | | main.rs:181:5:182:14 | S1 | +| main.rs:369:25:369:25 | a | | main.rs:175:5:179:5 | MyPair | +| main.rs:369:25:369:25 | a | P1 | main.rs:181:5:182:14 | S1 | +| main.rs:369:25:369:25 | a | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:370:18:370:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:370:26:370:26 | y | | main.rs:181:5:182:14 | S1 | +| main.rs:373:13:373:13 | b | | main.rs:175:5:179:5 | MyPair | +| main.rs:373:13:373:13 | b | P1 | main.rs:183:5:184:14 | S2 | +| main.rs:373:13:373:13 | b | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:373:17:373:41 | MyPair {...} | | main.rs:175:5:179:5 | MyPair | +| main.rs:373:17:373:41 | MyPair {...} | P1 | main.rs:183:5:184:14 | S2 | +| main.rs:373:17:373:41 | MyPair {...} | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:373:30:373:31 | S2 | | main.rs:183:5:184:14 | S2 | +| main.rs:373:38:373:39 | S1 | | main.rs:181:5:182:14 | S1 | +| main.rs:374:13:374:13 | x | | main.rs:181:5:182:14 | S1 | +| main.rs:374:17:374:26 | get_fst(...) | | main.rs:181:5:182:14 | S1 | +| main.rs:374:25:374:25 | b | | main.rs:175:5:179:5 | MyPair | +| main.rs:374:25:374:25 | b | P1 | main.rs:183:5:184:14 | S2 | +| main.rs:374:25:374:25 | b | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:375:18:375:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:375:26:375:26 | x | | main.rs:181:5:182:14 | S1 | +| main.rs:376:13:376:13 | y | | main.rs:183:5:184:14 | S2 | +| main.rs:376:17:376:26 | get_snd(...) | | main.rs:183:5:184:14 | S2 | +| main.rs:376:25:376:25 | b | | main.rs:175:5:179:5 | MyPair | +| main.rs:376:25:376:25 | b | P1 | main.rs:183:5:184:14 | S2 | +| main.rs:376:25:376:25 | b | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:377:18:377:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:377:26:377:26 | y | | main.rs:183:5:184:14 | S2 | +| main.rs:379:13:379:13 | c | | main.rs:175:5:179:5 | MyPair | +| main.rs:379:13:379:13 | c | P1 | main.rs:185:5:186:14 | S3 | +| main.rs:379:13:379:13 | c | P2 | main.rs:175:5:179:5 | MyPair | +| main.rs:379:13:379:13 | c | P2.P1 | main.rs:183:5:184:14 | S2 | +| main.rs:379:13:379:13 | c | P2.P2 | main.rs:181:5:182:14 | S1 | +| main.rs:379:17:382:9 | MyPair {...} | | main.rs:175:5:179:5 | MyPair | +| main.rs:379:17:382:9 | MyPair {...} | P1 | main.rs:185:5:186:14 | S3 | +| main.rs:379:17:382:9 | MyPair {...} | P2 | main.rs:175:5:179:5 | MyPair | +| main.rs:379:17:382:9 | MyPair {...} | P2.P1 | main.rs:183:5:184:14 | S2 | +| main.rs:379:17:382:9 | MyPair {...} | P2.P2 | main.rs:181:5:182:14 | S1 | +| main.rs:380:17:380:18 | S3 | | main.rs:185:5:186:14 | S3 | +| main.rs:381:17:381:41 | MyPair {...} | | main.rs:175:5:179:5 | MyPair | +| main.rs:381:17:381:41 | MyPair {...} | P1 | main.rs:183:5:184:14 | S2 | +| main.rs:381:17:381:41 | MyPair {...} | P2 | main.rs:181:5:182:14 | S1 | +| main.rs:381:30:381:31 | S2 | | main.rs:183:5:184:14 | S2 | +| main.rs:381:38:381:39 | S1 | | main.rs:181:5:182:14 | S1 | +| main.rs:383:13:383:13 | x | | main.rs:181:5:182:14 | S1 | +| main.rs:383:17:383:30 | get_snd_fst(...) | | main.rs:181:5:182:14 | S1 | +| main.rs:383:29:383:29 | c | | main.rs:175:5:179:5 | MyPair | +| main.rs:383:29:383:29 | c | P1 | main.rs:185:5:186:14 | S3 | +| main.rs:383:29:383:29 | c | P2 | main.rs:175:5:179:5 | MyPair | +| main.rs:383:29:383:29 | c | P2.P1 | main.rs:183:5:184:14 | S2 | +| main.rs:383:29:383:29 | c | P2.P2 | main.rs:181:5:182:14 | S1 | +| main.rs:385:13:385:17 | thing | | main.rs:170:5:173:5 | MyThing | +| main.rs:385:13:385:17 | thing | A | main.rs:181:5:182:14 | S1 | +| main.rs:385:21:385:37 | MyThing {...} | | main.rs:170:5:173:5 | MyThing | +| main.rs:385:21:385:37 | MyThing {...} | A | main.rs:181:5:182:14 | S1 | +| main.rs:385:34:385:35 | S1 | | main.rs:181:5:182:14 | S1 | +| main.rs:386:17:386:21 | thing | | main.rs:170:5:173:5 | MyThing | +| main.rs:386:17:386:21 | thing | A | main.rs:181:5:182:14 | S1 | +| main.rs:387:13:387:13 | j | | main.rs:181:5:182:14 | S1 | +| main.rs:387:17:387:33 | convert_to(...) | | main.rs:181:5:182:14 | S1 | +| main.rs:387:28:387:32 | thing | | main.rs:170:5:173:5 | MyThing | +| main.rs:387:28:387:32 | thing | A | main.rs:181:5:182:14 | S1 | +| main.rs:396:26:396:29 | SelfParam | | main.rs:395:5:399:5 | Self [trait OverlappingTrait] | +| main.rs:398:28:398:31 | SelfParam | | main.rs:395:5:399:5 | Self [trait OverlappingTrait] | +| main.rs:398:34:398:35 | s1 | | main.rs:392:5:393:14 | S1 | +| main.rs:403:26:403:29 | SelfParam | | main.rs:392:5:393:14 | S1 | +| main.rs:403:38:405:9 | { ... } | | main.rs:392:5:393:14 | S1 | +| main.rs:404:20:404:31 | "not called" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:408:28:408:31 | SelfParam | | main.rs:392:5:393:14 | S1 | +| main.rs:408:34:408:35 | s1 | | main.rs:392:5:393:14 | S1 | +| main.rs:408:48:410:9 | { ... } | | main.rs:392:5:393:14 | S1 | +| main.rs:409:20:409:31 | "not called" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:415:26:415:29 | SelfParam | | main.rs:392:5:393:14 | S1 | +| main.rs:415:38:417:9 | { ... } | | main.rs:392:5:393:14 | S1 | +| main.rs:416:13:416:16 | self | | main.rs:392:5:393:14 | S1 | +| main.rs:420:28:420:31 | SelfParam | | main.rs:392:5:393:14 | S1 | +| main.rs:420:40:422:9 | { ... } | | main.rs:392:5:393:14 | S1 | +| main.rs:421:13:421:16 | self | | main.rs:392:5:393:14 | S1 | +| main.rs:426:13:426:13 | x | | main.rs:392:5:393:14 | S1 | +| main.rs:426:17:426:18 | S1 | | main.rs:392:5:393:14 | S1 | +| main.rs:427:18:427:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:427:26:427:26 | x | | main.rs:392:5:393:14 | S1 | +| main.rs:427:26:427:42 | x.common_method() | | main.rs:392:5:393:14 | S1 | +| main.rs:428:18:428:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:428:26:428:26 | x | | main.rs:392:5:393:14 | S1 | +| main.rs:428:26:428:44 | x.common_method_2() | | main.rs:392:5:393:14 | S1 | +| main.rs:445:19:445:22 | SelfParam | | main.rs:443:5:446:5 | Self [trait FirstTrait] | +| main.rs:450:19:450:22 | SelfParam | | main.rs:448:5:451:5 | Self [trait SecondTrait] | +| main.rs:453:64:453:64 | x | | main.rs:453:45:453:61 | T | +| main.rs:455:13:455:14 | s1 | | main.rs:453:35:453:42 | I | +| main.rs:455:18:455:18 | x | | main.rs:453:45:453:61 | T | +| main.rs:455:18:455:27 | x.method() | | main.rs:453:35:453:42 | I | +| main.rs:456:18:456:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:456:26:456:27 | s1 | | main.rs:453:35:453:42 | I | +| main.rs:459:65:459:65 | x | | main.rs:459:46:459:62 | T | +| main.rs:461:13:461:14 | s2 | | main.rs:459:36:459:43 | I | +| main.rs:461:18:461:18 | x | | main.rs:459:46:459:62 | T | +| main.rs:461:18:461:27 | x.method() | | main.rs:459:36:459:43 | I | +| main.rs:462:18:462:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:462:26:462:27 | s2 | | main.rs:459:36:459:43 | I | +| main.rs:465:49:465:49 | x | | main.rs:465:30:465:46 | T | +| main.rs:466:13:466:13 | s | | main.rs:435:5:436:14 | S1 | +| main.rs:466:17:466:17 | x | | main.rs:465:30:465:46 | T | +| main.rs:466:17:466:26 | x.method() | | main.rs:435:5:436:14 | S1 | +| main.rs:467:18:467:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:467:26:467:26 | s | | main.rs:435:5:436:14 | S1 | +| main.rs:470:53:470:53 | x | | main.rs:470:34:470:50 | T | +| main.rs:471:13:471:13 | s | | main.rs:435:5:436:14 | S1 | +| main.rs:471:17:471:17 | x | | main.rs:470:34:470:50 | T | +| main.rs:471:17:471:26 | x.method() | | main.rs:435:5:436:14 | S1 | +| main.rs:472:18:472:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:472:26:472:26 | s | | main.rs:435:5:436:14 | S1 | +| main.rs:476:16:476:19 | SelfParam | | main.rs:475:5:479:5 | Self [trait Pair] | +| main.rs:478:16:478:19 | SelfParam | | main.rs:475:5:479:5 | Self [trait Pair] | +| main.rs:481:58:481:58 | x | | main.rs:481:41:481:55 | T | +| main.rs:481:64:481:64 | y | | main.rs:481:41:481:55 | T | +| main.rs:483:13:483:14 | s1 | | main.rs:435:5:436:14 | S1 | +| main.rs:483:18:483:18 | x | | main.rs:481:41:481:55 | T | +| main.rs:483:18:483:24 | x.fst() | | main.rs:435:5:436:14 | S1 | +| main.rs:484:13:484:14 | s2 | | main.rs:438:5:439:14 | S2 | +| main.rs:484:18:484:18 | y | | main.rs:481:41:481:55 | T | +| main.rs:484:18:484:24 | y.snd() | | main.rs:438:5:439:14 | S2 | +| main.rs:485:18:485:29 | "{:?}, {:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:485:32:485:33 | s1 | | main.rs:435:5:436:14 | S1 | +| main.rs:485:36:485:37 | s2 | | main.rs:438:5:439:14 | S2 | +| main.rs:488:69:488:69 | x | | main.rs:488:52:488:66 | T | +| main.rs:488:75:488:75 | y | | main.rs:488:52:488:66 | T | +| main.rs:490:13:490:14 | s1 | | main.rs:435:5:436:14 | S1 | +| main.rs:490:18:490:18 | x | | main.rs:488:52:488:66 | T | +| main.rs:490:18:490:24 | x.fst() | | main.rs:435:5:436:14 | S1 | +| main.rs:491:13:491:14 | s2 | | main.rs:488:41:488:49 | T2 | +| main.rs:491:18:491:18 | y | | main.rs:488:52:488:66 | T | +| main.rs:491:18:491:24 | y.snd() | | main.rs:488:41:488:49 | T2 | +| main.rs:492:18:492:29 | "{:?}, {:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:492:32:492:33 | s1 | | main.rs:435:5:436:14 | S1 | +| main.rs:492:36:492:37 | s2 | | main.rs:488:41:488:49 | T2 | +| main.rs:508:15:508:18 | SelfParam | | main.rs:507:5:516:5 | Self [trait MyTrait] | +| main.rs:510:15:510:18 | SelfParam | | main.rs:507:5:516:5 | Self [trait MyTrait] | +| main.rs:513:9:515:9 | { ... } | | main.rs:507:19:507:19 | A | +| main.rs:514:13:514:16 | self | | main.rs:507:5:516:5 | Self [trait MyTrait] | +| main.rs:514:13:514:21 | self.m1() | | main.rs:507:19:507:19 | A | +| main.rs:519:43:519:43 | x | | main.rs:519:26:519:40 | T2 | +| main.rs:519:56:521:5 | { ... } | | main.rs:519:22:519:23 | T1 | +| main.rs:520:9:520:9 | x | | main.rs:519:26:519:40 | T2 | +| main.rs:520:9:520:14 | x.m1() | | main.rs:519:22:519:23 | T1 | +| main.rs:524:49:524:49 | x | | main.rs:497:5:500:5 | MyThing | +| main.rs:524:49:524:49 | x | T | main.rs:524:32:524:46 | T2 | +| main.rs:524:71:526:5 | { ... } | | main.rs:524:28:524:29 | T1 | +| main.rs:525:9:525:9 | x | | main.rs:497:5:500:5 | MyThing | +| main.rs:525:9:525:9 | x | T | main.rs:524:32:524:46 | T2 | +| main.rs:525:9:525:11 | x.a | | main.rs:524:32:524:46 | T2 | +| main.rs:525:9:525:16 | ... .m1() | | main.rs:524:28:524:29 | T1 | +| main.rs:529:15:529:18 | SelfParam | | main.rs:497:5:500:5 | MyThing | +| main.rs:529:15:529:18 | SelfParam | T | main.rs:528:10:528:10 | T | +| main.rs:529:26:531:9 | { ... } | | main.rs:528:10:528:10 | T | +| main.rs:530:13:530:16 | self | | main.rs:497:5:500:5 | MyThing | +| main.rs:530:13:530:16 | self | T | main.rs:528:10:528:10 | T | +| main.rs:530:13:530:18 | self.a | | main.rs:528:10:528:10 | T | +| main.rs:535:13:535:13 | x | | main.rs:497:5:500:5 | MyThing | +| main.rs:535:13:535:13 | x | T | main.rs:502:5:503:14 | S1 | +| main.rs:535:17:535:33 | MyThing {...} | | main.rs:497:5:500:5 | MyThing | +| main.rs:535:17:535:33 | MyThing {...} | T | main.rs:502:5:503:14 | S1 | +| main.rs:535:30:535:31 | S1 | | main.rs:502:5:503:14 | S1 | +| main.rs:536:13:536:13 | y | | main.rs:497:5:500:5 | MyThing | +| main.rs:536:13:536:13 | y | T | main.rs:504:5:505:14 | S2 | +| main.rs:536:17:536:33 | MyThing {...} | | main.rs:497:5:500:5 | MyThing | +| main.rs:536:17:536:33 | MyThing {...} | T | main.rs:504:5:505:14 | S2 | +| main.rs:536:30:536:31 | S2 | | main.rs:504:5:505:14 | S2 | +| main.rs:538:18:538:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:538:26:538:26 | x | | main.rs:497:5:500:5 | MyThing | +| main.rs:538:26:538:26 | x | T | main.rs:502:5:503:14 | S1 | +| main.rs:538:26:538:31 | x.m1() | | main.rs:502:5:503:14 | S1 | +| main.rs:539:18:539:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:539:26:539:26 | y | | main.rs:497:5:500:5 | MyThing | +| main.rs:539:26:539:26 | y | T | main.rs:504:5:505:14 | S2 | +| main.rs:539:26:539:31 | y.m1() | | main.rs:504:5:505:14 | S2 | +| main.rs:541:13:541:13 | x | | main.rs:497:5:500:5 | MyThing | +| main.rs:541:13:541:13 | x | T | main.rs:502:5:503:14 | S1 | +| main.rs:541:17:541:33 | MyThing {...} | | main.rs:497:5:500:5 | MyThing | +| main.rs:541:17:541:33 | MyThing {...} | T | main.rs:502:5:503:14 | S1 | +| main.rs:541:30:541:31 | S1 | | main.rs:502:5:503:14 | S1 | +| main.rs:542:13:542:13 | y | | main.rs:497:5:500:5 | MyThing | +| main.rs:542:13:542:13 | y | T | main.rs:504:5:505:14 | S2 | +| main.rs:542:17:542:33 | MyThing {...} | | main.rs:497:5:500:5 | MyThing | +| main.rs:542:17:542:33 | MyThing {...} | T | main.rs:504:5:505:14 | S2 | +| main.rs:542:30:542:31 | S2 | | main.rs:504:5:505:14 | S2 | +| main.rs:544:18:544:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:544:26:544:26 | x | | main.rs:497:5:500:5 | MyThing | +| main.rs:544:26:544:26 | x | T | main.rs:502:5:503:14 | S1 | +| main.rs:544:26:544:31 | x.m2() | | main.rs:502:5:503:14 | S1 | +| main.rs:545:18:545:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:545:26:545:26 | y | | main.rs:497:5:500:5 | MyThing | +| main.rs:545:26:545:26 | y | T | main.rs:504:5:505:14 | S2 | +| main.rs:545:26:545:31 | y.m2() | | main.rs:504:5:505:14 | S2 | +| main.rs:547:13:547:14 | x2 | | main.rs:497:5:500:5 | MyThing | +| main.rs:547:13:547:14 | x2 | T | main.rs:502:5:503:14 | S1 | +| main.rs:547:18:547:34 | MyThing {...} | | main.rs:497:5:500:5 | MyThing | +| main.rs:547:18:547:34 | MyThing {...} | T | main.rs:502:5:503:14 | S1 | +| main.rs:547:31:547:32 | S1 | | main.rs:502:5:503:14 | S1 | +| main.rs:548:13:548:14 | y2 | | main.rs:497:5:500:5 | MyThing | +| main.rs:548:13:548:14 | y2 | T | main.rs:504:5:505:14 | S2 | +| main.rs:548:18:548:34 | MyThing {...} | | main.rs:497:5:500:5 | MyThing | +| main.rs:548:18:548:34 | MyThing {...} | T | main.rs:504:5:505:14 | S2 | +| main.rs:548:31:548:32 | S2 | | main.rs:504:5:505:14 | S2 | +| main.rs:550:18:550:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:550:26:550:42 | call_trait_m1(...) | | main.rs:502:5:503:14 | S1 | +| main.rs:550:40:550:41 | x2 | | main.rs:497:5:500:5 | MyThing | +| main.rs:550:40:550:41 | x2 | T | main.rs:502:5:503:14 | S1 | +| main.rs:551:18:551:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:551:26:551:42 | call_trait_m1(...) | | main.rs:504:5:505:14 | S2 | +| main.rs:551:40:551:41 | y2 | | main.rs:497:5:500:5 | MyThing | +| main.rs:551:40:551:41 | y2 | T | main.rs:504:5:505:14 | S2 | +| main.rs:553:13:553:14 | x3 | | main.rs:497:5:500:5 | MyThing | +| main.rs:553:13:553:14 | x3 | T | main.rs:497:5:500:5 | MyThing | +| main.rs:553:13:553:14 | x3 | T.T | main.rs:502:5:503:14 | S1 | +| main.rs:553:18:555:9 | MyThing {...} | | main.rs:497:5:500:5 | MyThing | +| main.rs:553:18:555:9 | MyThing {...} | T | main.rs:497:5:500:5 | MyThing | +| main.rs:553:18:555:9 | MyThing {...} | T.T | main.rs:502:5:503:14 | S1 | +| main.rs:554:16:554:32 | MyThing {...} | | main.rs:497:5:500:5 | MyThing | +| main.rs:554:16:554:32 | MyThing {...} | T | main.rs:502:5:503:14 | S1 | +| main.rs:554:29:554:30 | S1 | | main.rs:502:5:503:14 | S1 | +| main.rs:556:13:556:14 | y3 | | main.rs:497:5:500:5 | MyThing | +| main.rs:556:13:556:14 | y3 | T | main.rs:497:5:500:5 | MyThing | +| main.rs:556:13:556:14 | y3 | T.T | main.rs:504:5:505:14 | S2 | +| main.rs:556:18:558:9 | MyThing {...} | | main.rs:497:5:500:5 | MyThing | +| main.rs:556:18:558:9 | MyThing {...} | T | main.rs:497:5:500:5 | MyThing | +| main.rs:556:18:558:9 | MyThing {...} | T.T | main.rs:504:5:505:14 | S2 | +| main.rs:557:16:557:32 | MyThing {...} | | main.rs:497:5:500:5 | MyThing | +| main.rs:557:16:557:32 | MyThing {...} | T | main.rs:504:5:505:14 | S2 | +| main.rs:557:29:557:30 | S2 | | main.rs:504:5:505:14 | S2 | +| main.rs:560:13:560:13 | a | | main.rs:502:5:503:14 | S1 | +| main.rs:560:17:560:39 | call_trait_thing_m1(...) | | main.rs:502:5:503:14 | S1 | +| main.rs:560:37:560:38 | x3 | | main.rs:497:5:500:5 | MyThing | +| main.rs:560:37:560:38 | x3 | T | main.rs:497:5:500:5 | MyThing | +| main.rs:560:37:560:38 | x3 | T.T | main.rs:502:5:503:14 | S1 | +| main.rs:561:18:561:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:561:26:561:26 | a | | main.rs:502:5:503:14 | S1 | +| main.rs:562:13:562:13 | b | | main.rs:504:5:505:14 | S2 | +| main.rs:562:17:562:39 | call_trait_thing_m1(...) | | main.rs:504:5:505:14 | S2 | +| main.rs:562:37:562:38 | y3 | | main.rs:497:5:500:5 | MyThing | +| main.rs:562:37:562:38 | y3 | T | main.rs:497:5:500:5 | MyThing | +| main.rs:562:37:562:38 | y3 | T.T | main.rs:504:5:505:14 | S2 | +| main.rs:563:18:563:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:563:26:563:26 | b | | main.rs:504:5:505:14 | S2 | +| main.rs:574:19:574:22 | SelfParam | | main.rs:568:5:571:5 | Wrapper | +| main.rs:574:19:574:22 | SelfParam | A | main.rs:573:10:573:10 | A | +| main.rs:574:30:576:9 | { ... } | | main.rs:573:10:573:10 | A | +| main.rs:575:13:575:16 | self | | main.rs:568:5:571:5 | Wrapper | +| main.rs:575:13:575:16 | self | A | main.rs:573:10:573:10 | A | +| main.rs:575:13:575:22 | self.field | | main.rs:573:10:573:10 | A | +| main.rs:583:15:583:18 | SelfParam | | main.rs:579:5:593:5 | Self [trait MyTrait] | +| main.rs:585:15:585:18 | SelfParam | | main.rs:579:5:593:5 | Self [trait MyTrait] | +| main.rs:589:9:592:9 | { ... } | | main.rs:580:9:580:28 | AssociatedType | +| main.rs:590:13:590:16 | self | | main.rs:579:5:593:5 | Self [trait MyTrait] | +| main.rs:590:13:590:21 | self.m1() | | main.rs:580:9:580:28 | AssociatedType | +| main.rs:591:13:591:43 | ...::default(...) | | main.rs:580:9:580:28 | AssociatedType | +| main.rs:599:19:599:23 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:599:19:599:23 | SelfParam | &T | main.rs:595:5:605:5 | Self [trait MyTraitAssoc2] | +| main.rs:599:26:599:26 | a | | main.rs:599:16:599:16 | A | +| main.rs:601:22:601:26 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:601:22:601:26 | SelfParam | &T | main.rs:595:5:605:5 | Self [trait MyTraitAssoc2] | +| main.rs:601:29:601:29 | a | | main.rs:601:19:601:19 | A | +| main.rs:601:35:601:35 | b | | main.rs:601:19:601:19 | A | +| main.rs:601:75:604:9 | { ... } | | main.rs:596:9:596:52 | GenericAssociatedType | +| main.rs:602:13:602:16 | self | | file://:0:0:0:0 | & | +| main.rs:602:13:602:16 | self | &T | main.rs:595:5:605:5 | Self [trait MyTraitAssoc2] | +| main.rs:602:13:602:23 | self.put(...) | | main.rs:596:9:596:52 | GenericAssociatedType | +| main.rs:602:22:602:22 | a | | main.rs:601:19:601:19 | A | +| main.rs:603:13:603:16 | self | | file://:0:0:0:0 | & | +| main.rs:603:13:603:16 | self | &T | main.rs:595:5:605:5 | Self [trait MyTraitAssoc2] | +| main.rs:603:13:603:23 | self.put(...) | | main.rs:596:9:596:52 | GenericAssociatedType | +| main.rs:603:22:603:22 | b | | main.rs:601:19:601:19 | A | +| main.rs:612:21:612:25 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:612:21:612:25 | SelfParam | &T | main.rs:607:5:617:5 | Self [trait TraitMultipleAssoc] | +| main.rs:614:20:614:24 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:614:20:614:24 | SelfParam | &T | main.rs:607:5:617:5 | Self [trait TraitMultipleAssoc] | +| main.rs:616:20:616:24 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:616:20:616:24 | SelfParam | &T | main.rs:607:5:617:5 | Self [trait TraitMultipleAssoc] | +| main.rs:632:15:632:18 | SelfParam | | main.rs:619:5:620:13 | S | +| main.rs:632:45:634:9 | { ... } | | main.rs:625:5:626:14 | AT | +| main.rs:633:13:633:14 | AT | | main.rs:625:5:626:14 | AT | +| main.rs:642:19:642:23 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:642:19:642:23 | SelfParam | &T | main.rs:619:5:620:13 | S | +| main.rs:642:26:642:26 | a | | main.rs:642:16:642:16 | A | +| main.rs:642:46:644:9 | { ... } | | main.rs:568:5:571:5 | Wrapper | +| main.rs:642:46:644:9 | { ... } | A | main.rs:642:16:642:16 | A | +| main.rs:643:13:643:32 | Wrapper {...} | | main.rs:568:5:571:5 | Wrapper | +| main.rs:643:13:643:32 | Wrapper {...} | A | main.rs:642:16:642:16 | A | +| main.rs:643:30:643:30 | a | | main.rs:642:16:642:16 | A | +| main.rs:651:15:651:18 | SelfParam | | main.rs:622:5:623:14 | S2 | +| main.rs:651:45:653:9 | { ... } | | main.rs:568:5:571:5 | Wrapper | +| main.rs:651:45:653:9 | { ... } | A | main.rs:622:5:623:14 | S2 | +| main.rs:652:13:652:35 | Wrapper {...} | | main.rs:568:5:571:5 | Wrapper | +| main.rs:652:13:652:35 | Wrapper {...} | A | main.rs:622:5:623:14 | S2 | +| main.rs:652:30:652:33 | self | | main.rs:622:5:623:14 | S2 | +| main.rs:658:30:660:9 | { ... } | | main.rs:568:5:571:5 | Wrapper | +| main.rs:658:30:660:9 | { ... } | A | main.rs:622:5:623:14 | S2 | +| main.rs:659:13:659:33 | Wrapper {...} | | main.rs:568:5:571:5 | Wrapper | +| main.rs:659:13:659:33 | Wrapper {...} | A | main.rs:622:5:623:14 | S2 | +| main.rs:659:30:659:31 | S2 | | main.rs:622:5:623:14 | S2 | +| main.rs:664:22:664:26 | thing | | main.rs:664:10:664:19 | T | +| main.rs:665:9:665:13 | thing | | main.rs:664:10:664:19 | T | +| main.rs:672:21:672:25 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:672:21:672:25 | SelfParam | &T | main.rs:625:5:626:14 | AT | +| main.rs:672:34:674:9 | { ... } | | main.rs:625:5:626:14 | AT | +| main.rs:673:13:673:14 | AT | | main.rs:625:5:626:14 | AT | +| main.rs:676:20:676:24 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:676:20:676:24 | SelfParam | &T | main.rs:625:5:626:14 | AT | +| main.rs:676:43:678:9 | { ... } | | main.rs:619:5:620:13 | S | +| main.rs:677:13:677:13 | S | | main.rs:619:5:620:13 | S | +| main.rs:680:20:680:24 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:680:20:680:24 | SelfParam | &T | main.rs:625:5:626:14 | AT | +| main.rs:680:43:682:9 | { ... } | | main.rs:622:5:623:14 | S2 | +| main.rs:681:13:681:14 | S2 | | main.rs:622:5:623:14 | S2 | +| main.rs:686:13:686:14 | x1 | | main.rs:619:5:620:13 | S | +| main.rs:686:18:686:18 | S | | main.rs:619:5:620:13 | S | +| main.rs:688:18:688:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:688:26:688:27 | x1 | | main.rs:619:5:620:13 | S | +| main.rs:688:26:688:32 | x1.m1() | | main.rs:625:5:626:14 | AT | +| main.rs:690:13:690:14 | x2 | | main.rs:619:5:620:13 | S | +| main.rs:690:18:690:18 | S | | main.rs:619:5:620:13 | S | +| main.rs:692:13:692:13 | y | | main.rs:625:5:626:14 | AT | +| main.rs:692:17:692:18 | x2 | | main.rs:619:5:620:13 | S | +| main.rs:692:17:692:23 | x2.m2() | | main.rs:625:5:626:14 | AT | +| main.rs:693:18:693:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:693:26:693:26 | y | | main.rs:625:5:626:14 | AT | +| main.rs:695:13:695:14 | x3 | | main.rs:619:5:620:13 | S | +| main.rs:695:18:695:18 | S | | main.rs:619:5:620:13 | S | +| main.rs:697:18:697:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:697:26:697:27 | x3 | | main.rs:619:5:620:13 | S | +| main.rs:697:26:697:34 | x3.put(...) | | main.rs:568:5:571:5 | Wrapper | +| main.rs:697:26:697:34 | x3.put(...) | A | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:697:26:697:43 | ... .unwrap() | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:697:33:697:33 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:700:18:700:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:700:26:700:27 | x3 | | main.rs:619:5:620:13 | S | +| main.rs:700:36:700:36 | 2 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:700:39:700:39 | 3 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:702:20:702:20 | S | | main.rs:619:5:620:13 | S | +| main.rs:703:18:703:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:705:13:705:14 | x5 | | main.rs:622:5:623:14 | S2 | +| main.rs:705:18:705:19 | S2 | | main.rs:622:5:623:14 | S2 | +| main.rs:706:18:706:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:706:26:706:27 | x5 | | main.rs:622:5:623:14 | S2 | +| main.rs:706:26:706:32 | x5.m1() | | main.rs:568:5:571:5 | Wrapper | +| main.rs:706:26:706:32 | x5.m1() | A | main.rs:622:5:623:14 | S2 | +| main.rs:707:13:707:14 | x6 | | main.rs:622:5:623:14 | S2 | +| main.rs:707:18:707:19 | S2 | | main.rs:622:5:623:14 | S2 | +| main.rs:708:18:708:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:708:26:708:27 | x6 | | main.rs:622:5:623:14 | S2 | +| main.rs:708:26:708:32 | x6.m2() | | main.rs:568:5:571:5 | Wrapper | +| main.rs:708:26:708:32 | x6.m2() | A | main.rs:622:5:623:14 | S2 | +| main.rs:710:13:710:22 | assoc_zero | | main.rs:625:5:626:14 | AT | +| main.rs:710:26:710:27 | AT | | main.rs:625:5:626:14 | AT | +| main.rs:710:26:710:38 | AT.get_zero() | | main.rs:625:5:626:14 | AT | +| main.rs:711:13:711:21 | assoc_one | | main.rs:619:5:620:13 | S | +| main.rs:711:25:711:26 | AT | | main.rs:625:5:626:14 | AT | +| main.rs:711:25:711:36 | AT.get_one() | | main.rs:619:5:620:13 | S | +| main.rs:712:13:712:21 | assoc_two | | main.rs:622:5:623:14 | S2 | +| main.rs:712:25:712:26 | AT | | main.rs:625:5:626:14 | AT | +| main.rs:712:25:712:36 | AT.get_two() | | main.rs:622:5:623:14 | S2 | +| main.rs:729:15:729:18 | SelfParam | | main.rs:717:5:721:5 | MyEnum | +| main.rs:729:15:729:18 | SelfParam | A | main.rs:728:10:728:10 | T | +| main.rs:729:26:734:9 | { ... } | | main.rs:728:10:728:10 | T | +| main.rs:730:13:733:13 | match self { ... } | | main.rs:728:10:728:10 | T | +| main.rs:730:19:730:22 | self | | main.rs:717:5:721:5 | MyEnum | +| main.rs:730:19:730:22 | self | A | main.rs:728:10:728:10 | T | +| main.rs:731:28:731:28 | a | | main.rs:728:10:728:10 | T | +| main.rs:731:34:731:34 | a | | main.rs:728:10:728:10 | T | +| main.rs:732:30:732:30 | a | | main.rs:728:10:728:10 | T | +| main.rs:732:37:732:37 | a | | main.rs:728:10:728:10 | T | +| main.rs:738:13:738:13 | x | | main.rs:717:5:721:5 | MyEnum | +| main.rs:738:13:738:13 | x | A | main.rs:723:5:724:14 | S1 | +| main.rs:738:17:738:30 | ...::C1(...) | | main.rs:717:5:721:5 | MyEnum | +| main.rs:738:17:738:30 | ...::C1(...) | A | main.rs:723:5:724:14 | S1 | +| main.rs:738:28:738:29 | S1 | | main.rs:723:5:724:14 | S1 | +| main.rs:739:13:739:13 | y | | main.rs:717:5:721:5 | MyEnum | +| main.rs:739:13:739:13 | y | A | main.rs:725:5:726:14 | S2 | +| main.rs:739:17:739:36 | ...::C2 {...} | | main.rs:717:5:721:5 | MyEnum | +| main.rs:739:17:739:36 | ...::C2 {...} | A | main.rs:725:5:726:14 | S2 | +| main.rs:739:33:739:34 | S2 | | main.rs:725:5:726:14 | S2 | +| main.rs:741:18:741:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:741:26:741:26 | x | | main.rs:717:5:721:5 | MyEnum | +| main.rs:741:26:741:26 | x | A | main.rs:723:5:724:14 | S1 | +| main.rs:741:26:741:31 | x.m1() | | main.rs:723:5:724:14 | S1 | +| main.rs:742:18:742:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:742:26:742:26 | y | | main.rs:717:5:721:5 | MyEnum | +| main.rs:742:26:742:26 | y | A | main.rs:725:5:726:14 | S2 | +| main.rs:742:26:742:31 | y.m1() | | main.rs:725:5:726:14 | S2 | +| main.rs:764:15:764:18 | SelfParam | | main.rs:762:5:765:5 | Self [trait MyTrait1] | +| main.rs:768:15:768:18 | SelfParam | | main.rs:767:5:778:5 | Self [trait MyTrait2] | +| main.rs:771:9:777:9 | { ... } | | main.rs:767:20:767:22 | Tr2 | +| main.rs:772:13:776:13 | if ... {...} else {...} | | main.rs:767:20:767:22 | Tr2 | +| main.rs:772:16:772:16 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:772:20:772:20 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:772:24:772:24 | 2 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:772:26:774:13 | { ... } | | main.rs:767:20:767:22 | Tr2 | +| main.rs:773:17:773:20 | self | | main.rs:767:5:778:5 | Self [trait MyTrait2] | +| main.rs:773:17:773:25 | self.m1() | | main.rs:767:20:767:22 | Tr2 | +| main.rs:774:20:776:13 | { ... } | | main.rs:767:20:767:22 | Tr2 | +| main.rs:775:17:775:30 | ...::m1(...) | | main.rs:767:20:767:22 | Tr2 | +| main.rs:775:26:775:29 | self | | main.rs:767:5:778:5 | Self [trait MyTrait2] | +| main.rs:781:15:781:18 | SelfParam | | main.rs:780:5:791:5 | Self [trait MyTrait3] | +| main.rs:784:9:790:9 | { ... } | | main.rs:780:20:780:22 | Tr3 | +| main.rs:785:13:789:13 | if ... {...} else {...} | | main.rs:780:20:780:22 | Tr3 | +| main.rs:785:16:785:16 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:785:20:785:20 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:785:24:785:24 | 2 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:785:26:787:13 | { ... } | | main.rs:780:20:780:22 | Tr3 | +| main.rs:786:17:786:20 | self | | main.rs:780:5:791:5 | Self [trait MyTrait3] | +| main.rs:786:17:786:25 | self.m2() | | main.rs:747:5:750:5 | MyThing | +| main.rs:786:17:786:25 | self.m2() | A | main.rs:780:20:780:22 | Tr3 | +| main.rs:786:17:786:27 | ... .a | | main.rs:780:20:780:22 | Tr3 | +| main.rs:787:20:789:13 | { ... } | | main.rs:780:20:780:22 | Tr3 | +| main.rs:788:17:788:30 | ...::m2(...) | | main.rs:747:5:750:5 | MyThing | +| main.rs:788:17:788:30 | ...::m2(...) | A | main.rs:780:20:780:22 | Tr3 | +| main.rs:788:17:788:32 | ... .a | | main.rs:780:20:780:22 | Tr3 | +| main.rs:788:26:788:29 | self | | main.rs:780:5:791:5 | Self [trait MyTrait3] | +| main.rs:795:15:795:18 | SelfParam | | main.rs:747:5:750:5 | MyThing | +| main.rs:795:15:795:18 | SelfParam | A | main.rs:793:10:793:10 | T | +| main.rs:795:26:797:9 | { ... } | | main.rs:793:10:793:10 | T | +| main.rs:796:13:796:16 | self | | main.rs:747:5:750:5 | MyThing | +| main.rs:796:13:796:16 | self | A | main.rs:793:10:793:10 | T | +| main.rs:796:13:796:18 | self.a | | main.rs:793:10:793:10 | T | +| main.rs:804:15:804:18 | SelfParam | | main.rs:752:5:755:5 | MyThing2 | +| main.rs:804:15:804:18 | SelfParam | A | main.rs:802:10:802:10 | T | +| main.rs:804:35:806:9 | { ... } | | main.rs:747:5:750:5 | MyThing | +| main.rs:804:35:806:9 | { ... } | A | main.rs:802:10:802:10 | T | +| main.rs:805:13:805:33 | MyThing {...} | | main.rs:747:5:750:5 | MyThing | +| main.rs:805:13:805:33 | MyThing {...} | A | main.rs:802:10:802:10 | T | +| main.rs:805:26:805:29 | self | | main.rs:752:5:755:5 | MyThing2 | +| main.rs:805:26:805:29 | self | A | main.rs:802:10:802:10 | T | +| main.rs:805:26:805:31 | self.a | | main.rs:802:10:802:10 | T | +| main.rs:813:44:813:44 | x | | main.rs:813:26:813:41 | T2 | +| main.rs:813:57:815:5 | { ... } | | main.rs:813:22:813:23 | T1 | +| main.rs:814:9:814:9 | x | | main.rs:813:26:813:41 | T2 | +| main.rs:814:9:814:14 | x.m1() | | main.rs:813:22:813:23 | T1 | +| main.rs:817:56:817:56 | x | | main.rs:817:39:817:53 | T | +| main.rs:819:13:819:13 | a | | main.rs:747:5:750:5 | MyThing | +| main.rs:819:13:819:13 | a | A | main.rs:757:5:758:14 | S1 | +| main.rs:819:17:819:17 | x | | main.rs:817:39:817:53 | T | +| main.rs:819:17:819:22 | x.m1() | | main.rs:747:5:750:5 | MyThing | +| main.rs:819:17:819:22 | x.m1() | A | main.rs:757:5:758:14 | S1 | +| main.rs:820:18:820:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:820:26:820:26 | a | | main.rs:747:5:750:5 | MyThing | +| main.rs:820:26:820:26 | a | A | main.rs:757:5:758:14 | S1 | +| main.rs:824:13:824:13 | x | | main.rs:747:5:750:5 | MyThing | +| main.rs:824:13:824:13 | x | A | main.rs:757:5:758:14 | S1 | +| main.rs:824:17:824:33 | MyThing {...} | | main.rs:747:5:750:5 | MyThing | +| main.rs:824:17:824:33 | MyThing {...} | A | main.rs:757:5:758:14 | S1 | +| main.rs:824:30:824:31 | S1 | | main.rs:757:5:758:14 | S1 | +| main.rs:825:13:825:13 | y | | main.rs:747:5:750:5 | MyThing | +| main.rs:825:13:825:13 | y | A | main.rs:759:5:760:14 | S2 | +| main.rs:825:17:825:33 | MyThing {...} | | main.rs:747:5:750:5 | MyThing | +| main.rs:825:17:825:33 | MyThing {...} | A | main.rs:759:5:760:14 | S2 | +| main.rs:825:30:825:31 | S2 | | main.rs:759:5:760:14 | S2 | +| main.rs:827:18:827:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:827:26:827:26 | x | | main.rs:747:5:750:5 | MyThing | +| main.rs:827:26:827:26 | x | A | main.rs:757:5:758:14 | S1 | +| main.rs:827:26:827:31 | x.m1() | | main.rs:757:5:758:14 | S1 | +| main.rs:828:18:828:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:828:26:828:26 | y | | main.rs:747:5:750:5 | MyThing | +| main.rs:828:26:828:26 | y | A | main.rs:759:5:760:14 | S2 | +| main.rs:828:26:828:31 | y.m1() | | main.rs:759:5:760:14 | S2 | +| main.rs:830:13:830:13 | x | | main.rs:747:5:750:5 | MyThing | +| main.rs:830:13:830:13 | x | A | main.rs:757:5:758:14 | S1 | +| main.rs:830:17:830:33 | MyThing {...} | | main.rs:747:5:750:5 | MyThing | +| main.rs:830:17:830:33 | MyThing {...} | A | main.rs:757:5:758:14 | S1 | +| main.rs:830:30:830:31 | S1 | | main.rs:757:5:758:14 | S1 | +| main.rs:831:13:831:13 | y | | main.rs:747:5:750:5 | MyThing | +| main.rs:831:13:831:13 | y | A | main.rs:759:5:760:14 | S2 | +| main.rs:831:17:831:33 | MyThing {...} | | main.rs:747:5:750:5 | MyThing | +| main.rs:831:17:831:33 | MyThing {...} | A | main.rs:759:5:760:14 | S2 | +| main.rs:831:30:831:31 | S2 | | main.rs:759:5:760:14 | S2 | +| main.rs:833:18:833:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:833:26:833:26 | x | | main.rs:747:5:750:5 | MyThing | +| main.rs:833:26:833:26 | x | A | main.rs:757:5:758:14 | S1 | +| main.rs:833:26:833:31 | x.m2() | | main.rs:757:5:758:14 | S1 | +| main.rs:834:18:834:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:834:26:834:26 | y | | main.rs:747:5:750:5 | MyThing | +| main.rs:834:26:834:26 | y | A | main.rs:759:5:760:14 | S2 | +| main.rs:834:26:834:31 | y.m2() | | main.rs:759:5:760:14 | S2 | +| main.rs:836:13:836:13 | x | | main.rs:752:5:755:5 | MyThing2 | +| main.rs:836:13:836:13 | x | A | main.rs:757:5:758:14 | S1 | +| main.rs:836:17:836:34 | MyThing2 {...} | | main.rs:752:5:755:5 | MyThing2 | +| main.rs:836:17:836:34 | MyThing2 {...} | A | main.rs:757:5:758:14 | S1 | +| main.rs:836:31:836:32 | S1 | | main.rs:757:5:758:14 | S1 | +| main.rs:837:13:837:13 | y | | main.rs:752:5:755:5 | MyThing2 | +| main.rs:837:13:837:13 | y | A | main.rs:759:5:760:14 | S2 | +| main.rs:837:17:837:34 | MyThing2 {...} | | main.rs:752:5:755:5 | MyThing2 | +| main.rs:837:17:837:34 | MyThing2 {...} | A | main.rs:759:5:760:14 | S2 | +| main.rs:837:31:837:32 | S2 | | main.rs:759:5:760:14 | S2 | +| main.rs:839:18:839:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:839:26:839:26 | x | | main.rs:752:5:755:5 | MyThing2 | +| main.rs:839:26:839:26 | x | A | main.rs:757:5:758:14 | S1 | +| main.rs:839:26:839:31 | x.m3() | | main.rs:757:5:758:14 | S1 | +| main.rs:840:18:840:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:840:26:840:26 | y | | main.rs:752:5:755:5 | MyThing2 | +| main.rs:840:26:840:26 | y | A | main.rs:759:5:760:14 | S2 | +| main.rs:840:26:840:31 | y.m3() | | main.rs:759:5:760:14 | S2 | +| main.rs:842:13:842:13 | x | | main.rs:747:5:750:5 | MyThing | +| main.rs:842:13:842:13 | x | A | main.rs:757:5:758:14 | S1 | +| main.rs:842:17:842:33 | MyThing {...} | | main.rs:747:5:750:5 | MyThing | +| main.rs:842:17:842:33 | MyThing {...} | A | main.rs:757:5:758:14 | S1 | +| main.rs:842:30:842:31 | S1 | | main.rs:757:5:758:14 | S1 | +| main.rs:843:13:843:13 | s | | main.rs:757:5:758:14 | S1 | +| main.rs:843:17:843:32 | call_trait_m1(...) | | main.rs:757:5:758:14 | S1 | +| main.rs:843:31:843:31 | x | | main.rs:747:5:750:5 | MyThing | +| main.rs:843:31:843:31 | x | A | main.rs:757:5:758:14 | S1 | +| main.rs:845:13:845:13 | x | | main.rs:752:5:755:5 | MyThing2 | +| main.rs:845:13:845:13 | x | A | main.rs:759:5:760:14 | S2 | +| main.rs:845:17:845:34 | MyThing2 {...} | | main.rs:752:5:755:5 | MyThing2 | +| main.rs:845:17:845:34 | MyThing2 {...} | A | main.rs:759:5:760:14 | S2 | +| main.rs:845:31:845:32 | S2 | | main.rs:759:5:760:14 | S2 | +| main.rs:846:13:846:13 | s | | main.rs:747:5:750:5 | MyThing | +| main.rs:846:13:846:13 | s | A | main.rs:759:5:760:14 | S2 | +| main.rs:846:17:846:32 | call_trait_m1(...) | | main.rs:747:5:750:5 | MyThing | +| main.rs:846:17:846:32 | call_trait_m1(...) | A | main.rs:759:5:760:14 | S2 | +| main.rs:846:31:846:31 | x | | main.rs:752:5:755:5 | MyThing2 | +| main.rs:846:31:846:31 | x | A | main.rs:759:5:760:14 | S2 | +| main.rs:864:22:864:22 | x | | file://:0:0:0:0 | & | +| main.rs:864:22:864:22 | x | &T | main.rs:864:11:864:19 | T | +| main.rs:864:35:866:5 | { ... } | | file://:0:0:0:0 | & | +| main.rs:864:35:866:5 | { ... } | &T | main.rs:864:11:864:19 | T | +| main.rs:865:9:865:9 | x | | file://:0:0:0:0 | & | +| main.rs:865:9:865:9 | x | &T | main.rs:864:11:864:19 | T | +| main.rs:869:17:869:20 | SelfParam | | main.rs:854:5:855:14 | S1 | +| main.rs:869:29:871:9 | { ... } | | main.rs:857:5:858:14 | S2 | +| main.rs:870:13:870:14 | S2 | | main.rs:857:5:858:14 | S2 | +| main.rs:874:21:874:21 | x | | main.rs:874:13:874:14 | T1 | +| main.rs:877:5:879:5 | { ... } | | main.rs:874:17:874:18 | T2 | +| main.rs:878:9:878:9 | x | | main.rs:874:13:874:14 | T1 | +| main.rs:878:9:878:16 | x.into() | | main.rs:874:17:874:18 | T2 | +| main.rs:882:13:882:13 | x | | main.rs:854:5:855:14 | S1 | +| main.rs:882:17:882:18 | S1 | | main.rs:854:5:855:14 | S1 | +| main.rs:883:18:883:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:883:26:883:31 | id(...) | | file://:0:0:0:0 | & | +| main.rs:883:26:883:31 | id(...) | &T | main.rs:854:5:855:14 | S1 | +| main.rs:883:29:883:30 | &x | | file://:0:0:0:0 | & | +| main.rs:883:29:883:30 | &x | &T | main.rs:854:5:855:14 | S1 | +| main.rs:883:30:883:30 | x | | main.rs:854:5:855:14 | S1 | +| main.rs:885:13:885:13 | x | | main.rs:854:5:855:14 | S1 | +| main.rs:885:17:885:18 | S1 | | main.rs:854:5:855:14 | S1 | +| main.rs:886:18:886:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:886:26:886:37 | id::<...>(...) | | file://:0:0:0:0 | & | +| main.rs:886:26:886:37 | id::<...>(...) | &T | main.rs:854:5:855:14 | S1 | +| main.rs:886:35:886:36 | &x | | file://:0:0:0:0 | & | +| main.rs:886:35:886:36 | &x | &T | main.rs:854:5:855:14 | S1 | +| main.rs:886:36:886:36 | x | | main.rs:854:5:855:14 | S1 | +| main.rs:888:13:888:13 | x | | main.rs:854:5:855:14 | S1 | +| main.rs:888:17:888:18 | S1 | | main.rs:854:5:855:14 | S1 | +| main.rs:889:18:889:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:889:26:889:44 | id::<...>(...) | | file://:0:0:0:0 | & | +| main.rs:889:26:889:44 | id::<...>(...) | &T | main.rs:854:5:855:14 | S1 | +| main.rs:889:42:889:43 | &x | | file://:0:0:0:0 | & | +| main.rs:889:42:889:43 | &x | &T | main.rs:854:5:855:14 | S1 | +| main.rs:889:43:889:43 | x | | main.rs:854:5:855:14 | S1 | +| main.rs:891:13:891:13 | x | | main.rs:854:5:855:14 | S1 | +| main.rs:891:17:891:18 | S1 | | main.rs:854:5:855:14 | S1 | +| main.rs:892:9:892:25 | into::<...>(...) | | main.rs:857:5:858:14 | S2 | +| main.rs:892:24:892:24 | x | | main.rs:854:5:855:14 | S1 | +| main.rs:894:13:894:13 | x | | main.rs:854:5:855:14 | S1 | +| main.rs:894:17:894:18 | S1 | | main.rs:854:5:855:14 | S1 | +| main.rs:895:13:895:13 | y | | main.rs:857:5:858:14 | S2 | +| main.rs:895:21:895:27 | into(...) | | main.rs:857:5:858:14 | S2 | +| main.rs:895:26:895:26 | x | | main.rs:854:5:855:14 | S1 | +| main.rs:909:22:909:25 | SelfParam | | main.rs:900:5:906:5 | PairOption | +| main.rs:909:22:909:25 | SelfParam | Fst | main.rs:908:10:908:12 | Fst | +| main.rs:909:22:909:25 | SelfParam | Snd | main.rs:908:15:908:17 | Snd | +| main.rs:909:35:916:9 | { ... } | | main.rs:908:15:908:17 | Snd | +| main.rs:910:13:915:13 | match self { ... } | | main.rs:908:15:908:17 | Snd | +| main.rs:910:19:910:22 | self | | main.rs:900:5:906:5 | PairOption | +| main.rs:910:19:910:22 | self | Fst | main.rs:908:10:908:12 | Fst | +| main.rs:910:19:910:22 | self | Snd | main.rs:908:15:908:17 | Snd | +| main.rs:911:43:911:82 | MacroExpr | | main.rs:908:15:908:17 | Snd | +| main.rs:911:50:911:81 | "PairNone has no second elemen... | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:912:43:912:81 | MacroExpr | | main.rs:908:15:908:17 | Snd | +| main.rs:912:50:912:80 | "PairFst has no second element... | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:913:37:913:39 | snd | | main.rs:908:15:908:17 | Snd | +| main.rs:913:45:913:47 | snd | | main.rs:908:15:908:17 | Snd | +| main.rs:914:41:914:43 | snd | | main.rs:908:15:908:17 | Snd | +| main.rs:914:49:914:51 | snd | | main.rs:908:15:908:17 | Snd | +| main.rs:940:10:940:10 | t | | main.rs:900:5:906:5 | PairOption | +| main.rs:940:10:940:10 | t | Fst | main.rs:922:5:923:14 | S2 | +| main.rs:940:10:940:10 | t | Snd | main.rs:900:5:906:5 | PairOption | +| main.rs:940:10:940:10 | t | Snd.Fst | main.rs:922:5:923:14 | S2 | +| main.rs:940:10:940:10 | t | Snd.Snd | main.rs:925:5:926:14 | S3 | +| main.rs:941:13:941:13 | x | | main.rs:925:5:926:14 | S3 | +| main.rs:941:17:941:17 | t | | main.rs:900:5:906:5 | PairOption | +| main.rs:941:17:941:17 | t | Fst | main.rs:922:5:923:14 | S2 | +| main.rs:941:17:941:17 | t | Snd | main.rs:900:5:906:5 | PairOption | +| main.rs:941:17:941:17 | t | Snd.Fst | main.rs:922:5:923:14 | S2 | +| main.rs:941:17:941:17 | t | Snd.Snd | main.rs:925:5:926:14 | S3 | +| main.rs:941:17:941:29 | t.unwrapSnd() | | main.rs:900:5:906:5 | PairOption | +| main.rs:941:17:941:29 | t.unwrapSnd() | Fst | main.rs:922:5:923:14 | S2 | +| main.rs:941:17:941:29 | t.unwrapSnd() | Snd | main.rs:925:5:926:14 | S3 | +| main.rs:941:17:941:41 | ... .unwrapSnd() | | main.rs:925:5:926:14 | S3 | +| main.rs:942:18:942:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:942:26:942:26 | x | | main.rs:925:5:926:14 | S3 | +| main.rs:947:13:947:14 | p1 | | main.rs:900:5:906:5 | PairOption | +| main.rs:947:13:947:14 | p1 | Fst | main.rs:919:5:920:14 | S1 | +| main.rs:947:13:947:14 | p1 | Snd | main.rs:922:5:923:14 | S2 | +| main.rs:947:26:947:53 | ...::PairBoth(...) | | main.rs:900:5:906:5 | PairOption | +| main.rs:947:26:947:53 | ...::PairBoth(...) | Fst | main.rs:919:5:920:14 | S1 | +| main.rs:947:26:947:53 | ...::PairBoth(...) | Snd | main.rs:922:5:923:14 | S2 | +| main.rs:947:47:947:48 | S1 | | main.rs:919:5:920:14 | S1 | +| main.rs:947:51:947:52 | S2 | | main.rs:922:5:923:14 | S2 | +| main.rs:948:18:948:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:948:26:948:27 | p1 | | main.rs:900:5:906:5 | PairOption | +| main.rs:948:26:948:27 | p1 | Fst | main.rs:919:5:920:14 | S1 | +| main.rs:948:26:948:27 | p1 | Snd | main.rs:922:5:923:14 | S2 | +| main.rs:951:13:951:14 | p2 | | main.rs:900:5:906:5 | PairOption | +| main.rs:951:13:951:14 | p2 | Fst | main.rs:919:5:920:14 | S1 | +| main.rs:951:13:951:14 | p2 | Snd | main.rs:922:5:923:14 | S2 | +| main.rs:951:26:951:47 | ...::PairNone(...) | | main.rs:900:5:906:5 | PairOption | +| main.rs:951:26:951:47 | ...::PairNone(...) | Fst | main.rs:919:5:920:14 | S1 | +| main.rs:951:26:951:47 | ...::PairNone(...) | Snd | main.rs:922:5:923:14 | S2 | +| main.rs:952:18:952:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:952:26:952:27 | p2 | | main.rs:900:5:906:5 | PairOption | +| main.rs:952:26:952:27 | p2 | Fst | main.rs:919:5:920:14 | S1 | +| main.rs:952:26:952:27 | p2 | Snd | main.rs:922:5:923:14 | S2 | +| main.rs:955:13:955:14 | p3 | | main.rs:900:5:906:5 | PairOption | +| main.rs:955:13:955:14 | p3 | Fst | main.rs:922:5:923:14 | S2 | +| main.rs:955:13:955:14 | p3 | Snd | main.rs:925:5:926:14 | S3 | +| main.rs:955:34:955:56 | ...::PairSnd(...) | | main.rs:900:5:906:5 | PairOption | +| main.rs:955:34:955:56 | ...::PairSnd(...) | Fst | main.rs:922:5:923:14 | S2 | +| main.rs:955:34:955:56 | ...::PairSnd(...) | Snd | main.rs:925:5:926:14 | S3 | +| main.rs:955:54:955:55 | S3 | | main.rs:925:5:926:14 | S3 | +| main.rs:956:18:956:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:956:26:956:27 | p3 | | main.rs:900:5:906:5 | PairOption | +| main.rs:956:26:956:27 | p3 | Fst | main.rs:922:5:923:14 | S2 | +| main.rs:956:26:956:27 | p3 | Snd | main.rs:925:5:926:14 | S3 | +| main.rs:959:13:959:14 | p3 | | main.rs:900:5:906:5 | PairOption | +| main.rs:959:13:959:14 | p3 | Fst | main.rs:922:5:923:14 | S2 | +| main.rs:959:13:959:14 | p3 | Snd | main.rs:925:5:926:14 | S3 | +| main.rs:959:35:959:56 | ...::PairNone(...) | | main.rs:900:5:906:5 | PairOption | +| main.rs:959:35:959:56 | ...::PairNone(...) | Fst | main.rs:922:5:923:14 | S2 | +| main.rs:959:35:959:56 | ...::PairNone(...) | Snd | main.rs:925:5:926:14 | S3 | +| main.rs:960:18:960:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:960:26:960:27 | p3 | | main.rs:900:5:906:5 | PairOption | +| main.rs:960:26:960:27 | p3 | Fst | main.rs:922:5:923:14 | S2 | +| main.rs:960:26:960:27 | p3 | Snd | main.rs:925:5:926:14 | S3 | +| main.rs:962:11:962:54 | ...::PairSnd(...) | | main.rs:900:5:906:5 | PairOption | +| main.rs:962:11:962:54 | ...::PairSnd(...) | Fst | main.rs:922:5:923:14 | S2 | +| main.rs:962:11:962:54 | ...::PairSnd(...) | Snd | main.rs:900:5:906:5 | PairOption | +| main.rs:962:11:962:54 | ...::PairSnd(...) | Snd.Fst | main.rs:922:5:923:14 | S2 | +| main.rs:962:11:962:54 | ...::PairSnd(...) | Snd.Snd | main.rs:925:5:926:14 | S3 | +| main.rs:962:31:962:53 | ...::PairSnd(...) | | main.rs:900:5:906:5 | PairOption | +| main.rs:962:31:962:53 | ...::PairSnd(...) | Fst | main.rs:922:5:923:14 | S2 | +| main.rs:962:31:962:53 | ...::PairSnd(...) | Snd | main.rs:925:5:926:14 | S3 | +| main.rs:962:51:962:52 | S3 | | main.rs:925:5:926:14 | S3 | +| main.rs:975:16:975:24 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:975:16:975:24 | SelfParam | &T | main.rs:973:5:980:5 | Self [trait MyTrait] | +| main.rs:975:27:975:31 | value | | main.rs:973:19:973:19 | S | +| main.rs:977:21:977:29 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:977:21:977:29 | SelfParam | &T | main.rs:973:5:980:5 | Self [trait MyTrait] | +| main.rs:977:32:977:36 | value | | main.rs:973:19:973:19 | S | +| main.rs:978:13:978:16 | self | | file://:0:0:0:0 | & | +| main.rs:978:13:978:16 | self | &T | main.rs:973:5:980:5 | Self [trait MyTrait] | +| main.rs:978:22:978:26 | value | | main.rs:973:19:973:19 | S | +| main.rs:984:16:984:24 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:984:16:984:24 | SelfParam | &T | main.rs:967:5:971:5 | MyOption | +| main.rs:984:16:984:24 | SelfParam | &T.T | main.rs:982:10:982:10 | T | +| main.rs:984:27:984:31 | value | | main.rs:982:10:982:10 | T | +| main.rs:988:26:990:9 | { ... } | | main.rs:967:5:971:5 | MyOption | +| main.rs:988:26:990:9 | { ... } | T | main.rs:987:10:987:10 | T | +| main.rs:989:13:989:30 | ...::MyNone(...) | | main.rs:967:5:971:5 | MyOption | +| main.rs:989:13:989:30 | ...::MyNone(...) | T | main.rs:987:10:987:10 | T | +| main.rs:994:20:994:23 | SelfParam | | main.rs:967:5:971:5 | MyOption | +| main.rs:994:20:994:23 | SelfParam | T | main.rs:967:5:971:5 | MyOption | +| main.rs:994:20:994:23 | SelfParam | T.T | main.rs:993:10:993:10 | T | +| main.rs:994:41:999:9 | { ... } | | main.rs:967:5:971:5 | MyOption | +| main.rs:994:41:999:9 | { ... } | T | main.rs:993:10:993:10 | T | +| main.rs:995:13:998:13 | match self { ... } | | main.rs:967:5:971:5 | MyOption | +| main.rs:995:13:998:13 | match self { ... } | T | main.rs:993:10:993:10 | T | +| main.rs:995:19:995:22 | self | | main.rs:967:5:971:5 | MyOption | +| main.rs:995:19:995:22 | self | T | main.rs:967:5:971:5 | MyOption | +| main.rs:995:19:995:22 | self | T.T | main.rs:993:10:993:10 | T | +| main.rs:996:39:996:56 | ...::MyNone(...) | | main.rs:967:5:971:5 | MyOption | +| main.rs:996:39:996:56 | ...::MyNone(...) | T | main.rs:993:10:993:10 | T | +| main.rs:997:34:997:34 | x | | main.rs:967:5:971:5 | MyOption | +| main.rs:997:34:997:34 | x | T | main.rs:993:10:993:10 | T | +| main.rs:997:40:997:40 | x | | main.rs:967:5:971:5 | MyOption | +| main.rs:997:40:997:40 | x | T | main.rs:993:10:993:10 | T | +| main.rs:1006:13:1006:14 | x1 | | main.rs:967:5:971:5 | MyOption | +| main.rs:1006:18:1006:37 | ...::new(...) | | main.rs:967:5:971:5 | MyOption | +| main.rs:1007:18:1007:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1007:26:1007:27 | x1 | | main.rs:967:5:971:5 | MyOption | +| main.rs:1009:13:1009:18 | mut x2 | | main.rs:967:5:971:5 | MyOption | +| main.rs:1009:13:1009:18 | mut x2 | T | main.rs:1002:5:1003:13 | S | +| main.rs:1009:22:1009:36 | ...::new(...) | | main.rs:967:5:971:5 | MyOption | +| main.rs:1009:22:1009:36 | ...::new(...) | T | main.rs:1002:5:1003:13 | S | +| main.rs:1010:9:1010:10 | x2 | | main.rs:967:5:971:5 | MyOption | +| main.rs:1010:9:1010:10 | x2 | T | main.rs:1002:5:1003:13 | S | +| main.rs:1010:16:1010:16 | S | | main.rs:1002:5:1003:13 | S | +| main.rs:1011:18:1011:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1011:26:1011:27 | x2 | | main.rs:967:5:971:5 | MyOption | +| main.rs:1011:26:1011:27 | x2 | T | main.rs:1002:5:1003:13 | S | +| main.rs:1013:13:1013:18 | mut x3 | | main.rs:967:5:971:5 | MyOption | +| main.rs:1013:22:1013:36 | ...::new(...) | | main.rs:967:5:971:5 | MyOption | +| main.rs:1014:9:1014:10 | x3 | | main.rs:967:5:971:5 | MyOption | +| main.rs:1014:21:1014:21 | S | | main.rs:1002:5:1003:13 | S | +| main.rs:1015:18:1015:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1015:26:1015:27 | x3 | | main.rs:967:5:971:5 | MyOption | +| main.rs:1017:13:1017:18 | mut x4 | | main.rs:967:5:971:5 | MyOption | +| main.rs:1017:13:1017:18 | mut x4 | T | main.rs:1002:5:1003:13 | S | +| main.rs:1017:22:1017:36 | ...::new(...) | | main.rs:967:5:971:5 | MyOption | +| main.rs:1017:22:1017:36 | ...::new(...) | T | main.rs:1002:5:1003:13 | S | +| main.rs:1018:23:1018:29 | &mut x4 | | file://:0:0:0:0 | & | +| main.rs:1018:23:1018:29 | &mut x4 | &T | main.rs:967:5:971:5 | MyOption | +| main.rs:1018:23:1018:29 | &mut x4 | &T.T | main.rs:1002:5:1003:13 | S | +| main.rs:1018:28:1018:29 | x4 | | main.rs:967:5:971:5 | MyOption | +| main.rs:1018:28:1018:29 | x4 | T | main.rs:1002:5:1003:13 | S | +| main.rs:1018:32:1018:32 | S | | main.rs:1002:5:1003:13 | S | +| main.rs:1019:18:1019:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1019:26:1019:27 | x4 | | main.rs:967:5:971:5 | MyOption | +| main.rs:1019:26:1019:27 | x4 | T | main.rs:1002:5:1003:13 | S | +| main.rs:1021:13:1021:14 | x5 | | main.rs:967:5:971:5 | MyOption | +| main.rs:1021:13:1021:14 | x5 | T | main.rs:967:5:971:5 | MyOption | +| main.rs:1021:13:1021:14 | x5 | T.T | main.rs:1002:5:1003:13 | S | +| main.rs:1021:18:1021:58 | ...::MySome(...) | | main.rs:967:5:971:5 | MyOption | +| main.rs:1021:18:1021:58 | ...::MySome(...) | T | main.rs:967:5:971:5 | MyOption | +| main.rs:1021:18:1021:58 | ...::MySome(...) | T.T | main.rs:1002:5:1003:13 | S | +| main.rs:1021:35:1021:57 | ...::MyNone(...) | | main.rs:967:5:971:5 | MyOption | +| main.rs:1021:35:1021:57 | ...::MyNone(...) | T | main.rs:1002:5:1003:13 | S | +| main.rs:1022:18:1022:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1022:26:1022:27 | x5 | | main.rs:967:5:971:5 | MyOption | +| main.rs:1022:26:1022:27 | x5 | T | main.rs:967:5:971:5 | MyOption | +| main.rs:1022:26:1022:27 | x5 | T.T | main.rs:1002:5:1003:13 | S | +| main.rs:1022:26:1022:37 | x5.flatten() | | main.rs:967:5:971:5 | MyOption | +| main.rs:1022:26:1022:37 | x5.flatten() | T | main.rs:1002:5:1003:13 | S | +| main.rs:1024:13:1024:14 | x6 | | main.rs:967:5:971:5 | MyOption | +| main.rs:1024:13:1024:14 | x6 | T | main.rs:967:5:971:5 | MyOption | +| main.rs:1024:13:1024:14 | x6 | T.T | main.rs:1002:5:1003:13 | S | +| main.rs:1024:18:1024:58 | ...::MySome(...) | | main.rs:967:5:971:5 | MyOption | +| main.rs:1024:18:1024:58 | ...::MySome(...) | T | main.rs:967:5:971:5 | MyOption | +| main.rs:1024:18:1024:58 | ...::MySome(...) | T.T | main.rs:1002:5:1003:13 | S | +| main.rs:1024:35:1024:57 | ...::MyNone(...) | | main.rs:967:5:971:5 | MyOption | +| main.rs:1024:35:1024:57 | ...::MyNone(...) | T | main.rs:1002:5:1003:13 | S | +| main.rs:1025:18:1025:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1025:26:1025:61 | ...::flatten(...) | | main.rs:967:5:971:5 | MyOption | +| main.rs:1025:26:1025:61 | ...::flatten(...) | T | main.rs:1002:5:1003:13 | S | +| main.rs:1025:59:1025:60 | x6 | | main.rs:967:5:971:5 | MyOption | +| main.rs:1025:59:1025:60 | x6 | T | main.rs:967:5:971:5 | MyOption | +| main.rs:1025:59:1025:60 | x6 | T.T | main.rs:1002:5:1003:13 | S | +| main.rs:1027:13:1027:19 | from_if | | main.rs:967:5:971:5 | MyOption | +| main.rs:1027:13:1027:19 | from_if | T | main.rs:1002:5:1003:13 | S | +| main.rs:1027:23:1031:9 | if ... {...} else {...} | | main.rs:967:5:971:5 | MyOption | +| main.rs:1027:23:1031:9 | if ... {...} else {...} | T | main.rs:1002:5:1003:13 | S | +| main.rs:1027:26:1027:26 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1027:30:1027:30 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1027:34:1027:34 | 2 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1027:36:1029:9 | { ... } | | main.rs:967:5:971:5 | MyOption | +| main.rs:1027:36:1029:9 | { ... } | T | main.rs:1002:5:1003:13 | S | +| main.rs:1028:13:1028:30 | ...::MyNone(...) | | main.rs:967:5:971:5 | MyOption | +| main.rs:1028:13:1028:30 | ...::MyNone(...) | T | main.rs:1002:5:1003:13 | S | +| main.rs:1029:16:1031:9 | { ... } | | main.rs:967:5:971:5 | MyOption | +| main.rs:1029:16:1031:9 | { ... } | T | main.rs:1002:5:1003:13 | S | +| main.rs:1030:13:1030:31 | ...::MySome(...) | | main.rs:967:5:971:5 | MyOption | +| main.rs:1030:13:1030:31 | ...::MySome(...) | T | main.rs:1002:5:1003:13 | S | +| main.rs:1030:30:1030:30 | S | | main.rs:1002:5:1003:13 | S | +| main.rs:1032:18:1032:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1032:26:1032:32 | from_if | | main.rs:967:5:971:5 | MyOption | +| main.rs:1032:26:1032:32 | from_if | T | main.rs:1002:5:1003:13 | S | +| main.rs:1034:13:1034:22 | from_match | | main.rs:967:5:971:5 | MyOption | +| main.rs:1034:13:1034:22 | from_match | T | main.rs:1002:5:1003:13 | S | +| main.rs:1034:26:1037:9 | match ... { ... } | | main.rs:967:5:971:5 | MyOption | +| main.rs:1034:26:1037:9 | match ... { ... } | T | main.rs:1002:5:1003:13 | S | +| main.rs:1034:32:1034:32 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1034:36:1034:36 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1034:40:1034:40 | 2 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1035:13:1035:16 | true | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:1035:21:1035:38 | ...::MyNone(...) | | main.rs:967:5:971:5 | MyOption | +| main.rs:1035:21:1035:38 | ...::MyNone(...) | T | main.rs:1002:5:1003:13 | S | +| main.rs:1036:13:1036:17 | false | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:1036:22:1036:40 | ...::MySome(...) | | main.rs:967:5:971:5 | MyOption | +| main.rs:1036:22:1036:40 | ...::MySome(...) | T | main.rs:1002:5:1003:13 | S | +| main.rs:1036:39:1036:39 | S | | main.rs:1002:5:1003:13 | S | +| main.rs:1038:18:1038:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1038:26:1038:35 | from_match | | main.rs:967:5:971:5 | MyOption | +| main.rs:1038:26:1038:35 | from_match | T | main.rs:1002:5:1003:13 | S | +| main.rs:1040:13:1040:21 | from_loop | | main.rs:967:5:971:5 | MyOption | +| main.rs:1040:13:1040:21 | from_loop | T | main.rs:1002:5:1003:13 | S | +| main.rs:1040:25:1045:9 | loop { ... } | | main.rs:967:5:971:5 | MyOption | +| main.rs:1040:25:1045:9 | loop { ... } | T | main.rs:1002:5:1003:13 | S | +| main.rs:1041:16:1041:16 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1041:20:1041:20 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1041:24:1041:24 | 2 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1042:23:1042:40 | ...::MyNone(...) | | main.rs:967:5:971:5 | MyOption | +| main.rs:1042:23:1042:40 | ...::MyNone(...) | T | main.rs:1002:5:1003:13 | S | +| main.rs:1044:19:1044:37 | ...::MySome(...) | | main.rs:967:5:971:5 | MyOption | +| main.rs:1044:19:1044:37 | ...::MySome(...) | T | main.rs:1002:5:1003:13 | S | +| main.rs:1044:36:1044:36 | S | | main.rs:1002:5:1003:13 | S | +| main.rs:1046:18:1046:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1046:26:1046:34 | from_loop | | main.rs:967:5:971:5 | MyOption | +| main.rs:1046:26:1046:34 | from_loop | T | main.rs:1002:5:1003:13 | S | +| main.rs:1059:15:1059:18 | SelfParam | | main.rs:1052:5:1053:19 | S | +| main.rs:1059:15:1059:18 | SelfParam | T | main.rs:1058:10:1058:10 | T | +| main.rs:1059:26:1061:9 | { ... } | | main.rs:1058:10:1058:10 | T | +| main.rs:1060:13:1060:16 | self | | main.rs:1052:5:1053:19 | S | +| main.rs:1060:13:1060:16 | self | T | main.rs:1058:10:1058:10 | T | +| main.rs:1060:13:1060:18 | self.0 | | main.rs:1058:10:1058:10 | T | +| main.rs:1063:15:1063:19 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:1063:15:1063:19 | SelfParam | &T | main.rs:1052:5:1053:19 | S | +| main.rs:1063:15:1063:19 | SelfParam | &T.T | main.rs:1058:10:1058:10 | T | +| main.rs:1063:28:1065:9 | { ... } | | file://:0:0:0:0 | & | +| main.rs:1063:28:1065:9 | { ... } | &T | main.rs:1058:10:1058:10 | T | +| main.rs:1064:13:1064:19 | &... | | file://:0:0:0:0 | & | +| main.rs:1064:13:1064:19 | &... | &T | main.rs:1058:10:1058:10 | T | +| main.rs:1064:14:1064:17 | self | | file://:0:0:0:0 | & | +| main.rs:1064:14:1064:17 | self | &T | main.rs:1052:5:1053:19 | S | +| main.rs:1064:14:1064:17 | self | &T.T | main.rs:1058:10:1058:10 | T | +| main.rs:1064:14:1064:19 | self.0 | | main.rs:1058:10:1058:10 | T | +| main.rs:1067:15:1067:25 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:1067:15:1067:25 | SelfParam | &T | main.rs:1052:5:1053:19 | S | +| main.rs:1067:15:1067:25 | SelfParam | &T.T | main.rs:1058:10:1058:10 | T | +| main.rs:1067:34:1069:9 | { ... } | | file://:0:0:0:0 | & | +| main.rs:1067:34:1069:9 | { ... } | &T | main.rs:1058:10:1058:10 | T | +| main.rs:1068:13:1068:19 | &... | | file://:0:0:0:0 | & | +| main.rs:1068:13:1068:19 | &... | &T | main.rs:1058:10:1058:10 | T | +| main.rs:1068:14:1068:17 | self | | file://:0:0:0:0 | & | +| main.rs:1068:14:1068:17 | self | &T | main.rs:1052:5:1053:19 | S | +| main.rs:1068:14:1068:17 | self | &T.T | main.rs:1058:10:1058:10 | T | +| main.rs:1068:14:1068:19 | self.0 | | main.rs:1058:10:1058:10 | T | +| main.rs:1073:13:1073:14 | x1 | | main.rs:1052:5:1053:19 | S | +| main.rs:1073:13:1073:14 | x1 | T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1073:18:1073:22 | S(...) | | main.rs:1052:5:1053:19 | S | +| main.rs:1073:18:1073:22 | S(...) | T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1073:20:1073:21 | S2 | | main.rs:1055:5:1056:14 | S2 | +| main.rs:1074:18:1074:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1074:26:1074:27 | x1 | | main.rs:1052:5:1053:19 | S | +| main.rs:1074:26:1074:27 | x1 | T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1074:26:1074:32 | x1.m1() | | main.rs:1055:5:1056:14 | S2 | +| main.rs:1076:13:1076:14 | x2 | | main.rs:1052:5:1053:19 | S | +| main.rs:1076:13:1076:14 | x2 | T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1076:18:1076:22 | S(...) | | main.rs:1052:5:1053:19 | S | +| main.rs:1076:18:1076:22 | S(...) | T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1076:20:1076:21 | S2 | | main.rs:1055:5:1056:14 | S2 | | main.rs:1078:18:1078:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:1078:26:1078:27 | x7 | | main.rs:1026:5:1027:19 | S | -| main.rs:1078:26:1078:27 | x7 | T | file://:0:0:0:0 | & | -| main.rs:1078:26:1078:27 | x7 | T.&T | main.rs:1029:5:1030:14 | S2 | -| main.rs:1085:16:1085:20 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:1085:16:1085:20 | SelfParam | &T | main.rs:1083:5:1091:5 | Self [trait MyTrait] | -| main.rs:1088:16:1088:20 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:1088:16:1088:20 | SelfParam | &T | main.rs:1083:5:1091:5 | Self [trait MyTrait] | -| main.rs:1088:32:1090:9 | { ... } | | file://:0:0:0:0 | & | -| main.rs:1088:32:1090:9 | { ... } | &T | main.rs:1083:5:1091:5 | Self [trait MyTrait] | -| main.rs:1089:13:1089:16 | self | | file://:0:0:0:0 | & | -| main.rs:1089:13:1089:16 | self | &T | main.rs:1083:5:1091:5 | Self [trait MyTrait] | -| main.rs:1089:13:1089:22 | self.foo() | | file://:0:0:0:0 | & | -| main.rs:1089:13:1089:22 | self.foo() | &T | main.rs:1083:5:1091:5 | Self [trait MyTrait] | -| main.rs:1097:16:1097:20 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:1097:16:1097:20 | SelfParam | &T | main.rs:1093:5:1093:20 | MyStruct | -| main.rs:1097:36:1099:9 | { ... } | | file://:0:0:0:0 | & | -| main.rs:1097:36:1099:9 | { ... } | &T | main.rs:1093:5:1093:20 | MyStruct | -| main.rs:1098:13:1098:16 | self | | file://:0:0:0:0 | & | -| main.rs:1098:13:1098:16 | self | &T | main.rs:1093:5:1093:20 | MyStruct | -| main.rs:1103:13:1103:13 | x | | main.rs:1093:5:1093:20 | MyStruct | -| main.rs:1103:17:1103:24 | MyStruct | | main.rs:1093:5:1093:20 | MyStruct | -| main.rs:1104:9:1104:9 | x | | main.rs:1093:5:1093:20 | MyStruct | -| main.rs:1104:9:1104:15 | x.bar() | | file://:0:0:0:0 | & | -| main.rs:1104:9:1104:15 | x.bar() | &T | main.rs:1093:5:1093:20 | MyStruct | +| main.rs:1078:26:1078:27 | x2 | | main.rs:1052:5:1053:19 | S | +| main.rs:1078:26:1078:27 | x2 | T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1078:26:1078:32 | x2.m2() | | file://:0:0:0:0 | & | +| main.rs:1078:26:1078:32 | x2.m2() | &T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1079:18:1079:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1079:26:1079:27 | x2 | | main.rs:1052:5:1053:19 | S | +| main.rs:1079:26:1079:27 | x2 | T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1079:26:1079:32 | x2.m3() | | file://:0:0:0:0 | & | +| main.rs:1079:26:1079:32 | x2.m3() | &T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1081:13:1081:14 | x3 | | main.rs:1052:5:1053:19 | S | +| main.rs:1081:13:1081:14 | x3 | T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1081:18:1081:22 | S(...) | | main.rs:1052:5:1053:19 | S | +| main.rs:1081:18:1081:22 | S(...) | T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1081:20:1081:21 | S2 | | main.rs:1055:5:1056:14 | S2 | +| main.rs:1083:18:1083:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1083:26:1083:41 | ...::m2(...) | | file://:0:0:0:0 | & | +| main.rs:1083:26:1083:41 | ...::m2(...) | &T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1083:38:1083:40 | &x3 | | file://:0:0:0:0 | & | +| main.rs:1083:38:1083:40 | &x3 | &T | main.rs:1052:5:1053:19 | S | +| main.rs:1083:38:1083:40 | &x3 | &T.T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1083:39:1083:40 | x3 | | main.rs:1052:5:1053:19 | S | +| main.rs:1083:39:1083:40 | x3 | T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1084:18:1084:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1084:26:1084:41 | ...::m3(...) | | file://:0:0:0:0 | & | +| main.rs:1084:26:1084:41 | ...::m3(...) | &T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1084:38:1084:40 | &x3 | | file://:0:0:0:0 | & | +| main.rs:1084:38:1084:40 | &x3 | &T | main.rs:1052:5:1053:19 | S | +| main.rs:1084:38:1084:40 | &x3 | &T.T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1084:39:1084:40 | x3 | | main.rs:1052:5:1053:19 | S | +| main.rs:1084:39:1084:40 | x3 | T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1086:13:1086:14 | x4 | | file://:0:0:0:0 | & | +| main.rs:1086:13:1086:14 | x4 | &T | main.rs:1052:5:1053:19 | S | +| main.rs:1086:13:1086:14 | x4 | &T.T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1086:18:1086:23 | &... | | file://:0:0:0:0 | & | +| main.rs:1086:18:1086:23 | &... | &T | main.rs:1052:5:1053:19 | S | +| main.rs:1086:18:1086:23 | &... | &T.T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1086:19:1086:23 | S(...) | | main.rs:1052:5:1053:19 | S | +| main.rs:1086:19:1086:23 | S(...) | T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1086:21:1086:22 | S2 | | main.rs:1055:5:1056:14 | S2 | +| main.rs:1088:18:1088:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1088:26:1088:27 | x4 | | file://:0:0:0:0 | & | +| main.rs:1088:26:1088:27 | x4 | &T | main.rs:1052:5:1053:19 | S | +| main.rs:1088:26:1088:27 | x4 | &T.T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1088:26:1088:32 | x4.m2() | | file://:0:0:0:0 | & | +| main.rs:1088:26:1088:32 | x4.m2() | &T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1089:18:1089:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1089:26:1089:27 | x4 | | file://:0:0:0:0 | & | +| main.rs:1089:26:1089:27 | x4 | &T | main.rs:1052:5:1053:19 | S | +| main.rs:1089:26:1089:27 | x4 | &T.T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1089:26:1089:32 | x4.m3() | | file://:0:0:0:0 | & | +| main.rs:1089:26:1089:32 | x4.m3() | &T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1091:13:1091:14 | x5 | | file://:0:0:0:0 | & | +| main.rs:1091:13:1091:14 | x5 | &T | main.rs:1052:5:1053:19 | S | +| main.rs:1091:13:1091:14 | x5 | &T.T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1091:18:1091:23 | &... | | file://:0:0:0:0 | & | +| main.rs:1091:18:1091:23 | &... | &T | main.rs:1052:5:1053:19 | S | +| main.rs:1091:18:1091:23 | &... | &T.T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1091:19:1091:23 | S(...) | | main.rs:1052:5:1053:19 | S | +| main.rs:1091:19:1091:23 | S(...) | T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1091:21:1091:22 | S2 | | main.rs:1055:5:1056:14 | S2 | +| main.rs:1093:18:1093:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1093:26:1093:27 | x5 | | file://:0:0:0:0 | & | +| main.rs:1093:26:1093:27 | x5 | &T | main.rs:1052:5:1053:19 | S | +| main.rs:1093:26:1093:27 | x5 | &T.T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1093:26:1093:32 | x5.m1() | | main.rs:1055:5:1056:14 | S2 | +| main.rs:1094:18:1094:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1094:26:1094:27 | x5 | | file://:0:0:0:0 | & | +| main.rs:1094:26:1094:27 | x5 | &T | main.rs:1052:5:1053:19 | S | +| main.rs:1094:26:1094:27 | x5 | &T.T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1094:26:1094:29 | x5.0 | | main.rs:1055:5:1056:14 | S2 | +| main.rs:1096:13:1096:14 | x6 | | file://:0:0:0:0 | & | +| main.rs:1096:13:1096:14 | x6 | &T | main.rs:1052:5:1053:19 | S | +| main.rs:1096:13:1096:14 | x6 | &T.T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1096:18:1096:23 | &... | | file://:0:0:0:0 | & | +| main.rs:1096:18:1096:23 | &... | &T | main.rs:1052:5:1053:19 | S | +| main.rs:1096:18:1096:23 | &... | &T.T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1096:19:1096:23 | S(...) | | main.rs:1052:5:1053:19 | S | +| main.rs:1096:19:1096:23 | S(...) | T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1096:21:1096:22 | S2 | | main.rs:1055:5:1056:14 | S2 | +| main.rs:1098:18:1098:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1098:26:1098:30 | (...) | | main.rs:1052:5:1053:19 | S | +| main.rs:1098:26:1098:30 | (...) | T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1098:26:1098:35 | ... .m1() | | main.rs:1055:5:1056:14 | S2 | +| main.rs:1098:27:1098:29 | * ... | | main.rs:1052:5:1053:19 | S | +| main.rs:1098:27:1098:29 | * ... | T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1098:28:1098:29 | x6 | | file://:0:0:0:0 | & | +| main.rs:1098:28:1098:29 | x6 | &T | main.rs:1052:5:1053:19 | S | +| main.rs:1098:28:1098:29 | x6 | &T.T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1100:13:1100:14 | x7 | | main.rs:1052:5:1053:19 | S | +| main.rs:1100:13:1100:14 | x7 | T | file://:0:0:0:0 | & | +| main.rs:1100:13:1100:14 | x7 | T.&T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1100:18:1100:23 | S(...) | | main.rs:1052:5:1053:19 | S | +| main.rs:1100:18:1100:23 | S(...) | T | file://:0:0:0:0 | & | +| main.rs:1100:18:1100:23 | S(...) | T.&T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1100:20:1100:22 | &S2 | | file://:0:0:0:0 | & | +| main.rs:1100:20:1100:22 | &S2 | &T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1100:21:1100:22 | S2 | | main.rs:1055:5:1056:14 | S2 | +| main.rs:1103:13:1103:13 | t | | file://:0:0:0:0 | & | +| main.rs:1103:13:1103:13 | t | &T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1103:17:1103:18 | x7 | | main.rs:1052:5:1053:19 | S | +| main.rs:1103:17:1103:18 | x7 | T | file://:0:0:0:0 | & | +| main.rs:1103:17:1103:18 | x7 | T.&T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1103:17:1103:23 | x7.m1() | | file://:0:0:0:0 | & | +| main.rs:1103:17:1103:23 | x7.m1() | &T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1104:18:1104:23 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1104:26:1104:27 | x7 | | main.rs:1052:5:1053:19 | S | +| main.rs:1104:26:1104:27 | x7 | T | file://:0:0:0:0 | & | +| main.rs:1104:26:1104:27 | x7 | T.&T | main.rs:1055:5:1056:14 | S2 | +| main.rs:1111:16:1111:20 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:1111:16:1111:20 | SelfParam | &T | main.rs:1109:5:1117:5 | Self [trait MyTrait] | | main.rs:1114:16:1114:20 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:1114:16:1114:20 | SelfParam | &T | main.rs:1111:5:1111:26 | MyStruct | -| main.rs:1114:16:1114:20 | SelfParam | &T.T | main.rs:1113:10:1113:10 | T | +| main.rs:1114:16:1114:20 | SelfParam | &T | main.rs:1109:5:1117:5 | Self [trait MyTrait] | | main.rs:1114:32:1116:9 | { ... } | | file://:0:0:0:0 | & | -| main.rs:1114:32:1116:9 | { ... } | &T | main.rs:1111:5:1111:26 | MyStruct | -| main.rs:1114:32:1116:9 | { ... } | &T.T | main.rs:1113:10:1113:10 | T | +| main.rs:1114:32:1116:9 | { ... } | &T | main.rs:1109:5:1117:5 | Self [trait MyTrait] | | main.rs:1115:13:1115:16 | self | | file://:0:0:0:0 | & | -| main.rs:1115:13:1115:16 | self | &T | main.rs:1111:5:1111:26 | MyStruct | -| main.rs:1115:13:1115:16 | self | &T.T | main.rs:1113:10:1113:10 | T | -| main.rs:1120:13:1120:13 | x | | main.rs:1111:5:1111:26 | MyStruct | -| main.rs:1120:13:1120:13 | x | T | main.rs:1109:5:1109:13 | S | -| main.rs:1120:17:1120:27 | MyStruct(...) | | main.rs:1111:5:1111:26 | MyStruct | -| main.rs:1120:17:1120:27 | MyStruct(...) | T | main.rs:1109:5:1109:13 | S | -| main.rs:1120:26:1120:26 | S | | main.rs:1109:5:1109:13 | S | -| main.rs:1121:9:1121:9 | x | | main.rs:1111:5:1111:26 | MyStruct | -| main.rs:1121:9:1121:9 | x | T | main.rs:1109:5:1109:13 | S | -| main.rs:1121:9:1121:15 | x.foo() | | file://:0:0:0:0 | & | -| main.rs:1121:9:1121:15 | x.foo() | &T | main.rs:1111:5:1111:26 | MyStruct | -| main.rs:1121:9:1121:15 | x.foo() | &T.T | main.rs:1109:5:1109:13 | S | -| main.rs:1129:15:1129:19 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:1129:15:1129:19 | SelfParam | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1129:31:1131:9 | { ... } | | file://:0:0:0:0 | & | -| main.rs:1129:31:1131:9 | { ... } | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1130:13:1130:19 | &... | | file://:0:0:0:0 | & | -| main.rs:1130:13:1130:19 | &... | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1130:14:1130:19 | &... | | file://:0:0:0:0 | & | -| main.rs:1130:14:1130:19 | &... | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1130:15:1130:19 | &self | | file://:0:0:0:0 | & | -| main.rs:1130:15:1130:19 | &self | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1130:16:1130:19 | self | | file://:0:0:0:0 | & | -| main.rs:1130:16:1130:19 | self | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1133:15:1133:25 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:1133:15:1133:25 | SelfParam | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1133:37:1135:9 | { ... } | | file://:0:0:0:0 | & | -| main.rs:1133:37:1135:9 | { ... } | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1134:13:1134:19 | &... | | file://:0:0:0:0 | & | -| main.rs:1134:13:1134:19 | &... | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1134:14:1134:19 | &... | | file://:0:0:0:0 | & | -| main.rs:1134:14:1134:19 | &... | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1134:15:1134:19 | &self | | file://:0:0:0:0 | & | -| main.rs:1134:15:1134:19 | &self | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1134:16:1134:19 | self | | file://:0:0:0:0 | & | -| main.rs:1134:16:1134:19 | self | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1137:15:1137:15 | x | | file://:0:0:0:0 | & | -| main.rs:1137:15:1137:15 | x | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1137:34:1139:9 | { ... } | | file://:0:0:0:0 | & | -| main.rs:1137:34:1139:9 | { ... } | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1138:13:1138:13 | x | | file://:0:0:0:0 | & | -| main.rs:1138:13:1138:13 | x | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1141:15:1141:15 | x | | file://:0:0:0:0 | & | -| main.rs:1141:15:1141:15 | x | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1141:34:1143:9 | { ... } | | file://:0:0:0:0 | & | -| main.rs:1141:34:1143:9 | { ... } | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1142:13:1142:16 | &... | | file://:0:0:0:0 | & | -| main.rs:1142:13:1142:16 | &... | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1142:14:1142:16 | &... | | file://:0:0:0:0 | & | -| main.rs:1142:14:1142:16 | &... | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1142:15:1142:16 | &x | | file://:0:0:0:0 | & | -| main.rs:1142:15:1142:16 | &x | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1142:16:1142:16 | x | | file://:0:0:0:0 | & | -| main.rs:1142:16:1142:16 | x | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1147:13:1147:13 | x | | main.rs:1126:5:1126:13 | S | -| main.rs:1147:17:1147:20 | S {...} | | main.rs:1126:5:1126:13 | S | -| main.rs:1148:9:1148:9 | x | | main.rs:1126:5:1126:13 | S | -| main.rs:1148:9:1148:14 | x.f1() | | file://:0:0:0:0 | & | -| main.rs:1148:9:1148:14 | x.f1() | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1149:9:1149:9 | x | | main.rs:1126:5:1126:13 | S | -| main.rs:1149:9:1149:14 | x.f2() | | file://:0:0:0:0 | & | -| main.rs:1149:9:1149:14 | x.f2() | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1150:9:1150:17 | ...::f3(...) | | file://:0:0:0:0 | & | -| main.rs:1150:9:1150:17 | ...::f3(...) | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1150:15:1150:16 | &x | | file://:0:0:0:0 | & | -| main.rs:1150:15:1150:16 | &x | &T | main.rs:1126:5:1126:13 | S | -| main.rs:1150:16:1150:16 | x | | main.rs:1126:5:1126:13 | S | -| main.rs:1164:43:1167:5 | { ... } | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1164:43:1167:5 | { ... } | E | main.rs:1157:5:1158:14 | S1 | -| main.rs:1164:43:1167:5 | { ... } | T | main.rs:1157:5:1158:14 | S1 | -| main.rs:1165:13:1165:13 | x | | main.rs:1157:5:1158:14 | S1 | -| main.rs:1165:17:1165:30 | ...::Ok(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1165:17:1165:30 | ...::Ok(...) | T | main.rs:1157:5:1158:14 | S1 | -| main.rs:1165:17:1165:31 | TryExpr | | main.rs:1157:5:1158:14 | S1 | -| main.rs:1165:28:1165:29 | S1 | | main.rs:1157:5:1158:14 | S1 | -| main.rs:1166:9:1166:22 | ...::Ok(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1166:9:1166:22 | ...::Ok(...) | E | main.rs:1157:5:1158:14 | S1 | -| main.rs:1166:9:1166:22 | ...::Ok(...) | T | main.rs:1157:5:1158:14 | S1 | -| main.rs:1166:20:1166:21 | S1 | | main.rs:1157:5:1158:14 | S1 | -| main.rs:1170:46:1174:5 | { ... } | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1170:46:1174:5 | { ... } | E | main.rs:1160:5:1161:14 | S2 | -| main.rs:1170:46:1174:5 | { ... } | T | main.rs:1157:5:1158:14 | S1 | -| main.rs:1171:13:1171:13 | x | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1171:13:1171:13 | x | T | main.rs:1157:5:1158:14 | S1 | -| main.rs:1171:17:1171:30 | ...::Ok(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1171:17:1171:30 | ...::Ok(...) | T | main.rs:1157:5:1158:14 | S1 | -| main.rs:1171:28:1171:29 | S1 | | main.rs:1157:5:1158:14 | S1 | -| main.rs:1172:13:1172:13 | y | | main.rs:1157:5:1158:14 | S1 | -| main.rs:1172:17:1172:17 | x | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1172:17:1172:17 | x | T | main.rs:1157:5:1158:14 | S1 | -| main.rs:1172:17:1172:18 | TryExpr | | main.rs:1157:5:1158:14 | S1 | -| main.rs:1173:9:1173:22 | ...::Ok(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1173:9:1173:22 | ...::Ok(...) | E | main.rs:1160:5:1161:14 | S2 | -| main.rs:1173:9:1173:22 | ...::Ok(...) | T | main.rs:1157:5:1158:14 | S1 | -| main.rs:1173:20:1173:21 | S1 | | main.rs:1157:5:1158:14 | S1 | -| main.rs:1177:40:1182:5 | { ... } | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1177:40:1182:5 | { ... } | E | main.rs:1160:5:1161:14 | S2 | -| main.rs:1177:40:1182:5 | { ... } | T | main.rs:1157:5:1158:14 | S1 | -| main.rs:1178:13:1178:13 | x | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1178:13:1178:13 | x | T | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1178:13:1178:13 | x | T.T | main.rs:1157:5:1158:14 | S1 | -| main.rs:1178:17:1178:42 | ...::Ok(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1178:17:1178:42 | ...::Ok(...) | T | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1178:17:1178:42 | ...::Ok(...) | T.T | main.rs:1157:5:1158:14 | S1 | -| main.rs:1178:28:1178:41 | ...::Ok(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1178:28:1178:41 | ...::Ok(...) | T | main.rs:1157:5:1158:14 | S1 | -| main.rs:1178:39:1178:40 | S1 | | main.rs:1157:5:1158:14 | S1 | -| main.rs:1180:17:1180:17 | x | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1180:17:1180:17 | x | T | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1180:17:1180:17 | x | T.T | main.rs:1157:5:1158:14 | S1 | -| main.rs:1180:17:1180:18 | TryExpr | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1180:17:1180:18 | TryExpr | T | main.rs:1157:5:1158:14 | S1 | -| main.rs:1180:17:1180:29 | ... .map(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1181:9:1181:22 | ...::Ok(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1181:9:1181:22 | ...::Ok(...) | E | main.rs:1160:5:1161:14 | S2 | -| main.rs:1181:9:1181:22 | ...::Ok(...) | T | main.rs:1157:5:1158:14 | S1 | -| main.rs:1181:20:1181:21 | S1 | | main.rs:1157:5:1158:14 | S1 | -| main.rs:1185:30:1185:34 | input | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1185:30:1185:34 | input | E | main.rs:1157:5:1158:14 | S1 | -| main.rs:1185:30:1185:34 | input | T | main.rs:1185:20:1185:27 | T | -| main.rs:1185:69:1192:5 | { ... } | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1185:69:1192:5 | { ... } | E | main.rs:1157:5:1158:14 | S1 | -| main.rs:1185:69:1192:5 | { ... } | T | main.rs:1185:20:1185:27 | T | -| main.rs:1186:13:1186:17 | value | | main.rs:1185:20:1185:27 | T | -| main.rs:1186:21:1186:25 | input | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1186:21:1186:25 | input | E | main.rs:1157:5:1158:14 | S1 | -| main.rs:1186:21:1186:25 | input | T | main.rs:1185:20:1185:27 | T | -| main.rs:1186:21:1186:26 | TryExpr | | main.rs:1185:20:1185:27 | T | -| main.rs:1187:22:1187:38 | ...::Ok(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1187:22:1187:38 | ...::Ok(...) | T | main.rs:1185:20:1185:27 | T | -| main.rs:1187:22:1190:10 | ... .and_then(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1187:33:1187:37 | value | | main.rs:1185:20:1185:27 | T | -| main.rs:1187:53:1190:9 | { ... } | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1187:53:1190:9 | { ... } | E | main.rs:1157:5:1158:14 | S1 | -| main.rs:1188:22:1188:27 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:1189:13:1189:34 | ...::Ok::<...>(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1189:13:1189:34 | ...::Ok::<...>(...) | E | main.rs:1157:5:1158:14 | S1 | -| main.rs:1191:9:1191:23 | ...::Err(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1191:9:1191:23 | ...::Err(...) | E | main.rs:1157:5:1158:14 | S1 | -| main.rs:1191:9:1191:23 | ...::Err(...) | T | main.rs:1185:20:1185:27 | T | -| main.rs:1191:21:1191:22 | S1 | | main.rs:1157:5:1158:14 | S1 | -| main.rs:1195:37:1195:52 | try_same_error(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1195:37:1195:52 | try_same_error(...) | E | main.rs:1157:5:1158:14 | S1 | -| main.rs:1195:37:1195:52 | try_same_error(...) | T | main.rs:1157:5:1158:14 | S1 | -| main.rs:1196:22:1196:27 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:1199:37:1199:55 | try_convert_error(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1199:37:1199:55 | try_convert_error(...) | E | main.rs:1160:5:1161:14 | S2 | -| main.rs:1199:37:1199:55 | try_convert_error(...) | T | main.rs:1157:5:1158:14 | S1 | -| main.rs:1200:22:1200:27 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:1203:37:1203:49 | try_chained(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1203:37:1203:49 | try_chained(...) | E | main.rs:1160:5:1161:14 | S2 | -| main.rs:1203:37:1203:49 | try_chained(...) | T | main.rs:1157:5:1158:14 | S1 | -| main.rs:1204:22:1204:27 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:1207:37:1207:63 | try_complex(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1207:37:1207:63 | try_complex(...) | E | main.rs:1157:5:1158:14 | S1 | -| main.rs:1207:37:1207:63 | try_complex(...) | T | main.rs:1157:5:1158:14 | S1 | -| main.rs:1207:49:1207:62 | ...::Ok(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | -| main.rs:1207:49:1207:62 | ...::Ok(...) | E | main.rs:1157:5:1158:14 | S1 | -| main.rs:1207:49:1207:62 | ...::Ok(...) | T | main.rs:1157:5:1158:14 | S1 | -| main.rs:1207:60:1207:61 | S1 | | main.rs:1157:5:1158:14 | S1 | -| main.rs:1208:22:1208:27 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:1215:13:1215:13 | x | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1215:22:1215:22 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1216:13:1216:13 | y | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1216:17:1216:17 | 2 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1217:17:1217:17 | x | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1217:21:1217:21 | y | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1218:13:1218:13 | z | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1218:17:1218:17 | x | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1218:17:1218:23 | x.abs() | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1219:13:1219:13 | c | | file:///BUILTINS/types.rs:6:1:7:16 | char | -| main.rs:1219:17:1219:19 | 'c' | | file:///BUILTINS/types.rs:6:1:7:16 | char | -| main.rs:1220:13:1220:17 | hello | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:1220:21:1220:27 | "Hello" | | file:///BUILTINS/types.rs:8:1:8:15 | str | -| main.rs:1221:13:1221:13 | f | | file:///BUILTINS/types.rs:25:1:25:15 | f64 | -| main.rs:1221:17:1221:24 | 123.0f64 | | file:///BUILTINS/types.rs:25:1:25:15 | f64 | -| main.rs:1222:13:1222:13 | t | | file:///BUILTINS/types.rs:3:1:5:16 | bool | -| main.rs:1222:17:1222:20 | true | | file:///BUILTINS/types.rs:3:1:5:16 | bool | -| main.rs:1223:13:1223:13 | f | | file:///BUILTINS/types.rs:3:1:5:16 | bool | -| main.rs:1223:17:1223:21 | false | | file:///BUILTINS/types.rs:3:1:5:16 | bool | -| main.rs:1229:13:1229:13 | x | | file:///BUILTINS/types.rs:3:1:5:16 | bool | -| main.rs:1229:17:1229:20 | true | | file:///BUILTINS/types.rs:3:1:5:16 | bool | -| main.rs:1229:17:1229:29 | ... && ... | | file:///BUILTINS/types.rs:3:1:5:16 | bool | -| main.rs:1229:25:1229:29 | false | | file:///BUILTINS/types.rs:3:1:5:16 | bool | -| main.rs:1230:13:1230:13 | y | | file:///BUILTINS/types.rs:3:1:5:16 | bool | -| main.rs:1230:17:1230:20 | true | | file:///BUILTINS/types.rs:3:1:5:16 | bool | -| main.rs:1230:17:1230:29 | ... \|\| ... | | file:///BUILTINS/types.rs:3:1:5:16 | bool | -| main.rs:1230:25:1230:29 | false | | file:///BUILTINS/types.rs:3:1:5:16 | bool | -| main.rs:1232:13:1232:17 | mut a | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1233:12:1233:13 | 34 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1233:18:1233:19 | 33 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1234:17:1234:17 | z | | file://:0:0:0:0 | () | -| main.rs:1234:21:1234:27 | (...) | | file://:0:0:0:0 | () | -| main.rs:1234:22:1234:22 | a | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1234:22:1234:26 | ... = ... | | file://:0:0:0:0 | () | -| main.rs:1234:26:1234:26 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1236:13:1236:13 | a | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1236:13:1236:17 | ... = ... | | file://:0:0:0:0 | () | -| main.rs:1236:17:1236:17 | 2 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1238:9:1238:9 | a | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | -| main.rs:1244:5:1244:20 | ...::f(...) | | main.rs:67:5:67:21 | Foo | -| main.rs:1245:5:1245:60 | ...::g(...) | | main.rs:67:5:67:21 | Foo | -| main.rs:1245:20:1245:38 | ...::Foo {...} | | main.rs:67:5:67:21 | Foo | -| main.rs:1245:41:1245:59 | ...::Foo {...} | | main.rs:67:5:67:21 | Foo | +| main.rs:1115:13:1115:16 | self | &T | main.rs:1109:5:1117:5 | Self [trait MyTrait] | +| main.rs:1115:13:1115:22 | self.foo() | | file://:0:0:0:0 | & | +| main.rs:1115:13:1115:22 | self.foo() | &T | main.rs:1109:5:1117:5 | Self [trait MyTrait] | +| main.rs:1123:16:1123:20 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:1123:16:1123:20 | SelfParam | &T | main.rs:1119:5:1119:20 | MyStruct | +| main.rs:1123:36:1125:9 | { ... } | | file://:0:0:0:0 | & | +| main.rs:1123:36:1125:9 | { ... } | &T | main.rs:1119:5:1119:20 | MyStruct | +| main.rs:1124:13:1124:16 | self | | file://:0:0:0:0 | & | +| main.rs:1124:13:1124:16 | self | &T | main.rs:1119:5:1119:20 | MyStruct | +| main.rs:1129:13:1129:13 | x | | main.rs:1119:5:1119:20 | MyStruct | +| main.rs:1129:17:1129:24 | MyStruct | | main.rs:1119:5:1119:20 | MyStruct | +| main.rs:1130:9:1130:9 | x | | main.rs:1119:5:1119:20 | MyStruct | +| main.rs:1130:9:1130:15 | x.bar() | | file://:0:0:0:0 | & | +| main.rs:1130:9:1130:15 | x.bar() | &T | main.rs:1119:5:1119:20 | MyStruct | +| main.rs:1140:16:1140:20 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:1140:16:1140:20 | SelfParam | &T | main.rs:1137:5:1137:26 | MyStruct | +| main.rs:1140:16:1140:20 | SelfParam | &T.T | main.rs:1139:10:1139:10 | T | +| main.rs:1140:32:1142:9 | { ... } | | file://:0:0:0:0 | & | +| main.rs:1140:32:1142:9 | { ... } | &T | main.rs:1137:5:1137:26 | MyStruct | +| main.rs:1140:32:1142:9 | { ... } | &T.T | main.rs:1139:10:1139:10 | T | +| main.rs:1141:13:1141:16 | self | | file://:0:0:0:0 | & | +| main.rs:1141:13:1141:16 | self | &T | main.rs:1137:5:1137:26 | MyStruct | +| main.rs:1141:13:1141:16 | self | &T.T | main.rs:1139:10:1139:10 | T | +| main.rs:1146:13:1146:13 | x | | main.rs:1137:5:1137:26 | MyStruct | +| main.rs:1146:13:1146:13 | x | T | main.rs:1135:5:1135:13 | S | +| main.rs:1146:17:1146:27 | MyStruct(...) | | main.rs:1137:5:1137:26 | MyStruct | +| main.rs:1146:17:1146:27 | MyStruct(...) | T | main.rs:1135:5:1135:13 | S | +| main.rs:1146:26:1146:26 | S | | main.rs:1135:5:1135:13 | S | +| main.rs:1147:9:1147:9 | x | | main.rs:1137:5:1137:26 | MyStruct | +| main.rs:1147:9:1147:9 | x | T | main.rs:1135:5:1135:13 | S | +| main.rs:1147:9:1147:15 | x.foo() | | file://:0:0:0:0 | & | +| main.rs:1147:9:1147:15 | x.foo() | &T | main.rs:1137:5:1137:26 | MyStruct | +| main.rs:1147:9:1147:15 | x.foo() | &T.T | main.rs:1135:5:1135:13 | S | +| main.rs:1155:15:1155:19 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:1155:15:1155:19 | SelfParam | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1155:31:1157:9 | { ... } | | file://:0:0:0:0 | & | +| main.rs:1155:31:1157:9 | { ... } | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1156:13:1156:19 | &... | | file://:0:0:0:0 | & | +| main.rs:1156:13:1156:19 | &... | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1156:14:1156:19 | &... | | file://:0:0:0:0 | & | +| main.rs:1156:14:1156:19 | &... | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1156:15:1156:19 | &self | | file://:0:0:0:0 | & | +| main.rs:1156:15:1156:19 | &self | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1156:16:1156:19 | self | | file://:0:0:0:0 | & | +| main.rs:1156:16:1156:19 | self | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1159:15:1159:25 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:1159:15:1159:25 | SelfParam | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1159:37:1161:9 | { ... } | | file://:0:0:0:0 | & | +| main.rs:1159:37:1161:9 | { ... } | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1160:13:1160:19 | &... | | file://:0:0:0:0 | & | +| main.rs:1160:13:1160:19 | &... | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1160:14:1160:19 | &... | | file://:0:0:0:0 | & | +| main.rs:1160:14:1160:19 | &... | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1160:15:1160:19 | &self | | file://:0:0:0:0 | & | +| main.rs:1160:15:1160:19 | &self | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1160:16:1160:19 | self | | file://:0:0:0:0 | & | +| main.rs:1160:16:1160:19 | self | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1163:15:1163:15 | x | | file://:0:0:0:0 | & | +| main.rs:1163:15:1163:15 | x | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1163:34:1165:9 | { ... } | | file://:0:0:0:0 | & | +| main.rs:1163:34:1165:9 | { ... } | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1164:13:1164:13 | x | | file://:0:0:0:0 | & | +| main.rs:1164:13:1164:13 | x | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1167:15:1167:15 | x | | file://:0:0:0:0 | & | +| main.rs:1167:15:1167:15 | x | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1167:34:1169:9 | { ... } | | file://:0:0:0:0 | & | +| main.rs:1167:34:1169:9 | { ... } | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1168:13:1168:16 | &... | | file://:0:0:0:0 | & | +| main.rs:1168:13:1168:16 | &... | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1168:14:1168:16 | &... | | file://:0:0:0:0 | & | +| main.rs:1168:14:1168:16 | &... | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1168:15:1168:16 | &x | | file://:0:0:0:0 | & | +| main.rs:1168:15:1168:16 | &x | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1168:16:1168:16 | x | | file://:0:0:0:0 | & | +| main.rs:1168:16:1168:16 | x | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1173:13:1173:13 | x | | main.rs:1152:5:1152:13 | S | +| main.rs:1173:17:1173:20 | S {...} | | main.rs:1152:5:1152:13 | S | +| main.rs:1174:9:1174:9 | x | | main.rs:1152:5:1152:13 | S | +| main.rs:1174:9:1174:14 | x.f1() | | file://:0:0:0:0 | & | +| main.rs:1174:9:1174:14 | x.f1() | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1175:9:1175:9 | x | | main.rs:1152:5:1152:13 | S | +| main.rs:1175:9:1175:14 | x.f2() | | file://:0:0:0:0 | & | +| main.rs:1175:9:1175:14 | x.f2() | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1176:9:1176:17 | ...::f3(...) | | file://:0:0:0:0 | & | +| main.rs:1176:9:1176:17 | ...::f3(...) | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1176:15:1176:16 | &x | | file://:0:0:0:0 | & | +| main.rs:1176:15:1176:16 | &x | &T | main.rs:1152:5:1152:13 | S | +| main.rs:1176:16:1176:16 | x | | main.rs:1152:5:1152:13 | S | +| main.rs:1190:43:1193:5 | { ... } | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1190:43:1193:5 | { ... } | E | main.rs:1183:5:1184:14 | S1 | +| main.rs:1190:43:1193:5 | { ... } | T | main.rs:1183:5:1184:14 | S1 | +| main.rs:1191:13:1191:13 | x | | main.rs:1183:5:1184:14 | S1 | +| main.rs:1191:17:1191:30 | ...::Ok(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1191:17:1191:30 | ...::Ok(...) | T | main.rs:1183:5:1184:14 | S1 | +| main.rs:1191:17:1191:31 | TryExpr | | main.rs:1183:5:1184:14 | S1 | +| main.rs:1191:28:1191:29 | S1 | | main.rs:1183:5:1184:14 | S1 | +| main.rs:1192:9:1192:22 | ...::Ok(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1192:9:1192:22 | ...::Ok(...) | E | main.rs:1183:5:1184:14 | S1 | +| main.rs:1192:9:1192:22 | ...::Ok(...) | T | main.rs:1183:5:1184:14 | S1 | +| main.rs:1192:20:1192:21 | S1 | | main.rs:1183:5:1184:14 | S1 | +| main.rs:1196:46:1200:5 | { ... } | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1196:46:1200:5 | { ... } | E | main.rs:1186:5:1187:14 | S2 | +| main.rs:1196:46:1200:5 | { ... } | T | main.rs:1183:5:1184:14 | S1 | +| main.rs:1197:13:1197:13 | x | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1197:13:1197:13 | x | T | main.rs:1183:5:1184:14 | S1 | +| main.rs:1197:17:1197:30 | ...::Ok(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1197:17:1197:30 | ...::Ok(...) | T | main.rs:1183:5:1184:14 | S1 | +| main.rs:1197:28:1197:29 | S1 | | main.rs:1183:5:1184:14 | S1 | +| main.rs:1198:13:1198:13 | y | | main.rs:1183:5:1184:14 | S1 | +| main.rs:1198:17:1198:17 | x | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1198:17:1198:17 | x | T | main.rs:1183:5:1184:14 | S1 | +| main.rs:1198:17:1198:18 | TryExpr | | main.rs:1183:5:1184:14 | S1 | +| main.rs:1199:9:1199:22 | ...::Ok(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1199:9:1199:22 | ...::Ok(...) | E | main.rs:1186:5:1187:14 | S2 | +| main.rs:1199:9:1199:22 | ...::Ok(...) | T | main.rs:1183:5:1184:14 | S1 | +| main.rs:1199:20:1199:21 | S1 | | main.rs:1183:5:1184:14 | S1 | +| main.rs:1203:40:1208:5 | { ... } | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1203:40:1208:5 | { ... } | E | main.rs:1186:5:1187:14 | S2 | +| main.rs:1203:40:1208:5 | { ... } | T | main.rs:1183:5:1184:14 | S1 | +| main.rs:1204:13:1204:13 | x | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1204:13:1204:13 | x | T | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1204:13:1204:13 | x | T.T | main.rs:1183:5:1184:14 | S1 | +| main.rs:1204:17:1204:42 | ...::Ok(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1204:17:1204:42 | ...::Ok(...) | T | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1204:17:1204:42 | ...::Ok(...) | T.T | main.rs:1183:5:1184:14 | S1 | +| main.rs:1204:28:1204:41 | ...::Ok(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1204:28:1204:41 | ...::Ok(...) | T | main.rs:1183:5:1184:14 | S1 | +| main.rs:1204:39:1204:40 | S1 | | main.rs:1183:5:1184:14 | S1 | +| main.rs:1206:17:1206:17 | x | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1206:17:1206:17 | x | T | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1206:17:1206:17 | x | T.T | main.rs:1183:5:1184:14 | S1 | +| main.rs:1206:17:1206:18 | TryExpr | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1206:17:1206:18 | TryExpr | T | main.rs:1183:5:1184:14 | S1 | +| main.rs:1206:17:1206:29 | ... .map(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1207:9:1207:22 | ...::Ok(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1207:9:1207:22 | ...::Ok(...) | E | main.rs:1186:5:1187:14 | S2 | +| main.rs:1207:9:1207:22 | ...::Ok(...) | T | main.rs:1183:5:1184:14 | S1 | +| main.rs:1207:20:1207:21 | S1 | | main.rs:1183:5:1184:14 | S1 | +| main.rs:1211:30:1211:34 | input | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1211:30:1211:34 | input | E | main.rs:1183:5:1184:14 | S1 | +| main.rs:1211:30:1211:34 | input | T | main.rs:1211:20:1211:27 | T | +| main.rs:1211:69:1218:5 | { ... } | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1211:69:1218:5 | { ... } | E | main.rs:1183:5:1184:14 | S1 | +| main.rs:1211:69:1218:5 | { ... } | T | main.rs:1211:20:1211:27 | T | +| main.rs:1212:13:1212:17 | value | | main.rs:1211:20:1211:27 | T | +| main.rs:1212:21:1212:25 | input | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1212:21:1212:25 | input | E | main.rs:1183:5:1184:14 | S1 | +| main.rs:1212:21:1212:25 | input | T | main.rs:1211:20:1211:27 | T | +| main.rs:1212:21:1212:26 | TryExpr | | main.rs:1211:20:1211:27 | T | +| main.rs:1213:22:1213:38 | ...::Ok(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1213:22:1213:38 | ...::Ok(...) | T | main.rs:1211:20:1211:27 | T | +| main.rs:1213:22:1216:10 | ... .and_then(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1213:33:1213:37 | value | | main.rs:1211:20:1211:27 | T | +| main.rs:1213:53:1216:9 | { ... } | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1213:53:1216:9 | { ... } | E | main.rs:1183:5:1184:14 | S1 | +| main.rs:1214:22:1214:27 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1215:13:1215:34 | ...::Ok::<...>(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1215:13:1215:34 | ...::Ok::<...>(...) | E | main.rs:1183:5:1184:14 | S1 | +| main.rs:1217:9:1217:23 | ...::Err(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1217:9:1217:23 | ...::Err(...) | E | main.rs:1183:5:1184:14 | S1 | +| main.rs:1217:9:1217:23 | ...::Err(...) | T | main.rs:1211:20:1211:27 | T | +| main.rs:1217:21:1217:22 | S1 | | main.rs:1183:5:1184:14 | S1 | +| main.rs:1221:37:1221:52 | try_same_error(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1221:37:1221:52 | try_same_error(...) | E | main.rs:1183:5:1184:14 | S1 | +| main.rs:1221:37:1221:52 | try_same_error(...) | T | main.rs:1183:5:1184:14 | S1 | +| main.rs:1222:22:1222:27 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1225:37:1225:55 | try_convert_error(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1225:37:1225:55 | try_convert_error(...) | E | main.rs:1186:5:1187:14 | S2 | +| main.rs:1225:37:1225:55 | try_convert_error(...) | T | main.rs:1183:5:1184:14 | S1 | +| main.rs:1226:22:1226:27 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1229:37:1229:49 | try_chained(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1229:37:1229:49 | try_chained(...) | E | main.rs:1186:5:1187:14 | S2 | +| main.rs:1229:37:1229:49 | try_chained(...) | T | main.rs:1183:5:1184:14 | S1 | +| main.rs:1230:22:1230:27 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1233:37:1233:63 | try_complex(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1233:37:1233:63 | try_complex(...) | E | main.rs:1183:5:1184:14 | S1 | +| main.rs:1233:37:1233:63 | try_complex(...) | T | main.rs:1183:5:1184:14 | S1 | +| main.rs:1233:49:1233:62 | ...::Ok(...) | | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/core/src/result.rs:520:1:538:1 | Result | +| main.rs:1233:49:1233:62 | ...::Ok(...) | E | main.rs:1183:5:1184:14 | S1 | +| main.rs:1233:49:1233:62 | ...::Ok(...) | T | main.rs:1183:5:1184:14 | S1 | +| main.rs:1233:60:1233:61 | S1 | | main.rs:1183:5:1184:14 | S1 | +| main.rs:1234:22:1234:27 | "{:?}\\n" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1241:13:1241:13 | x | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1241:22:1241:22 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1242:13:1242:13 | y | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1242:17:1242:17 | 2 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1243:17:1243:17 | x | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1243:21:1243:21 | y | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1244:13:1244:13 | z | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1244:17:1244:17 | x | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1244:17:1244:23 | x.abs() | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1245:13:1245:13 | c | | file:///BUILTINS/types.rs:6:1:7:16 | char | +| main.rs:1245:17:1245:19 | 'c' | | file:///BUILTINS/types.rs:6:1:7:16 | char | +| main.rs:1246:13:1246:17 | hello | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1246:21:1246:27 | "Hello" | | file:///BUILTINS/types.rs:8:1:8:15 | str | +| main.rs:1247:13:1247:13 | f | | file:///BUILTINS/types.rs:25:1:25:15 | f64 | +| main.rs:1247:17:1247:24 | 123.0f64 | | file:///BUILTINS/types.rs:25:1:25:15 | f64 | +| main.rs:1248:13:1248:13 | t | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:1248:17:1248:20 | true | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:1249:13:1249:13 | f | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:1249:17:1249:21 | false | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:1255:13:1255:13 | x | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:1255:17:1255:20 | true | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:1255:17:1255:29 | ... && ... | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:1255:25:1255:29 | false | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:1256:13:1256:13 | y | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:1256:17:1256:20 | true | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:1256:17:1256:29 | ... \|\| ... | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:1256:25:1256:29 | false | | file:///BUILTINS/types.rs:3:1:5:16 | bool | +| main.rs:1258:13:1258:17 | mut a | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1259:12:1259:13 | 34 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1259:18:1259:19 | 33 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1260:17:1260:17 | z | | file://:0:0:0:0 | () | +| main.rs:1260:21:1260:27 | (...) | | file://:0:0:0:0 | () | +| main.rs:1260:22:1260:22 | a | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1260:22:1260:26 | ... = ... | | file://:0:0:0:0 | () | +| main.rs:1260:26:1260:26 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1262:13:1262:13 | a | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1262:13:1262:17 | ... = ... | | file://:0:0:0:0 | () | +| main.rs:1262:17:1262:17 | 2 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1264:9:1264:9 | a | | file:///BUILTINS/types.rs:12:1:12:15 | i32 | +| main.rs:1270:5:1270:20 | ...::f(...) | | main.rs:67:5:67:21 | Foo | +| main.rs:1271:5:1271:60 | ...::g(...) | | main.rs:67:5:67:21 | Foo | +| main.rs:1271:20:1271:38 | ...::Foo {...} | | main.rs:67:5:67:21 | Foo | +| main.rs:1271:41:1271:59 | ...::Foo {...} | | main.rs:67:5:67:21 | Foo | From e778cbe768cb0efae57e198d3ba444aa76b44a31 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Sat, 24 May 2025 10:01:33 +0200 Subject: [PATCH 50/86] Rust: Resolve function calls to traits methods --- .../rust/elements/internal/CallExprImpl.qll | 10 +- .../elements/internal/MethodCallExprImpl.qll | 41 +-- .../codeql/rust/internal/TypeInference.qll | 261 ++++++++++++------ .../dataflow/global/inline-flow.expected | 42 +++ .../library-tests/dataflow/global/main.rs | 4 +- .../dataflow/global/viableCallable.expected | 3 + .../test/library-tests/type-inference/main.rs | 2 +- .../type-inference/type-inference.ql | 2 +- 8 files changed, 240 insertions(+), 125 deletions(-) diff --git a/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll index 944185cf122..e9ec4339d1a 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll @@ -14,6 +14,7 @@ private import codeql.rust.elements.PathExpr module Impl { private import rust private import codeql.rust.internal.PathResolution as PathResolution + private import codeql.rust.internal.TypeInference as TypeInference pragma[nomagic] Path getFunctionPath(CallExpr ce) { result = ce.getFunction().(PathExpr).getPath() } @@ -36,7 +37,14 @@ module Impl { class CallExpr extends Generated::CallExpr { override string toStringImpl() { result = this.getFunction().toAbbreviatedString() + "(...)" } - override Callable getStaticTarget() { result = getResolvedFunction(this) } + override Callable getStaticTarget() { + // If this call is to a trait method, e.g., `Trait::foo(bar)`, then check + // if type inference can resolve it to the correct trait implementation. + result = TypeInference::resolveMethodCallTarget(this) + or + not exists(TypeInference::resolveMethodCallTarget(this)) and + result = getResolvedFunction(this) + } /** Gets the struct that this call resolves to, if any. */ Struct getStruct() { result = getResolvedFunction(this) } diff --git a/rust/ql/lib/codeql/rust/elements/internal/MethodCallExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/MethodCallExprImpl.qll index 4996da37d90..1141ade4bd6 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/MethodCallExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/MethodCallExprImpl.qll @@ -14,14 +14,6 @@ private import codeql.rust.internal.TypeInference * be referenced directly. */ module Impl { - private predicate isInherentImplFunction(Function f) { - f = any(Impl impl | not impl.hasTrait()).(ImplItemNode).getAnAssocItem() - } - - private predicate isTraitImplFunction(Function f) { - f = any(Impl impl | impl.hasTrait()).(ImplItemNode).getAnAssocItem() - } - // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A method call expression. For example: @@ -31,38 +23,7 @@ module Impl { * ``` */ class MethodCallExpr extends Generated::MethodCallExpr { - private Function getStaticTargetFrom(boolean fromSource) { - result = resolveMethodCallExpr(this) and - (if result.fromSource() then fromSource = true else fromSource = false) and - ( - // prioritize inherent implementation methods first - isInherentImplFunction(result) - or - not isInherentImplFunction(resolveMethodCallExpr(this)) and - ( - // then trait implementation methods - isTraitImplFunction(result) - or - not isTraitImplFunction(resolveMethodCallExpr(this)) and - ( - // then trait methods with default implementations - result.hasBody() - or - // and finally trait methods without default implementations - not resolveMethodCallExpr(this).hasBody() - ) - ) - ) - } - - override Function getStaticTarget() { - // Functions in source code also gets extracted as library code, due to - // this duplication we prioritize functions from source code. - result = this.getStaticTargetFrom(true) - or - not exists(this.getStaticTargetFrom(true)) and - result = this.getStaticTargetFrom(false) - } + override Function getStaticTarget() { result = resolveMethodCallTarget(this) } private string toStringPart(int index) { index = 0 and diff --git a/rust/ql/lib/codeql/rust/internal/TypeInference.qll b/rust/ql/lib/codeql/rust/internal/TypeInference.qll index 5bc137252fd..8cff1635b93 100644 --- a/rust/ql/lib/codeql/rust/internal/TypeInference.qll +++ b/rust/ql/lib/codeql/rust/internal/TypeInference.qll @@ -678,7 +678,7 @@ private module CallExprBaseMatchingInput implements MatchingInputSig { Declaration getTarget() { result = CallExprImpl::getResolvedFunction(this) or - result = resolveMethodCallExpr(this) // mutual recursion; resolving method calls requires resolving types and vice versa + result = inferMethodCallTarget(this) // mutual recursion; resolving method calls requires resolving types and vice versa } } @@ -1000,6 +1000,150 @@ private StructType inferLiteralType(LiteralExpr le) { ) } +private module MethodCall { + /** An expression that calls a method. */ + abstract private class MethodCallImpl extends Expr { + /** Gets the name of the method targeted. */ + abstract string getMethodName(); + + /** Gets the number of arguments _excluding_ the `self` argument. */ + abstract int getArity(); + + /** Gets the trait targeted by this method call, if any. */ + Trait getTrait() { none() } + + /** Gets the type of the receiver of the method call at `path`. */ + abstract Type getTypeAt(TypePath path); + } + + final class MethodCall = MethodCallImpl; + + private class MethodCallExprMethodCall extends MethodCallImpl instanceof MethodCallExpr { + override string getMethodName() { result = super.getIdentifier().getText() } + + override int getArity() { result = super.getArgList().getNumberOfArgs() } + + pragma[nomagic] + override Type getTypeAt(TypePath path) { + exists(TypePath path0 | result = inferType(super.getReceiver(), path0) | + path0.isCons(TRefTypeParameter(), path) + or + not path0.isCons(TRefTypeParameter(), _) and + not (path0.isEmpty() and result = TRefType()) and + path = path0 + ) + } + } + + private class CallExprMethodCall extends MethodCallImpl instanceof CallExpr { + TraitItemNode trait; + string methodName; + Expr receiver; + + CallExprMethodCall() { + receiver = this.getArgList().getArg(0) and + exists(Path path, Function f | + path = this.getFunction().(PathExpr).getPath() and + f = resolvePath(path) and + f.getParamList().hasSelfParam() and + trait = resolvePath(path.getQualifier()) and + trait.getAnAssocItem() = f and + path.getSegment().getIdentifier().getText() = methodName + ) + } + + override string getMethodName() { result = methodName } + + override int getArity() { result = super.getArgList().getNumberOfArgs() - 1 } + + override Trait getTrait() { result = trait } + + pragma[nomagic] + override Type getTypeAt(TypePath path) { result = inferType(receiver, path) } + } +} + +import MethodCall + +/** + * Holds if a method for `type` with the name `name` and the arity `arity` + * exists in `impl`. + */ +private predicate methodCandidate(Type type, string name, int arity, Impl impl) { + type = impl.getSelfTy().(TypeMention).resolveType() and + exists(Function f | + f = impl.(ImplItemNode).getASuccessor(name) and + f.getParamList().hasSelfParam() and + arity = f.getParamList().getNumberOfParams() + ) +} + +/** + * Holds if a method for `type` for `trait` with the name `name` and the arity + * `arity` exists in `impl`. + */ +pragma[nomagic] +private predicate methodCandidateTrait(Type type, Trait trait, string name, int arity, Impl impl) { + trait = resolvePath(impl.getTrait().(PathTypeRepr).getPath()) and + methodCandidate(type, name, arity, impl) +} + +private module IsInstantiationOfInput implements IsInstantiationOfInputSig { + pragma[nomagic] + predicate potentialInstantiationOf(MethodCall mc, TypeAbstraction impl, TypeMention constraint) { + exists(Type rootType, string name, int arity | + rootType = mc.getTypeAt(TypePath::nil()) and + name = mc.getMethodName() and + arity = mc.getArity() and + constraint = impl.(ImplTypeAbstraction).getSelfTy() + | + methodCandidateTrait(rootType, mc.getTrait(), name, arity, impl) + or + not exists(mc.getTrait()) and + methodCandidate(rootType, name, arity, impl) + ) + } + + predicate relevantTypeMention(TypeMention constraint) { + exists(Impl impl | methodCandidate(_, _, _, impl) and constraint = impl.getSelfTy()) + } +} + +bindingset[item, name] +pragma[inline_late] +private Function getMethodSuccessor(ItemNode item, string name) { + result = item.getASuccessor(name) +} + +bindingset[tp, name] +pragma[inline_late] +private Function getTypeParameterMethod(TypeParameter tp, string name) { + result = getMethodSuccessor(tp.(TypeParamTypeParameter).getTypeParam(), name) + or + result = getMethodSuccessor(tp.(SelfTypeParameter).getTrait(), name) +} + +/** Gets a method from an `impl` block that matches the method call `mc`. */ +private Function getMethodFromImpl(MethodCall mc) { + exists(Impl impl | + IsInstantiationOf::isInstantiationOf(mc, impl, _) and + result = getMethodSuccessor(impl, mc.getMethodName()) + ) +} + +/** + * Gets a method that the method call `mc` resolves to based on type inference, + * if any. + */ +private Function inferMethodCallTarget(MethodCall mc) { + // The method comes from an `impl` block targeting the type of the receiver. + result = getMethodFromImpl(mc) + or + // The type of the receiver is a type parameter and the method comes from a + // trait bound on the type parameter. + result = getTypeParameterMethod(mc.getTypeAt(TypePath::nil()), mc.getMethodName()) +} + cached private module Cached { private import codeql.rust.internal.CachedStages @@ -1026,92 +1170,49 @@ private module Cached { ) } - private class ReceiverExpr extends Expr { - MethodCallExpr mce; - - ReceiverExpr() { mce.getReceiver() = this } - - string getField() { result = mce.getIdentifier().getText() } - - int getNumberOfArgs() { result = mce.getArgList().getNumberOfArgs() } - - pragma[nomagic] - Type getTypeAt(TypePath path) { - exists(TypePath path0 | result = inferType(this, path0) | - path0.isCons(TRefTypeParameter(), path) - or - not path0.isCons(TRefTypeParameter(), _) and - not (path0.isEmpty() and result = TRefType()) and - path = path0 - ) - } + private predicate isInherentImplFunction(Function f) { + f = any(Impl impl | not impl.hasTrait()).(ImplItemNode).getAnAssocItem() } - /** Holds if a method for `type` with the name `name` and the arity `arity` exists in `impl`. */ - pragma[nomagic] - private predicate methodCandidate(Type type, string name, int arity, Impl impl) { - type = impl.getSelfTy().(TypeReprMention).resolveType() and - exists(Function f | - f = impl.(ImplItemNode).getASuccessor(name) and - f.getParamList().hasSelfParam() and - arity = f.getParamList().getNumberOfParams() - ) + private predicate isTraitImplFunction(Function f) { + f = any(Impl impl | impl.hasTrait()).(ImplItemNode).getAnAssocItem() } - private module IsInstantiationOfInput implements IsInstantiationOfInputSig { - pragma[nomagic] - predicate potentialInstantiationOf( - ReceiverExpr receiver, TypeAbstraction impl, TypeMention constraint - ) { - methodCandidate(receiver.getTypeAt(TypePath::nil()), receiver.getField(), - receiver.getNumberOfArgs(), impl) and - constraint = impl.(ImplTypeAbstraction).getSelfTy() - } - - predicate relevantTypeMention(TypeMention constraint) { - exists(Impl impl | methodCandidate(_, _, _, impl) and constraint = impl.getSelfTy()) - } - } - - bindingset[item, name] - pragma[inline_late] - private Function getMethodSuccessor(ItemNode item, string name) { - result = item.getASuccessor(name) - } - - bindingset[tp, name] - pragma[inline_late] - private Function getTypeParameterMethod(TypeParameter tp, string name) { - result = getMethodSuccessor(tp.(TypeParamTypeParameter).getTypeParam(), name) - or - result = getMethodSuccessor(tp.(SelfTypeParameter).getTrait(), name) - } - - /** - * Gets the method from an `impl` block with an implementing type that matches - * the type of `receiver` and with a name of the method call in which - * `receiver` occurs, if any. - */ - private Function getMethodFromImpl(ReceiverExpr receiver) { - exists(Impl impl | - IsInstantiationOf::isInstantiationOf(receiver, impl, _) and - result = getMethodSuccessor(impl, receiver.getField()) - ) - } - - /** Gets a method that the method call `mce` resolves to, if any. */ - cached - Function resolveMethodCallExpr(MethodCallExpr mce) { - exists(ReceiverExpr receiver | mce.getReceiver() = receiver | - // The method comes from an `impl` block targeting the type of `receiver`. - result = getMethodFromImpl(receiver) + private Function resolveMethodCallTargetFrom(MethodCall mc, boolean fromSource) { + result = inferMethodCallTarget(mc) and + (if result.fromSource() then fromSource = true else fromSource = false) and + ( + // prioritize inherent implementation methods first + isInherentImplFunction(result) or - // The type of `receiver` is a type parameter and the method comes from a - // trait bound on the type parameter. - result = getTypeParameterMethod(receiver.getTypeAt(TypePath::nil()), receiver.getField()) + not isInherentImplFunction(inferMethodCallTarget(mc)) and + ( + // then trait implementation methods + isTraitImplFunction(result) + or + not isTraitImplFunction(inferMethodCallTarget(mc)) and + ( + // then trait methods with default implementations + result.hasBody() + or + // and finally trait methods without default implementations + not inferMethodCallTarget(mc).hasBody() + ) + ) ) } + /** Gets a method that the method call `mc` resolves to, if any. */ + cached + Function resolveMethodCallTarget(MethodCall mc) { + // Functions in source code also gets extracted as library code, due to + // this duplication we prioritize functions from source code. + result = resolveMethodCallTargetFrom(mc, true) + or + not exists(resolveMethodCallTargetFrom(mc, true)) and + result = resolveMethodCallTargetFrom(mc, false) + } + pragma[inline] private Type inferRootTypeDeref(AstNode n) { result = inferType(n) and @@ -1243,6 +1344,6 @@ private module Debug { Function debugResolveMethodCallExpr(MethodCallExpr mce) { mce = getRelevantLocatable() and - result = resolveMethodCallExpr(mce) + result = resolveMethodCallTarget(mce) } } diff --git a/rust/ql/test/library-tests/dataflow/global/inline-flow.expected b/rust/ql/test/library-tests/dataflow/global/inline-flow.expected index ec838732cd5..c64956c59a0 100644 --- a/rust/ql/test/library-tests/dataflow/global/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/global/inline-flow.expected @@ -92,6 +92,24 @@ edges | main.rs:188:9:188:9 | d [MyInt] | main.rs:189:10:189:10 | d [MyInt] | provenance | | | main.rs:188:13:188:20 | a.add(...) [MyInt] | main.rs:188:9:188:9 | d [MyInt] | provenance | | | main.rs:189:10:189:10 | d [MyInt] | main.rs:189:10:189:16 | d.value | provenance | | +| main.rs:201:18:201:21 | SelfParam [MyInt] | main.rs:201:48:203:5 | { ... } [MyInt] | provenance | | +| main.rs:205:26:205:37 | ...: MyInt [MyInt] | main.rs:205:49:207:5 | { ... } [MyInt] | provenance | | +| main.rs:211:9:211:9 | a [MyInt] | main.rs:213:49:213:49 | a [MyInt] | provenance | | +| main.rs:211:13:211:38 | MyInt {...} [MyInt] | main.rs:211:9:211:9 | a [MyInt] | provenance | | +| main.rs:211:28:211:36 | source(...) | main.rs:211:13:211:38 | MyInt {...} [MyInt] | provenance | | +| main.rs:213:9:213:26 | MyInt {...} [MyInt] | main.rs:213:24:213:24 | c | provenance | | +| main.rs:213:24:213:24 | c | main.rs:214:10:214:10 | c | provenance | | +| main.rs:213:30:213:53 | ...::take_self(...) [MyInt] | main.rs:213:9:213:26 | MyInt {...} [MyInt] | provenance | | +| main.rs:213:49:213:49 | a [MyInt] | main.rs:201:18:201:21 | SelfParam [MyInt] | provenance | | +| main.rs:213:49:213:49 | a [MyInt] | main.rs:213:30:213:53 | ...::take_self(...) [MyInt] | provenance | | +| main.rs:217:9:217:9 | b [MyInt] | main.rs:218:54:218:54 | b [MyInt] | provenance | | +| main.rs:217:13:217:39 | MyInt {...} [MyInt] | main.rs:217:9:217:9 | b [MyInt] | provenance | | +| main.rs:217:28:217:37 | source(...) | main.rs:217:13:217:39 | MyInt {...} [MyInt] | provenance | | +| main.rs:218:9:218:26 | MyInt {...} [MyInt] | main.rs:218:24:218:24 | c | provenance | | +| main.rs:218:24:218:24 | c | main.rs:219:10:219:10 | c | provenance | | +| main.rs:218:30:218:55 | ...::take_second(...) [MyInt] | main.rs:218:9:218:26 | MyInt {...} [MyInt] | provenance | | +| main.rs:218:54:218:54 | b [MyInt] | main.rs:205:26:205:37 | ...: MyInt [MyInt] | provenance | | +| main.rs:218:54:218:54 | b [MyInt] | main.rs:218:30:218:55 | ...::take_second(...) [MyInt] | provenance | | | main.rs:227:32:231:1 | { ... } | main.rs:246:41:246:54 | async_source(...) | provenance | | | main.rs:228:9:228:9 | a | main.rs:227:32:231:1 | { ... } | provenance | | | main.rs:228:9:228:9 | a | main.rs:229:10:229:10 | a | provenance | | @@ -202,6 +220,26 @@ nodes | main.rs:188:13:188:20 | a.add(...) [MyInt] | semmle.label | a.add(...) [MyInt] | | main.rs:189:10:189:10 | d [MyInt] | semmle.label | d [MyInt] | | main.rs:189:10:189:16 | d.value | semmle.label | d.value | +| main.rs:201:18:201:21 | SelfParam [MyInt] | semmle.label | SelfParam [MyInt] | +| main.rs:201:48:203:5 | { ... } [MyInt] | semmle.label | { ... } [MyInt] | +| main.rs:205:26:205:37 | ...: MyInt [MyInt] | semmle.label | ...: MyInt [MyInt] | +| main.rs:205:49:207:5 | { ... } [MyInt] | semmle.label | { ... } [MyInt] | +| main.rs:211:9:211:9 | a [MyInt] | semmle.label | a [MyInt] | +| main.rs:211:13:211:38 | MyInt {...} [MyInt] | semmle.label | MyInt {...} [MyInt] | +| main.rs:211:28:211:36 | source(...) | semmle.label | source(...) | +| main.rs:213:9:213:26 | MyInt {...} [MyInt] | semmle.label | MyInt {...} [MyInt] | +| main.rs:213:24:213:24 | c | semmle.label | c | +| main.rs:213:30:213:53 | ...::take_self(...) [MyInt] | semmle.label | ...::take_self(...) [MyInt] | +| main.rs:213:49:213:49 | a [MyInt] | semmle.label | a [MyInt] | +| main.rs:214:10:214:10 | c | semmle.label | c | +| main.rs:217:9:217:9 | b [MyInt] | semmle.label | b [MyInt] | +| main.rs:217:13:217:39 | MyInt {...} [MyInt] | semmle.label | MyInt {...} [MyInt] | +| main.rs:217:28:217:37 | source(...) | semmle.label | source(...) | +| main.rs:218:9:218:26 | MyInt {...} [MyInt] | semmle.label | MyInt {...} [MyInt] | +| main.rs:218:24:218:24 | c | semmle.label | c | +| main.rs:218:30:218:55 | ...::take_second(...) [MyInt] | semmle.label | ...::take_second(...) [MyInt] | +| main.rs:218:54:218:54 | b [MyInt] | semmle.label | b [MyInt] | +| main.rs:219:10:219:10 | c | semmle.label | c | | main.rs:227:32:231:1 | { ... } | semmle.label | { ... } | | main.rs:228:9:228:9 | a | semmle.label | a | | main.rs:228:13:228:21 | source(...) | semmle.label | source(...) | @@ -225,6 +263,8 @@ subpaths | main.rs:143:38:143:38 | a | main.rs:106:27:106:32 | ...: i64 | main.rs:106:42:112:5 | { ... } | main.rs:143:13:143:39 | ...::data_through(...) | | main.rs:161:24:161:33 | source(...) | main.rs:155:12:155:17 | ...: i64 | main.rs:155:28:157:5 | { ... } [MyInt] | main.rs:161:13:161:34 | ...::new(...) [MyInt] | | main.rs:186:9:186:9 | a [MyInt] | main.rs:169:12:169:15 | SelfParam [MyInt] | main.rs:169:42:172:5 | { ... } [MyInt] | main.rs:188:13:188:20 | a.add(...) [MyInt] | +| main.rs:213:49:213:49 | a [MyInt] | main.rs:201:18:201:21 | SelfParam [MyInt] | main.rs:201:48:203:5 | { ... } [MyInt] | main.rs:213:30:213:53 | ...::take_self(...) [MyInt] | +| main.rs:218:54:218:54 | b [MyInt] | main.rs:205:26:205:37 | ...: MyInt [MyInt] | main.rs:205:49:207:5 | { ... } [MyInt] | main.rs:218:30:218:55 | ...::take_second(...) [MyInt] | testFailures #select | main.rs:18:10:18:10 | a | main.rs:13:5:13:13 | source(...) | main.rs:18:10:18:10 | a | $@ | main.rs:13:5:13:13 | source(...) | source(...) | @@ -241,6 +281,8 @@ testFailures | main.rs:144:10:144:10 | b | main.rs:142:13:142:22 | source(...) | main.rs:144:10:144:10 | b | $@ | main.rs:142:13:142:22 | source(...) | source(...) | | main.rs:163:10:163:10 | m | main.rs:161:24:161:33 | source(...) | main.rs:163:10:163:10 | m | $@ | main.rs:161:24:161:33 | source(...) | source(...) | | main.rs:189:10:189:16 | d.value | main.rs:186:28:186:36 | source(...) | main.rs:189:10:189:16 | d.value | $@ | main.rs:186:28:186:36 | source(...) | source(...) | +| main.rs:214:10:214:10 | c | main.rs:211:28:211:36 | source(...) | main.rs:214:10:214:10 | c | $@ | main.rs:211:28:211:36 | source(...) | source(...) | +| main.rs:219:10:219:10 | c | main.rs:217:28:217:37 | source(...) | main.rs:219:10:219:10 | c | $@ | main.rs:217:28:217:37 | source(...) | source(...) | | main.rs:229:10:229:10 | a | main.rs:228:13:228:21 | source(...) | main.rs:229:10:229:10 | a | $@ | main.rs:228:13:228:21 | source(...) | source(...) | | main.rs:239:14:239:14 | c | main.rs:238:17:238:25 | source(...) | main.rs:239:14:239:14 | c | $@ | main.rs:238:17:238:25 | source(...) | source(...) | | main.rs:247:10:247:10 | a | main.rs:228:13:228:21 | source(...) | main.rs:247:10:247:10 | a | $@ | main.rs:228:13:228:21 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/global/main.rs b/rust/ql/test/library-tests/dataflow/global/main.rs index a28a8e03084..507772692d6 100644 --- a/rust/ql/test/library-tests/dataflow/global/main.rs +++ b/rust/ql/test/library-tests/dataflow/global/main.rs @@ -211,12 +211,12 @@ fn data_through_trait_method_called_as_function() { let a = MyInt { value: source(8) }; let b = MyInt { value: 2 }; let MyInt { value: c } = MyTrait::take_self(a, b); - sink(c); // $ MISSING: hasValueFlow=8 + sink(c); // $ hasValueFlow=8 let a = MyInt { value: 0 }; let b = MyInt { value: source(37) }; let MyInt { value: c } = MyTrait::take_second(a, b); - sink(c); // $ MISSING: hasValueFlow=37 + sink(c); // $ hasValueFlow=37 let a = MyInt { value: 0 }; let b = MyInt { value: source(38) }; diff --git a/rust/ql/test/library-tests/dataflow/global/viableCallable.expected b/rust/ql/test/library-tests/dataflow/global/viableCallable.expected index 76e65eea387..63abc4c7f41 100644 --- a/rust/ql/test/library-tests/dataflow/global/viableCallable.expected +++ b/rust/ql/test/library-tests/dataflow/global/viableCallable.expected @@ -48,10 +48,13 @@ | main.rs:188:13:188:20 | a.add(...) | main.rs:169:5:172:5 | fn add | | main.rs:189:5:189:17 | sink(...) | main.rs:5:1:7:1 | fn sink | | main.rs:211:28:211:36 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:213:30:213:53 | ...::take_self(...) | main.rs:201:5:203:5 | fn take_self | | main.rs:214:5:214:11 | sink(...) | main.rs:5:1:7:1 | fn sink | | main.rs:217:28:217:37 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:218:30:218:55 | ...::take_second(...) | main.rs:205:5:207:5 | fn take_second | | main.rs:219:5:219:11 | sink(...) | main.rs:5:1:7:1 | fn sink | | main.rs:222:28:222:37 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:223:30:223:53 | ...::take_self(...) | main.rs:201:5:203:5 | fn take_self | | main.rs:224:5:224:11 | sink(...) | main.rs:5:1:7:1 | fn sink | | main.rs:228:13:228:21 | source(...) | main.rs:1:1:3:1 | fn source | | main.rs:229:5:229:11 | sink(...) | main.rs:5:1:7:1 | fn sink | diff --git a/rust/ql/test/library-tests/type-inference/main.rs b/rust/ql/test/library-tests/type-inference/main.rs index 48964f9fb37..9f0056522b6 100644 --- a/rust/ql/test/library-tests/type-inference/main.rs +++ b/rust/ql/test/library-tests/type-inference/main.rs @@ -112,7 +112,7 @@ mod trait_impl { let a = x.trait_method(); // $ type=a:bool method=MyThing::trait_method let y = MyThing { field: false }; - let b = MyTrait::trait_method(y); // $ type=b:bool MISSING: method=MyThing::trait_method + let b = MyTrait::trait_method(y); // $ type=b:bool method=MyThing::trait_method } } diff --git a/rust/ql/test/library-tests/type-inference/type-inference.ql b/rust/ql/test/library-tests/type-inference/type-inference.ql index 94d8ee23796..cea5839c6ad 100644 --- a/rust/ql/test/library-tests/type-inference/type-inference.ql +++ b/rust/ql/test/library-tests/type-inference/type-inference.ql @@ -43,7 +43,7 @@ module ResolveTest implements TestSig { source.fromSource() and not source.isFromMacroExpansion() | - target = source.(MethodCallExpr).getStaticTarget() and + target = resolveMethodCallTarget(source) and functionHasValue(target, value) and tag = "method" or From bb9c72f889791cceef62074ede02edc9fbfb1d2a Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Sun, 25 May 2025 21:13:18 +0200 Subject: [PATCH 51/86] Swift: Update to Swift 6.1.1 --- swift/third_party/load.bzl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/swift/third_party/load.bzl b/swift/third_party/load.bzl index d19345a1880..ad05960e7f6 100644 --- a/swift/third_party/load.bzl +++ b/swift/third_party/load.bzl @@ -5,6 +5,10 @@ load("//misc/bazel:lfs.bzl", "lfs_archive", "lfs_files") _override = { # these are used to test new artifacts. Must be empty before merging to main + "swift-prebuilt-macOS-swift-6.1.1-RELEASE-108.tar.zst": "2aaf6e7083c27a561d7212f88b3e15cbeb2bdf1d2363d310227d278937a4c2c9", + "swift-prebuilt-Linux-swift-6.1.1-RELEASE-108.tar.zst": "31cba2387c7e1ce4e73743935b0db65ea69fccf5c07bd2b392fd6815f5dffca5", + "resource-dir-macOS-swift-6.1.1-RELEASE-115.zip": "84e34d6af45883fe6d0103c2f36bbff3069ac068e671cb62d0d01d16e087362d", + "resource-dir-Linux-swift-6.1.1-RELEASE-115.zip": "1e00a730a93b85a5ba478590218e1f769792ec56501977cc72d941101c5c3657", } _staging_url = "https://github.com/dsp-testing/codeql-swift-artifacts/releases/download/staging-{}/{}" From 27fd7c48faf5214c5576c18a9dfe8d2373fde502 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Mon, 26 May 2025 10:03:43 +0200 Subject: [PATCH 52/86] Swift: Update macOS runner --- .github/workflows/swift.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml index 4af46d302ac..df610a96702 100644 --- a/.github/workflows/swift.yml +++ b/.github/workflows/swift.yml @@ -32,7 +32,7 @@ jobs: if: github.repository_owner == 'github' strategy: matrix: - runner: [ubuntu-latest, macos-13-xlarge] + runner: [ubuntu-latest, macos-15-xlarge] fail-fast: false runs-on: ${{ matrix.runner }} steps: From 37024ade85bb73a443b216406fb9d315a94f0440 Mon Sep 17 00:00:00 2001 From: Napalys Klicius Date: Mon, 26 May 2025 10:22:33 +0200 Subject: [PATCH 53/86] JS: Move query suite selector logic to `javascript-security-and-quality.qls` --- .../javascript-security-and-quality.qls | 144 +++++++++++++++++- 1 file changed, 142 insertions(+), 2 deletions(-) diff --git a/javascript/ql/src/codeql-suites/javascript-security-and-quality.qls b/javascript/ql/src/codeql-suites/javascript-security-and-quality.qls index fe0fb9b6f34..d02a016f058 100644 --- a/javascript/ql/src/codeql-suites/javascript-security-and-quality.qls +++ b/javascript/ql/src/codeql-suites/javascript-security-and-quality.qls @@ -1,4 +1,144 @@ - description: Security-and-quality queries for JavaScript - queries: . -- apply: security-and-quality-selectors.yml - from: codeql/suite-helpers +- include: + kind: + - problem + - path-problem + precision: + - high + - very-high + tags contain: + - security +- include: + kind: + - problem + - path-problem + precision: medium + problem.severity: + - error + - warning + tags contain: + - security +- include: + id: + - js/node/assignment-to-exports-variable + - js/node/missing-exports-qualifier + - js/angular/duplicate-dependency + - js/angular/missing-explicit-injection + - js/angular/dependency-injection-mismatch + - js/angular/incompatible-service + - js/angular/expression-in-url-attribute + - js/angular/repeated-dependency-injection + - js/regex/back-reference-to-negative-lookahead + - js/regex/unmatchable-dollar + - js/regex/empty-character-class + - js/regex/back-reference-before-group + - js/regex/unbound-back-reference + - js/regex/always-matches + - js/regex/unmatchable-caret + - js/regex/duplicate-in-character-class + - js/vue/arrow-method-on-vue-instance + - js/conditional-comment + - js/superfluous-trailing-arguments + - js/illegal-invocation + - js/invalid-prototype-value + - js/incomplete-object-initialization + - js/useless-type-test + - js/template-syntax-in-string-literal + - js/with-statement + - js/property-assignment-on-primitive + - js/deletion-of-non-property + - js/setter-return + - js/index-out-of-bounds + - js/unused-index-variable + - js/non-standard-language-feature + - js/syntax-error + - js/for-in-comprehension + - js/strict-mode-call-stack-introspection + - js/automatic-semicolon-insertion + - js/inconsistent-use-of-new + - js/non-linear-pattern + - js/yield-outside-generator + - js/mixed-static-instance-this-access + - js/arguments-redefinition + - js/nested-function-reference-in-default-parameter + - js/duplicate-parameter-name + - js/unreachable-method-overloads + - js/duplicate-variable-declaration + - js/function-declaration-conflict + - js/ineffective-parameter-type + - js/assignment-to-constant + - js/use-before-declaration + - js/suspicious-method-name-declaration + - js/overwritten-property + - js/useless-assignment-to-local + - js/useless-assignment-to-property + - js/variable-initialization-conflict + - js/variable-use-in-temporal-dead-zone + - js/missing-variable-declaration + - js/missing-this-qualifier + - js/unused-local-variable + - js/label-in-switch + - js/ignore-array-result + - js/inconsistent-loop-direction + - js/unreachable-statement + - js/trivial-conditional + - js/useless-comparison-test + - js/misleading-indentation-of-dangling-else + - js/use-of-returnless-function + - js/useless-assignment-in-return + - js/loop-iteration-skipped-due-to-shifting + - js/misleading-indentation-after-control-statement + - js/unused-loop-variable + - js/implicit-operand-conversion + - js/whitespace-contradicts-precedence + - js/missing-space-in-concatenation + - js/unbound-event-handler-receiver + - js/shift-out-of-range + - js/missing-dot-length-in-comparison + - js/redundant-operation + - js/comparison-with-nan + - js/duplicate-property + - js/unclear-operator-precedence + - js/unknown-directive + - js/string-instead-of-regex + - js/unneeded-defensive-code + - js/duplicate-switch-case + - js/duplicate-condition + - js/useless-expression + - js/redundant-assignment + - js/misspelled-variable-name + - js/call-to-non-callable + - js/missing-await + - js/comparison-between-incompatible-types + - js/property-access-on-non-object + - js/malformed-html-id + - js/eval-like-call + - js/duplicate-html-attribute + - js/react/unsupported-state-update-in-lifecycle-method + - js/react/unused-or-undefined-state-property + - js/react/direct-state-mutation + - js/react/inconsistent-state-update + - js/diagnostics/extraction-errors + - js/diagnostics/successfully-extracted-files + - js/summary/lines-of-code + - js/summary/lines-of-user-code +- include: + kind: + - diagnostic +- include: + kind: + - metric + tags contain: + - summary +- exclude: + deprecated: // +- exclude: + query path: + - /^experimental\/.*/ + - Metrics/Summaries/FrameworkCoverage.ql + - /Diagnostics/Internal/.*/ +- exclude: + tags contain: + - modeleditor + - modelgenerator From ba7726462fb695d5b28280572d15cccd1eb73f3d Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 26 May 2025 12:17:25 +0200 Subject: [PATCH 54/86] Rust: Also include prelude path resolution in Core --- rust/ql/lib/codeql/rust/internal/PathResolution.qll | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll index 8764869a152..ca05b0fba7d 100644 --- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll +++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll @@ -1413,7 +1413,7 @@ private predicate useImportEdge(Use use, string name, ItemNode item) { */ private predicate preludeEdge(SourceFile f, string name, ItemNode i) { exists(Crate core, ModuleLikeNode mod, ModuleItemNode prelude, ModuleItemNode rust | - f = any(Crate c0 | core = c0.getDependency(_)).getASourceFile() and + f = any(Crate c0 | core = c0.getDependency(_) or core = c0).getASourceFile() and core.getName() = "core" and mod = core.getSourceFile() and prelude = mod.getASuccessorRec("prelude") and @@ -1438,8 +1438,8 @@ private module Debug { private Locatable getRelevantLocatable() { exists(string filepath, int startline, int startcolumn, int endline, int endcolumn | result.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and - filepath.matches("%/term.rs") and - startline = [71] + filepath.matches("%/test.rs") and + startline = 74 ) } From a749cf934ae87caf773a10e386ca4b45605b1ad2 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 26 May 2025 14:15:56 +0200 Subject: [PATCH 55/86] Rust: accept test changes --- rust/ql/integration-tests/macro-expansion/summary.expected | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/integration-tests/macro-expansion/summary.expected b/rust/ql/integration-tests/macro-expansion/summary.expected index 529d1736d02..6917d67b1cf 100644 --- a/rust/ql/integration-tests/macro-expansion/summary.expected +++ b/rust/ql/integration-tests/macro-expansion/summary.expected @@ -9,7 +9,7 @@ | Inconsistencies - Path resolution | 0 | | Inconsistencies - SSA | 0 | | Inconsistencies - data flow | 0 | -| Lines of code extracted | 46 | +| Lines of code extracted | 29 | | Lines of user code extracted | 29 | | Macro calls - resolved | 52 | | Macro calls - total | 53 | From 0ce06e88188df1d0301374a09608b3253eaca78e Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Mon, 26 May 2025 15:12:33 +0200 Subject: [PATCH 56/86] Rust: Use member predicate from path resolution --- rust/ql/lib/codeql/rust/internal/TypeInference.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/lib/codeql/rust/internal/TypeInference.qll b/rust/ql/lib/codeql/rust/internal/TypeInference.qll index 8cff1635b93..ca5c65f38ef 100644 --- a/rust/ql/lib/codeql/rust/internal/TypeInference.qll +++ b/rust/ql/lib/codeql/rust/internal/TypeInference.qll @@ -1084,7 +1084,7 @@ private predicate methodCandidate(Type type, string name, int arity, Impl impl) */ pragma[nomagic] private predicate methodCandidateTrait(Type type, Trait trait, string name, int arity, Impl impl) { - trait = resolvePath(impl.getTrait().(PathTypeRepr).getPath()) and + trait = resolvePath(impl.(ImplItemNode).getTraitPath()) and methodCandidate(type, name, arity, impl) } From b4d2fb45ab7b7e90f07d6dfb09153b90a83bd591 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Mon, 26 May 2025 16:22:20 +0200 Subject: [PATCH 57/86] Swift: Fix type string representation --- swift/extractor/translators/ExprTranslator.cpp | 4 +++- .../generated/expr/TypeValueExpr/TypeValueExpr.expected | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/swift/extractor/translators/ExprTranslator.cpp b/swift/extractor/translators/ExprTranslator.cpp index 30cca659a8c..15a6765e5fc 100644 --- a/swift/extractor/translators/ExprTranslator.cpp +++ b/swift/extractor/translators/ExprTranslator.cpp @@ -691,7 +691,9 @@ codeql::CurrentContextIsolationExpr ExprTranslator::translateCurrentContextIsola codeql::TypeValueExpr ExprTranslator::translateTypeValueExpr(const swift::TypeValueExpr& expr) { auto entry = createExprEntry(expr); - entry.type_repr = dispatcher.fetchLabel(expr.getParamTypeRepr()); + if (expr.getParamTypeRepr() && expr.getParamType()) { + entry.type_repr = dispatcher.fetchLabel(expr.getParamTypeRepr(), expr.getParamType()); + } return entry; } diff --git a/swift/ql/test/extractor-tests/generated/expr/TypeValueExpr/TypeValueExpr.expected b/swift/ql/test/extractor-tests/generated/expr/TypeValueExpr/TypeValueExpr.expected index fa57faafb19..685ff810fcf 100644 --- a/swift/ql/test/extractor-tests/generated/expr/TypeValueExpr/TypeValueExpr.expected +++ b/swift/ql/test/extractor-tests/generated/expr/TypeValueExpr/TypeValueExpr.expected @@ -1,2 +1,2 @@ -| type_value_exprs.swift:4:13:4:13 | TypeValueExpr | hasType: | yes | getTypeRepr: | type_value_exprs.swift:4:13:4:13 | (no string representation) | -| type_value_exprs.swift:5:13:5:13 | TypeValueExpr | hasType: | yes | getTypeRepr: | type_value_exprs.swift:5:13:5:13 | (no string representation) | +| type_value_exprs.swift:4:13:4:13 | TypeValueExpr | hasType: | yes | getTypeRepr: | type_value_exprs.swift:4:13:4:13 | N | +| type_value_exprs.swift:5:13:5:13 | TypeValueExpr | hasType: | yes | getTypeRepr: | type_value_exprs.swift:5:13:5:13 | N | From f17076e212187e3f0c601f706bfd9612474000eb Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Mon, 26 May 2025 16:41:05 +0200 Subject: [PATCH 58/86] Swift: Update expected test results --- swift/ql/test/library-tests/ast/Errors.expected | 2 -- swift/ql/test/library-tests/ast/Missing.expected | 2 -- swift/ql/test/library-tests/ast/PrintAst.expected | 6 ++---- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/swift/ql/test/library-tests/ast/Errors.expected b/swift/ql/test/library-tests/ast/Errors.expected index e6ccf071851..e69de29bb2d 100644 --- a/swift/ql/test/library-tests/ast/Errors.expected +++ b/swift/ql/test/library-tests/ast/Errors.expected @@ -1,2 +0,0 @@ -| cfg.swift:591:13:591:13 | missing type from TypeRepr | UnspecifiedElement | -| cfg.swift:595:13:595:13 | missing type from TypeRepr | UnspecifiedElement | diff --git a/swift/ql/test/library-tests/ast/Missing.expected b/swift/ql/test/library-tests/ast/Missing.expected index 1966db9b890..e69de29bb2d 100644 --- a/swift/ql/test/library-tests/ast/Missing.expected +++ b/swift/ql/test/library-tests/ast/Missing.expected @@ -1,2 +0,0 @@ -| cfg.swift:591:13:591:13 | missing type from TypeRepr | -| cfg.swift:595:13:595:13 | missing type from TypeRepr | diff --git a/swift/ql/test/library-tests/ast/PrintAst.expected b/swift/ql/test/library-tests/ast/PrintAst.expected index 248401ac814..f0383c005c3 100644 --- a/swift/ql/test/library-tests/ast/PrintAst.expected +++ b/swift/ql/test/library-tests/ast/PrintAst.expected @@ -3552,7 +3552,7 @@ cfg.swift: # 590| getGenericTypeParam(0): [GenericTypeParamDecl] N # 591| getMember(0): [PatternBindingDecl] var ... = ... # 591| getInit(0): [TypeValueExpr] TypeValueExpr -# 591| getTypeRepr(): (no string representation) +# 591| getTypeRepr(): [TypeRepr] N # 591| getPattern(0): [NamedPattern] x # 591| getMember(1): [ConcreteVarDecl] x # 591| Type = Int @@ -3596,7 +3596,6 @@ cfg.swift: # 590| Type = ValueGenericsStruct # 590| getBody(): [BraceStmt] { ... } # 590| getElement(0): [ReturnStmt] return -# 591| [UnspecifiedElement] missing type from TypeRepr # 594| [NamedFunction] valueGenericsFn(_:) # 594| InterfaceType = (ValueGenericsStruct) -> () # 594| getGenericTypeParam(0): [GenericTypeParamDecl] N @@ -3607,7 +3606,7 @@ cfg.swift: # 595| Type = Int # 595| getElement(0): [PatternBindingDecl] var ... = ... # 595| getInit(0): [TypeValueExpr] TypeValueExpr -# 595| getTypeRepr(): (no string representation) +# 595| getTypeRepr(): [TypeRepr] N # 595| getPattern(0): [NamedPattern] x # 596| getElement(1): [CallExpr] call to print(_:separator:terminator:) # 596| getFunction(): [DeclRefExpr] print(_:separator:terminator:) @@ -3624,7 +3623,6 @@ cfg.swift: # 597| getElement(2): [AssignExpr] ... = ... # 597| getDest(): [DiscardAssignmentExpr] _ # 597| getSource(): [DeclRefExpr] value -# 595| [UnspecifiedElement] missing type from TypeRepr declarations.swift: # 1| [StructDecl] Foo # 2| getMember(0): [PatternBindingDecl] var ... = ... From 765afdbae0a9464a9dda609944c196af542a7453 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Mon, 26 May 2025 18:21:35 +0200 Subject: [PATCH 59/86] Rust: add option to extract dependencies as source files --- rust/codeql-extractor.yml | 8 ++++++++ rust/extractor/src/config.rs | 1 + rust/extractor/src/main.rs | 15 +++++++++++++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/rust/codeql-extractor.yml b/rust/codeql-extractor.yml index 1c73a070e58..0ba77ee88d1 100644 --- a/rust/codeql-extractor.yml +++ b/rust/codeql-extractor.yml @@ -82,3 +82,11 @@ options: title: Skip path resolution description: > Skip path resolution. This is experimental, while we move path resolution from the extractor to the QL library. + type: string + pattern: "^(false|true)$" + extract_dependencies_as_source: + title: Extract dependencies as source code + description: > + Extract the full source code of dependencies instead of only extracting signatures. + type: string + pattern: "^(false|true)$" diff --git a/rust/extractor/src/config.rs b/rust/extractor/src/config.rs index e66d54807be..3f6b86d1f1f 100644 --- a/rust/extractor/src/config.rs +++ b/rust/extractor/src/config.rs @@ -67,6 +67,7 @@ pub struct Config { pub extra_includes: Vec, pub proc_macro_server: Option, pub skip_path_resolution: bool, + pub extract_dependencies_as_source: bool, } impl Config { diff --git a/rust/extractor/src/main.rs b/rust/extractor/src/main.rs index 99f470aa13e..fd827f46d7c 100644 --- a/rust/extractor/src/main.rs +++ b/rust/extractor/src/main.rs @@ -277,6 +277,16 @@ fn main() -> anyhow::Result<()> { } else { ResolvePaths::Yes }; + let library_mode = if cfg.extract_dependencies_as_source { + SourceKind::Source + } else { + SourceKind::Library + }; + let library_resolve_paths = if cfg.extract_dependencies_as_source { + resolve_paths + } else { + ResolvePaths::No + }; let mut processed_files: HashSet = HashSet::from_iter(files.iter().cloned()); for (manifest, files) in map.values().filter(|(_, files)| !files.is_empty()) { @@ -312,12 +322,13 @@ fn main() -> anyhow::Result<()> { .source_root(db) .is_library { + tracing::info!("file: {}", file.display()); extractor.extract_with_semantics( file, &semantics, vfs, - ResolvePaths::No, - SourceKind::Library, + library_resolve_paths, + library_mode, ); extractor.archiver.archive(file); } From 96cba8b8c248282c3de20b592f4c2b7c4dba0810 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Thu, 22 May 2025 14:04:44 +0200 Subject: [PATCH 60/86] Rust: Add inconsistency check for type mentions without a root type --- .../codeql/typeinference/internal/TypeInference.qll | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll index 6a1f1c50bb3..b0f5fc67300 100644 --- a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll +++ b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll @@ -1314,6 +1314,10 @@ module Make1 Input1> { getTypeParameterId(tp1) = getTypeParameterId(tp2) and tp1 != tp2 } + + query predicate illFormedTypeMention(TypeMention tm) { + not exists(tm.resolveTypeAt(TypePath::nil())) and exists(tm.getLocation()) + } } } } From 5278064407ea4880713d82f1fda1800eefbd6946 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Thu, 22 May 2025 14:08:25 +0200 Subject: [PATCH 61/86] Rust: Only include relevant AST nodes in TypeMention --- .../codeql/rust/internal/TypeInference.qll | 14 +- .../lib/codeql/rust/internal/TypeMention.qll | 154 ++++++++---------- 2 files changed, 77 insertions(+), 91 deletions(-) diff --git a/rust/ql/lib/codeql/rust/internal/TypeInference.qll b/rust/ql/lib/codeql/rust/internal/TypeInference.qll index ca5c65f38ef..ca60efe2864 100644 --- a/rust/ql/lib/codeql/rust/internal/TypeInference.qll +++ b/rust/ql/lib/codeql/rust/internal/TypeInference.qll @@ -314,7 +314,7 @@ private Type getRefAdjustImplicitSelfType(SelfParam self, TypePath suffix, Type pragma[nomagic] private Type resolveImplSelfType(Impl i, TypePath path) { - result = i.getSelfTy().(TypeReprMention).resolveTypeAt(path) + result = i.getSelfTy().(TypeMention).resolveTypeAt(path) } /** Gets the type at `path` of the implicitly typed `self` parameter. */ @@ -377,7 +377,7 @@ private module StructExprMatchingInput implements MatchingInputSig { Type getDeclaredType(DeclarationPosition dpos, TypePath path) { // type of a field - exists(TypeReprMention tp | + exists(TypeMention tp | tp = this.getField(dpos.asFieldPos()).getTypeRepr() and result = tp.resolveTypeAt(path) ) @@ -537,7 +537,7 @@ private module CallExprBaseMatchingInput implements MatchingInputSig { override Type getParameterType(DeclarationPosition dpos, TypePath path) { exists(int pos | - result = this.getTupleField(pos).getTypeRepr().(TypeReprMention).resolveTypeAt(path) and + result = this.getTupleField(pos).getTypeRepr().(TypeMention).resolveTypeAt(path) and dpos = TPositionalDeclarationPosition(pos, false) ) } @@ -560,7 +560,7 @@ private module CallExprBaseMatchingInput implements MatchingInputSig { override Type getParameterType(DeclarationPosition dpos, TypePath path) { exists(int p | - result = this.getTupleField(p).getTypeRepr().(TypeReprMention).resolveTypeAt(path) and + result = this.getTupleField(p).getTypeRepr().(TypeMention).resolveTypeAt(path) and dpos = TPositionalDeclarationPosition(p, false) ) } @@ -608,7 +608,7 @@ private module CallExprBaseMatchingInput implements MatchingInputSig { } override Type getReturnType(TypePath path) { - result = this.getRetType().getTypeRepr().(TypeReprMention).resolveTypeAt(path) + result = this.getRetType().getTypeRepr().(TypeMention).resolveTypeAt(path) } } @@ -646,7 +646,7 @@ private module CallExprBaseMatchingInput implements MatchingInputSig { private import codeql.rust.elements.internal.CallExprImpl::Impl as CallExprImpl class Access extends CallExprBase { - private TypeReprMention getMethodTypeArg(int i) { + private TypeMention getMethodTypeArg(int i) { result = this.(MethodCallExpr).getGenericArgList().getTypeArg(i) } @@ -831,7 +831,7 @@ private module FieldExprMatchingInput implements MatchingInputSig { ) or dpos.isField() and - result = this.getTypeRepr().(TypeReprMention).resolveTypeAt(path) + result = this.getTypeRepr().(TypeMention).resolveTypeAt(path) } } diff --git a/rust/ql/lib/codeql/rust/internal/TypeMention.qll b/rust/ql/lib/codeql/rust/internal/TypeMention.qll index a957a82149f..7e947a35bc4 100644 --- a/rust/ql/lib/codeql/rust/internal/TypeMention.qll +++ b/rust/ql/lib/codeql/rust/internal/TypeMention.qll @@ -31,53 +31,33 @@ abstract class TypeMention extends AstNode { Type resolveTypeAt(TypePath path) { result = this.getMentionAt(path).resolveType() } } -class TypeReprMention extends TypeMention, TypeRepr { - TypeReprMention() { not this instanceof InferTypeRepr } +class ArrayTypeReprMention extends TypeMention instanceof ArrayTypeRepr { + override TypeMention getTypeArgument(int i) { result = super.getElementTypeRepr() and i = 0 } - override TypeReprMention getTypeArgument(int i) { - result = this.(ArrayTypeRepr).getElementTypeRepr() and - i = 0 - or - result = this.(RefTypeRepr).getTypeRepr() and - i = 0 - or - result = this.(PathTypeRepr).getPath().(PathMention).getTypeArgument(i) - } - - override Type resolveType() { - this instanceof ArrayTypeRepr and - result = TArrayType() - or - this instanceof RefTypeRepr and - result = TRefType() - or - result = this.(PathTypeRepr).getPath().(PathMention).resolveType() - } - - override Type resolveTypeAt(TypePath path) { - result = this.(PathTypeRepr).getPath().(PathMention).resolveTypeAt(path) - or - not exists(this.(PathTypeRepr).getPath()) and - result = super.resolveTypeAt(path) - } + override Type resolveType() { result = TArrayType() } } -/** Holds if `path` resolves to the type alias `alias` with the definition `rhs`. */ -private predicate resolvePathAlias(Path path, TypeAlias alias, TypeReprMention rhs) { - alias = resolvePath(path) and rhs = alias.getTypeRepr() +class RefTypeReprMention extends TypeMention instanceof RefTypeRepr { + override TypeMention getTypeArgument(int i) { result = super.getTypeRepr() and i = 0 } + + override Type resolveType() { result = TRefType() } } -abstract class PathMention extends TypeMention, Path { - override TypeMention getTypeArgument(int i) { - result = this.getSegment().getGenericArgList().getTypeArg(i) +class PathTypeReprMention extends TypeMention instanceof PathTypeRepr { + Path path; + ItemNode resolved; + + PathTypeReprMention() { + path = super.getPath() and + // NOTE: This excludes unresolvable paths which is intentional as these + // don't add value to the type inference anyway. + resolved = resolvePath(path) } -} -class NonAliasPathMention extends PathMention { - NonAliasPathMention() { not resolvePathAlias(this, _, _) } + ItemNode getResolved() { result = resolved } override TypeMention getTypeArgument(int i) { - result = super.getTypeArgument(i) + result = path.getSegment().getGenericArgList().getTypeArg(i) or // `Self` paths inside `impl` blocks have implicit type arguments that are // the type parameters of the `impl` block. For example, in @@ -92,17 +72,17 @@ class NonAliasPathMention extends PathMention { // // the `Self` return type is shorthand for `Foo`. exists(ImplItemNode node | - this = node.getASelfPath() and + path = node.getASelfPath() and result = node.(ImplItemNode).getSelfPath().getSegment().getGenericArgList().getTypeArg(i) ) or - // If `this` is the trait of an `impl` block then any associated types + // If `path` is the trait of an `impl` block then any associated types // defined in the `impl` block are type arguments to the trait. // // For instance, for a trait implementation like this // ```rust // impl MyTrait for MyType { - // ^^^^^^^ this + // ^^^^^^^ path // type AssociatedType = i64 // ^^^ result // // ... @@ -110,88 +90,94 @@ class NonAliasPathMention extends PathMention { // ``` // the rhs. of the type alias is a type argument to the trait. exists(ImplItemNode impl, AssociatedTypeTypeParameter param, TypeAlias alias | - this = impl.getTraitPath() and - param.getTrait() = resolvePath(this) and + path = impl.getTraitPath() and + param.getTrait() = resolved and alias = impl.getASuccessor(param.getTypeAlias().getName().getText()) and result = alias.getTypeRepr() and param.getIndex() = i ) } + /** + * Holds if this path resolved to a type alias with a rhs. that has the + * resulting type at `typePath`. + */ + Type aliasResolveTypeAt(TypePath typePath) { + exists(TypeAlias alias, TypeMention rhs | alias = resolved and rhs = alias.getTypeRepr() | + result = rhs.resolveTypeAt(typePath) and + not result = pathGetTypeParameter(alias, _) + or + exists(TypeParameter tp, TypeMention arg, TypePath prefix, TypePath suffix, int i | + tp = rhs.resolveTypeAt(prefix) and + tp = pathGetTypeParameter(alias, i) and + arg = path.getSegment().getGenericArgList().getTypeArg(i) and + result = arg.resolveTypeAt(suffix) and + typePath = prefix.append(suffix) + ) + ) + } + override Type resolveType() { - exists(ItemNode i | i = resolvePath(this) | - result = TStruct(i) + result = this.aliasResolveTypeAt(TypePath::nil()) + or + not exists(resolved.(TypeAlias).getTypeRepr()) and + ( + result = TStruct(resolved) or - result = TEnum(i) + result = TEnum(resolved) or - exists(TraitItemNode trait | trait = i | + exists(TraitItemNode trait | trait = resolved | // If this is a `Self` path, then it resolves to the implicit `Self` // type parameter, otherwise it is a trait bound. - if this = trait.getASelfPath() + if super.getPath() = trait.getASelfPath() then result = TSelfTypeParameter(trait) else result = TTrait(trait) ) or - result = TTypeParamTypeParameter(i) + result = TTypeParamTypeParameter(resolved) or - exists(TypeAlias alias | alias = i | + exists(TypeAlias alias | alias = resolved | result.(AssociatedTypeTypeParameter).getTypeAlias() = alias or - result = alias.getTypeRepr().(TypeReprMention).resolveType() + result = alias.getTypeRepr().(TypeMention).resolveType() ) ) } + + override Type resolveTypeAt(TypePath typePath) { + result = this.aliasResolveTypeAt(typePath) + or + not exists(resolved.(TypeAlias).getTypeRepr()) and + result = super.resolveTypeAt(typePath) + } } -class AliasPathMention extends PathMention { - TypeAlias alias; - TypeReprMention rhs; - - AliasPathMention() { resolvePathAlias(this, alias, rhs) } - - /** Get the `i`th type parameter of the alias itself. */ - private TypeParameter getTypeParameter(int i) { - result = TTypeParamTypeParameter(alias.getGenericParamList().getTypeParam(i)) - } - - override Type resolveType() { result = rhs.resolveType() } - - override Type resolveTypeAt(TypePath path) { - result = rhs.resolveTypeAt(path) and - not result = this.getTypeParameter(_) - or - exists(TypeParameter tp, TypeMention arg, TypePath prefix, TypePath suffix, int i | - tp = rhs.resolveTypeAt(prefix) and - tp = this.getTypeParameter(i) and - arg = this.getTypeArgument(i) and - result = arg.resolveTypeAt(suffix) and - path = prefix.append(suffix) - ) - } +private TypeParameter pathGetTypeParameter(TypeAlias alias, int i) { + result = TTypeParamTypeParameter(alias.getGenericParamList().getTypeParam(i)) } // Used to represent implicit `Self` type arguments in traits and `impl` blocks, // see `PathMention` for details. -class TypeParamMention extends TypeMention, TypeParam { - override TypeReprMention getTypeArgument(int i) { none() } +class TypeParamMention extends TypeMention instanceof TypeParam { + override TypeMention getTypeArgument(int i) { none() } override Type resolveType() { result = TTypeParamTypeParameter(this) } } // Used to represent implicit type arguments for associated types in traits. -class TypeAliasMention extends TypeMention, TypeAlias { +class TypeAliasMention extends TypeMention instanceof TypeAlias { private Type t; TypeAliasMention() { t = TAssociatedTypeTypeParameter(this) } - override TypeReprMention getTypeArgument(int i) { none() } + override TypeMention getTypeArgument(int i) { none() } override Type resolveType() { result = t } } -class TraitMention extends TypeMention, TraitItemNode { +class TraitMention extends TypeMention instanceof TraitItemNode { override TypeMention getTypeArgument(int i) { - result = this.getTypeParam(i) + result = super.getTypeParam(i) or traitAliasIndex(this, i, result) } @@ -203,7 +189,7 @@ class TraitMention extends TypeMention, TraitItemNode { // appears in the AST, we (somewhat arbitrarily) choose the name of a trait as a // type mention. This works because there is a one-to-one correspondence between // a trait and its name. -class SelfTypeParameterMention extends TypeMention, Name { +class SelfTypeParameterMention extends TypeMention instanceof Name { Trait trait; SelfTypeParameterMention() { trait.getName() = this } @@ -212,5 +198,5 @@ class SelfTypeParameterMention extends TypeMention, Name { override Type resolveType() { result = TSelfTypeParameter(trait) } - override TypeReprMention getTypeArgument(int i) { none() } + override TypeMention getTypeArgument(int i) { none() } } From ba4950fb89100d94caf8dfd58627eb98d9418958 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Thu, 22 May 2025 14:52:37 +0200 Subject: [PATCH 62/86] Rust: Accept test changes --- .../CONSISTENCY/TypeInferenceConsistency.expected | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 rust/ql/test/query-tests/unusedentities/CONSISTENCY/TypeInferenceConsistency.expected diff --git a/rust/ql/test/query-tests/unusedentities/CONSISTENCY/TypeInferenceConsistency.expected b/rust/ql/test/query-tests/unusedentities/CONSISTENCY/TypeInferenceConsistency.expected new file mode 100644 index 00000000000..56ce1df5c89 --- /dev/null +++ b/rust/ql/test/query-tests/unusedentities/CONSISTENCY/TypeInferenceConsistency.expected @@ -0,0 +1,2 @@ +illFormedTypeMention +| main.rs:403:18:403:24 | FuncPtr | From 1f6b3ad929a7128f42d696e6c12249153beb0c03 Mon Sep 17 00:00:00 2001 From: Napalys Klicius Date: Tue, 27 May 2025 09:38:24 +0200 Subject: [PATCH 63/86] Update javascript/ql/src/codeql-suites/javascript-security-and-quality.qls Co-authored-by: Michael Nebel --- .../src/codeql-suites/javascript-security-and-quality.qls | 6 ------ 1 file changed, 6 deletions(-) diff --git a/javascript/ql/src/codeql-suites/javascript-security-and-quality.qls b/javascript/ql/src/codeql-suites/javascript-security-and-quality.qls index d02a016f058..38d45ecfbe6 100644 --- a/javascript/ql/src/codeql-suites/javascript-security-and-quality.qls +++ b/javascript/ql/src/codeql-suites/javascript-security-and-quality.qls @@ -136,9 +136,3 @@ - exclude: query path: - /^experimental\/.*/ - - Metrics/Summaries/FrameworkCoverage.ql - - /Diagnostics/Internal/.*/ -- exclude: - tags contain: - - modeleditor - - modelgenerator From 1e64f50c3c77f6a59651033b0462d496fb83a5f5 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 27 May 2025 08:51:00 +0100 Subject: [PATCH 64/86] Apply suggestions from code review Co-authored-by: Simon Friis Vindum --- rust/ql/lib/codeql/rust/elements/DerefExpr.qll | 2 +- .../lib/codeql/rust/security/AccessInvalidPointerExtensions.qll | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/ql/lib/codeql/rust/elements/DerefExpr.qll b/rust/ql/lib/codeql/rust/elements/DerefExpr.qll index 28302a93411..0eb54d4930d 100644 --- a/rust/ql/lib/codeql/rust/elements/DerefExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/DerefExpr.qll @@ -6,7 +6,7 @@ private import codeql.rust.elements.PrefixExpr private import codeql.rust.elements.Operation /** - * A dereference expression, `*`. + * A dereference expression, the prefix operator `*`. */ final class DerefExpr extends PrefixExpr, Operation { DerefExpr() { this.getOperatorName() = "*" } diff --git a/rust/ql/lib/codeql/rust/security/AccessInvalidPointerExtensions.qll b/rust/ql/lib/codeql/rust/security/AccessInvalidPointerExtensions.qll index 36abfb62d54..444db014209 100644 --- a/rust/ql/lib/codeql/rust/security/AccessInvalidPointerExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/AccessInvalidPointerExtensions.qll @@ -50,7 +50,7 @@ module AccessInvalidPointer { * A pointer access using the unary `*` operator. */ private class DereferenceSink extends Sink { - DereferenceSink() { exists(DerefExpr p | p.getExpr() = this.asExpr().getExpr()) } + DereferenceSink() { any(DerefExpr p).getExpr() = this.asExpr().getExpr() } } /** From 329d451d4db8e31a54bcad818433d10a7dfb035d Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 27 May 2025 10:53:57 +0200 Subject: [PATCH 65/86] Swift: Add change note --- swift/ql/lib/change-notes/2025-05-27-swift.6.1.1.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 swift/ql/lib/change-notes/2025-05-27-swift.6.1.1.md diff --git a/swift/ql/lib/change-notes/2025-05-27-swift.6.1.1.md b/swift/ql/lib/change-notes/2025-05-27-swift.6.1.1.md new file mode 100644 index 00000000000..19101e5b615 --- /dev/null +++ b/swift/ql/lib/change-notes/2025-05-27-swift.6.1.1.md @@ -0,0 +1,5 @@ + +--- +category: minorAnalysis +--- +* Updated to allow analysis of Swift 6.1.1. From f4636b9ef2bb822323fb9b9781f18a622e43c7ee Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 27 May 2025 10:56:52 +0200 Subject: [PATCH 66/86] Swift: Update Swift resources --- swift/third_party/load.bzl | 4 ---- swift/third_party/resources/resource-dir-linux.zip | 4 ++-- swift/third_party/resources/resource-dir-macos.zip | 4 ++-- swift/third_party/resources/swift-prebuilt-linux.tar.zst | 4 ++-- swift/third_party/resources/swift-prebuilt-macos.tar.zst | 4 ++-- 5 files changed, 8 insertions(+), 12 deletions(-) diff --git a/swift/third_party/load.bzl b/swift/third_party/load.bzl index ad05960e7f6..d19345a1880 100644 --- a/swift/third_party/load.bzl +++ b/swift/third_party/load.bzl @@ -5,10 +5,6 @@ load("//misc/bazel:lfs.bzl", "lfs_archive", "lfs_files") _override = { # these are used to test new artifacts. Must be empty before merging to main - "swift-prebuilt-macOS-swift-6.1.1-RELEASE-108.tar.zst": "2aaf6e7083c27a561d7212f88b3e15cbeb2bdf1d2363d310227d278937a4c2c9", - "swift-prebuilt-Linux-swift-6.1.1-RELEASE-108.tar.zst": "31cba2387c7e1ce4e73743935b0db65ea69fccf5c07bd2b392fd6815f5dffca5", - "resource-dir-macOS-swift-6.1.1-RELEASE-115.zip": "84e34d6af45883fe6d0103c2f36bbff3069ac068e671cb62d0d01d16e087362d", - "resource-dir-Linux-swift-6.1.1-RELEASE-115.zip": "1e00a730a93b85a5ba478590218e1f769792ec56501977cc72d941101c5c3657", } _staging_url = "https://github.com/dsp-testing/codeql-swift-artifacts/releases/download/staging-{}/{}" diff --git a/swift/third_party/resources/resource-dir-linux.zip b/swift/third_party/resources/resource-dir-linux.zip index 8697b7c7afc..e09b73863e5 100644 --- a/swift/third_party/resources/resource-dir-linux.zip +++ b/swift/third_party/resources/resource-dir-linux.zip @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:874932f93c4ca6269ae3a9e9c841916b3fd88f65f5018eec8777a52dde56901d -size 293646067 +oid sha256:1e00a730a93b85a5ba478590218e1f769792ec56501977cc72d941101c5c3657 +size 293644020 diff --git a/swift/third_party/resources/resource-dir-macos.zip b/swift/third_party/resources/resource-dir-macos.zip index 95ffbc2e02f..aaacc64a9e8 100644 --- a/swift/third_party/resources/resource-dir-macos.zip +++ b/swift/third_party/resources/resource-dir-macos.zip @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:12bef89163486ac24d9ca00a5cc6ef3851b633e6fa63b7493c518e4d426e036c -size 595744464 +oid sha256:84e34d6af45883fe6d0103c2f36bbff3069ac068e671cb62d0d01d16e087362d +size 595760699 diff --git a/swift/third_party/resources/swift-prebuilt-linux.tar.zst b/swift/third_party/resources/swift-prebuilt-linux.tar.zst index 03490187210..206ea6adb4d 100644 --- a/swift/third_party/resources/swift-prebuilt-linux.tar.zst +++ b/swift/third_party/resources/swift-prebuilt-linux.tar.zst @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d01b90bccfec46995bdf98a59339bd94e64257da99b4963148869c4a108bc2a9 -size 124360007 +oid sha256:31cba2387c7e1ce4e73743935b0db65ea69fccf5c07bd2b392fd6815f5dffca5 +size 124428345 diff --git a/swift/third_party/resources/swift-prebuilt-macos.tar.zst b/swift/third_party/resources/swift-prebuilt-macos.tar.zst index 692a8b05dc3..bcbc7aaf412 100644 --- a/swift/third_party/resources/swift-prebuilt-macos.tar.zst +++ b/swift/third_party/resources/swift-prebuilt-macos.tar.zst @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4dcfe858b5519327c9b0c99735b47fe75c7a5090793d917de1ba6e42795aa86d -size 105011965 +oid sha256:2aaf6e7083c27a561d7212f88b3e15cbeb2bdf1d2363d310227d278937a4c2c9 +size 104357336 From 5d8bb1b5b014e0408bc2e4c796b94772537256d2 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 23 May 2025 20:50:16 +0100 Subject: [PATCH 67/86] C++: Add more Windows sources. --- cpp/ql/lib/ext/Windows.model.yml | 10 + .../dataflow/external-models/flow.expected | 86 +++++- .../dataflow/external-models/sources.expected | 10 + .../dataflow/external-models/windows.cpp | 265 ++++++++++++++++++ 4 files changed, 357 insertions(+), 14 deletions(-) diff --git a/cpp/ql/lib/ext/Windows.model.yml b/cpp/ql/lib/ext/Windows.model.yml index acac5f5fbf8..89127459f96 100644 --- a/cpp/ql/lib/ext/Windows.model.yml +++ b/cpp/ql/lib/ext/Windows.model.yml @@ -11,6 +11,16 @@ extensions: - ["", "", False, "GetEnvironmentStringsW", "", "", "ReturnValue[*]", "local", "manual"] - ["", "", False, "GetEnvironmentVariableA", "", "", "Argument[*1]", "local", "manual"] - ["", "", False, "GetEnvironmentVariableW", "", "", "Argument[*1]", "local", "manual"] + - ["", "", False, "ReadFile", "", "", "Argument[*1]", "local", "manual"] + - ["", "", False, "ReadFileEx", "", "", "Argument[*1]", "local", "manual"] + - ["", "", False, "MapViewOfFile", "", "", "ReturnValue[*]", "local", "manual"] + - ["", "", False, "MapViewOfFile2", "", "", "ReturnValue[*]", "local", "manual"] + - ["", "", False, "MapViewOfFile3", "", "", "ReturnValue[*]", "local", "manual"] + - ["", "", False, "MapViewOfFile3FromApp", "", "", "ReturnValue[*]", "local", "manual"] + - ["", "", False, "MapViewOfFileEx", "", "", "ReturnValue[*]", "local", "manual"] + - ["", "", False, "MapViewOfFileFromApp", "", "", "ReturnValue[*]", "local", "manual"] + - ["", "", False, "MapViewOfFileNuma2", "", "", "ReturnValue[*]", "local", "manual"] + - ["", "", False, "NtReadFile", "", "", "Argument[*5]", "local", "manual"] - addsTo: pack: codeql/cpp-all extensible: summaryModel diff --git a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected index 9992ca5a721..c8babcb1454 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected @@ -10,44 +10,68 @@ edges | asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:6 | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:10 | -| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:23497 | -| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:23498 | -| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:23499 | +| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:23507 | +| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:23508 | +| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:23509 | | test.cpp:7:47:7:52 | value2 | test.cpp:7:64:7:69 | value2 | provenance | | | test.cpp:7:64:7:69 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | provenance | | -| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:10:10:10:18 | call to ymlSource | provenance | Src:MaD:23495 | -| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:14:10:14:10 | x | provenance | Sink:MaD:23496 | +| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:10:10:10:18 | call to ymlSource | provenance | Src:MaD:23505 | +| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:14:10:14:10 | x | provenance | Sink:MaD:23506 | | test.cpp:10:10:10:18 | call to ymlSource | test.cpp:17:24:17:24 | x | provenance | | | test.cpp:10:10:10:18 | call to ymlSource | test.cpp:21:27:21:27 | x | provenance | | | test.cpp:10:10:10:18 | call to ymlSource | test.cpp:25:35:25:35 | x | provenance | | | test.cpp:10:10:10:18 | call to ymlSource | test.cpp:32:41:32:41 | x | provenance | | | test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | | -| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:18:10:18:10 | y | provenance | Sink:MaD:23496 | +| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:18:10:18:10 | y | provenance | Sink:MaD:23506 | | test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | provenance | | -| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:23497 | +| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:23507 | | test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | | -| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:22:10:22:10 | z | provenance | Sink:MaD:23496 | +| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:22:10:22:10 | z | provenance | Sink:MaD:23506 | | test.cpp:21:27:21:27 | x | test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | provenance | | -| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:23498 | +| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:23508 | | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | | -| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:26:10:26:11 | y2 | provenance | Sink:MaD:23496 | +| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:26:10:26:11 | y2 | provenance | Sink:MaD:23506 | | test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | provenance | | -| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:23499 | +| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:23509 | | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | provenance | | -| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:33:10:33:11 | z2 | provenance | Sink:MaD:23496 | +| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:33:10:33:11 | z2 | provenance | Sink:MaD:23506 | | test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | provenance | | | test.cpp:32:41:32:41 | x | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | provenance | | -| windows.cpp:6:8:6:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:6:8:6:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:331 | +| windows.cpp:6:8:6:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:6:8:6:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:341 | | windows.cpp:11:15:11:29 | *call to GetCommandLineA | windows.cpp:11:15:11:29 | *call to GetCommandLineA | provenance | Src:MaD:325 | | windows.cpp:11:15:11:29 | *call to GetCommandLineA | windows.cpp:13:8:13:11 | * ... | provenance | | | windows.cpp:11:15:11:29 | *call to GetCommandLineA | windows.cpp:16:36:16:38 | *cmd | provenance | | | windows.cpp:16:17:16:34 | **call to CommandLineToArgvA | windows.cpp:16:17:16:34 | **call to CommandLineToArgvA | provenance | | | windows.cpp:16:17:16:34 | **call to CommandLineToArgvA | windows.cpp:19:8:19:15 | * ... | provenance | | | windows.cpp:16:36:16:38 | *cmd | windows.cpp:6:8:6:25 | [summary param] *0 in CommandLineToArgvA | provenance | | -| windows.cpp:16:36:16:38 | *cmd | windows.cpp:16:17:16:34 | **call to CommandLineToArgvA | provenance | MaD:331 | +| windows.cpp:16:36:16:38 | *cmd | windows.cpp:16:17:16:34 | **call to CommandLineToArgvA | provenance | MaD:341 | | windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | provenance | Src:MaD:327 | | windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | windows.cpp:25:10:25:13 | * ... | provenance | | | windows.cpp:28:36:28:38 | GetEnvironmentVariableA output argument | windows.cpp:30:10:30:13 | * ... | provenance | Src:MaD:329 | +| windows.cpp:145:35:145:40 | ReadFile output argument | windows.cpp:147:10:147:16 | * ... | provenance | Src:MaD:331 | +| windows.cpp:154:23:154:28 | ReadFileEx output argument | windows.cpp:156:10:156:16 | * ... | provenance | Src:MaD:332 | +| windows.cpp:168:84:168:89 | NtReadFile output argument | windows.cpp:170:10:170:16 | * ... | provenance | Src:MaD:340 | +| windows.cpp:245:23:245:35 | *call to MapViewOfFile | windows.cpp:245:23:245:35 | *call to MapViewOfFile | provenance | Src:MaD:333 | +| windows.cpp:245:23:245:35 | *call to MapViewOfFile | windows.cpp:246:20:246:52 | *pMapView | provenance | | +| windows.cpp:246:20:246:52 | *pMapView | windows.cpp:248:10:248:16 | * ... | provenance | | +| windows.cpp:252:23:252:36 | *call to MapViewOfFile2 | windows.cpp:252:23:252:36 | *call to MapViewOfFile2 | provenance | Src:MaD:334 | +| windows.cpp:252:23:252:36 | *call to MapViewOfFile2 | windows.cpp:253:20:253:52 | *pMapView | provenance | | +| windows.cpp:253:20:253:52 | *pMapView | windows.cpp:255:10:255:16 | * ... | provenance | | +| windows.cpp:261:23:261:36 | *call to MapViewOfFile3 | windows.cpp:261:23:261:36 | *call to MapViewOfFile3 | provenance | Src:MaD:335 | +| windows.cpp:261:23:261:36 | *call to MapViewOfFile3 | windows.cpp:262:20:262:52 | *pMapView | provenance | | +| windows.cpp:262:20:262:52 | *pMapView | windows.cpp:264:10:264:16 | * ... | provenance | | +| windows.cpp:270:23:270:43 | *call to MapViewOfFile3FromApp | windows.cpp:270:23:270:43 | *call to MapViewOfFile3FromApp | provenance | Src:MaD:336 | +| windows.cpp:270:23:270:43 | *call to MapViewOfFile3FromApp | windows.cpp:271:20:271:52 | *pMapView | provenance | | +| windows.cpp:271:20:271:52 | *pMapView | windows.cpp:273:10:273:16 | * ... | provenance | | +| windows.cpp:277:23:277:37 | *call to MapViewOfFileEx | windows.cpp:277:23:277:37 | *call to MapViewOfFileEx | provenance | Src:MaD:337 | +| windows.cpp:277:23:277:37 | *call to MapViewOfFileEx | windows.cpp:278:20:278:52 | *pMapView | provenance | | +| windows.cpp:278:20:278:52 | *pMapView | windows.cpp:280:10:280:16 | * ... | provenance | | +| windows.cpp:284:23:284:42 | *call to MapViewOfFileFromApp | windows.cpp:284:23:284:42 | *call to MapViewOfFileFromApp | provenance | Src:MaD:338 | +| windows.cpp:284:23:284:42 | *call to MapViewOfFileFromApp | windows.cpp:285:20:285:52 | *pMapView | provenance | | +| windows.cpp:285:20:285:52 | *pMapView | windows.cpp:287:10:287:16 | * ... | provenance | | +| windows.cpp:291:23:291:40 | *call to MapViewOfFileNuma2 | windows.cpp:291:23:291:40 | *call to MapViewOfFileNuma2 | provenance | Src:MaD:339 | +| windows.cpp:291:23:291:40 | *call to MapViewOfFileNuma2 | windows.cpp:292:20:292:52 | *pMapView | provenance | | +| windows.cpp:292:20:292:52 | *pMapView | windows.cpp:294:10:294:16 | * ... | provenance | | nodes | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | semmle.label | [summary param] *0 in buffer | | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | semmle.label | [summary] to write: ReturnValue in buffer | @@ -103,6 +127,40 @@ nodes | windows.cpp:25:10:25:13 | * ... | semmle.label | * ... | | windows.cpp:28:36:28:38 | GetEnvironmentVariableA output argument | semmle.label | GetEnvironmentVariableA output argument | | windows.cpp:30:10:30:13 | * ... | semmle.label | * ... | +| windows.cpp:145:35:145:40 | ReadFile output argument | semmle.label | ReadFile output argument | +| windows.cpp:147:10:147:16 | * ... | semmle.label | * ... | +| windows.cpp:154:23:154:28 | ReadFileEx output argument | semmle.label | ReadFileEx output argument | +| windows.cpp:156:10:156:16 | * ... | semmle.label | * ... | +| windows.cpp:168:84:168:89 | NtReadFile output argument | semmle.label | NtReadFile output argument | +| windows.cpp:170:10:170:16 | * ... | semmle.label | * ... | +| windows.cpp:245:23:245:35 | *call to MapViewOfFile | semmle.label | *call to MapViewOfFile | +| windows.cpp:245:23:245:35 | *call to MapViewOfFile | semmle.label | *call to MapViewOfFile | +| windows.cpp:246:20:246:52 | *pMapView | semmle.label | *pMapView | +| windows.cpp:248:10:248:16 | * ... | semmle.label | * ... | +| windows.cpp:252:23:252:36 | *call to MapViewOfFile2 | semmle.label | *call to MapViewOfFile2 | +| windows.cpp:252:23:252:36 | *call to MapViewOfFile2 | semmle.label | *call to MapViewOfFile2 | +| windows.cpp:253:20:253:52 | *pMapView | semmle.label | *pMapView | +| windows.cpp:255:10:255:16 | * ... | semmle.label | * ... | +| windows.cpp:261:23:261:36 | *call to MapViewOfFile3 | semmle.label | *call to MapViewOfFile3 | +| windows.cpp:261:23:261:36 | *call to MapViewOfFile3 | semmle.label | *call to MapViewOfFile3 | +| windows.cpp:262:20:262:52 | *pMapView | semmle.label | *pMapView | +| windows.cpp:264:10:264:16 | * ... | semmle.label | * ... | +| windows.cpp:270:23:270:43 | *call to MapViewOfFile3FromApp | semmle.label | *call to MapViewOfFile3FromApp | +| windows.cpp:270:23:270:43 | *call to MapViewOfFile3FromApp | semmle.label | *call to MapViewOfFile3FromApp | +| windows.cpp:271:20:271:52 | *pMapView | semmle.label | *pMapView | +| windows.cpp:273:10:273:16 | * ... | semmle.label | * ... | +| windows.cpp:277:23:277:37 | *call to MapViewOfFileEx | semmle.label | *call to MapViewOfFileEx | +| windows.cpp:277:23:277:37 | *call to MapViewOfFileEx | semmle.label | *call to MapViewOfFileEx | +| windows.cpp:278:20:278:52 | *pMapView | semmle.label | *pMapView | +| windows.cpp:280:10:280:16 | * ... | semmle.label | * ... | +| windows.cpp:284:23:284:42 | *call to MapViewOfFileFromApp | semmle.label | *call to MapViewOfFileFromApp | +| windows.cpp:284:23:284:42 | *call to MapViewOfFileFromApp | semmle.label | *call to MapViewOfFileFromApp | +| windows.cpp:285:20:285:52 | *pMapView | semmle.label | *pMapView | +| windows.cpp:287:10:287:16 | * ... | semmle.label | * ... | +| windows.cpp:291:23:291:40 | *call to MapViewOfFileNuma2 | semmle.label | *call to MapViewOfFileNuma2 | +| windows.cpp:291:23:291:40 | *call to MapViewOfFileNuma2 | semmle.label | *call to MapViewOfFileNuma2 | +| windows.cpp:292:20:292:52 | *pMapView | semmle.label | *pMapView | +| windows.cpp:294:10:294:16 | * ... | semmle.label | * ... | subpaths | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | asio_streams.cpp:100:44:100:62 | call to buffer | | test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/sources.expected b/cpp/ql/test/library-tests/dataflow/external-models/sources.expected index 1c21bf85121..f8d2da8a002 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/sources.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/sources.expected @@ -3,3 +3,13 @@ | windows.cpp:11:15:11:29 | *call to GetCommandLineA | local | | windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | local | | windows.cpp:28:36:28:38 | GetEnvironmentVariableA output argument | local | +| windows.cpp:145:35:145:40 | ReadFile output argument | local | +| windows.cpp:154:23:154:28 | ReadFileEx output argument | local | +| windows.cpp:168:84:168:89 | NtReadFile output argument | local | +| windows.cpp:245:23:245:35 | *call to MapViewOfFile | local | +| windows.cpp:252:23:252:36 | *call to MapViewOfFile2 | local | +| windows.cpp:261:23:261:36 | *call to MapViewOfFile3 | local | +| windows.cpp:270:23:270:43 | *call to MapViewOfFile3FromApp | local | +| windows.cpp:277:23:277:37 | *call to MapViewOfFileEx | local | +| windows.cpp:284:23:284:42 | *call to MapViewOfFileFromApp | local | +| windows.cpp:291:23:291:40 | *call to MapViewOfFileNuma2 | local | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp b/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp index dfa055fa1e8..382f534dde8 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp +++ b/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp @@ -29,3 +29,268 @@ void getEnvironment() { sink(buf); sink(*buf); // $ ir } + +using HANDLE = void*; +using DWORD = unsigned long; +using LPVOID = void*; +using LPDWORD = unsigned long*; +using PVOID = void*; +using ULONG_PTR = unsigned long*; +using SIZE_T = decltype(sizeof(0)); +typedef struct _OVERLAPPED { + ULONG_PTR Internal; + ULONG_PTR InternalHigh; + union { + struct { + DWORD Offset; + DWORD OffsetHigh; + } DUMMYSTRUCTNAME; + PVOID Pointer; + } DUMMYUNIONNAME; + HANDLE hEvent; +} OVERLAPPED, *LPOVERLAPPED; + +using BOOL = int; +#define FILE_MAP_READ 0x0004 + +using ULONG64 = unsigned long long; +using ULONG = unsigned long; + +using DWORD64 = unsigned long long; +#define MEM_EXTENDED_PARAMETER_TYPE_BITS 8 + +typedef struct MEM_EXTENDED_PARAMETER { + struct { + DWORD64 Type : MEM_EXTENDED_PARAMETER_TYPE_BITS; + DWORD64 Reserved : 64 - MEM_EXTENDED_PARAMETER_TYPE_BITS; + } DUMMYSTRUCTNAME; + union { + DWORD64 ULong64; + PVOID Pointer; + SIZE_T Size; + HANDLE Handle; + DWORD ULong; + } DUMMYUNIONNAME; +} MEM_EXTENDED_PARAMETER, *PMEM_EXTENDED_PARAMETER; + +BOOL ReadFile( + HANDLE hFile, + LPVOID lpBuffer, + DWORD nNumberOfBytesToRead, + LPDWORD lpNumberOfBytesRead, + LPOVERLAPPED lpOverlapped +); + +using LPOVERLAPPED_COMPLETION_ROUTINE = void (*)(DWORD, DWORD, LPOVERLAPPED); + +BOOL ReadFileEx( + HANDLE hFile, + LPVOID lpBuffer, + DWORD nNumberOfBytesToRead, + LPOVERLAPPED lpOverlapped, + LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine +); + +using NTSTATUS = long; +using PIO_APC_ROUTINE = void (*)(struct _DEVICE_OBJECT*, struct _IRP*, PVOID); +typedef struct _IO_STATUS_BLOCK { + union { + NTSTATUS Status; + PVOID Pointer; + } DUMMYUNIONNAME; + ULONG_PTR Information; +} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; +using LONGLONG = long long; +using LONG = long; +typedef struct _LARGE_INTEGER { + union { + struct { + ULONG LowPart; + LONG HighPart; + } DUMMYSTRUCTNAME; + LONGLONG QuadPart; + } DUMMYUNIONNAME; +} LARGE_INTEGER, *PLARGE_INTEGER; + +using PULONG = unsigned long*; + +NTSTATUS NtReadFile( + HANDLE FileHandle, + HANDLE Event, + PIO_APC_ROUTINE ApcRoutine, + PVOID ApcContext, + PIO_STATUS_BLOCK IoStatusBlock, + PVOID Buffer, + ULONG Length, + PLARGE_INTEGER ByteOffset, + PULONG Key +); + + +void FileIOCompletionRoutine( + DWORD dwErrorCode, + DWORD dwNumberOfBytesTransfered, + LPOVERLAPPED lpOverlapped +) { + char* buffer = reinterpret_cast(lpOverlapped->hEvent); + sink(buffer); + sink(*buffer); // $ MISSING: ir +} + +void readFile(HANDLE hFile) { + { + char buffer[1024]; + DWORD bytesRead; + OVERLAPPED overlapped; + BOOL result = ReadFile(hFile, buffer, sizeof(buffer), &bytesRead, &overlapped); + sink(buffer); + sink(*buffer); // $ ir + } + + { + char buffer[1024]; + OVERLAPPED overlapped; + overlapped.hEvent = reinterpret_cast(buffer); + ReadFileEx(hFile, buffer, sizeof(buffer) - 1, &overlapped, FileIOCompletionRoutine); + sink(buffer); + sink(*buffer); // $ ir + + char* p = reinterpret_cast(overlapped.hEvent); + sink(p); + sink(*p); // $ MISSING: ir + } + + { + char buffer[1024]; + IO_STATUS_BLOCK ioStatusBlock; + LARGE_INTEGER byteOffset; + ULONG key; + NTSTATUS status = NtReadFile(hFile, nullptr, nullptr, nullptr, &ioStatusBlock, buffer, sizeof(buffer), &byteOffset, &key); + sink(buffer); + sink(*buffer); // $ ir + } +} + +LPVOID MapViewOfFile( + HANDLE hFileMappingObject, + DWORD dwDesiredAccess, + DWORD dwFileOffsetHigh, + DWORD dwFileOffsetLow, + SIZE_T dwNumberOfBytesToMap +); + +PVOID MapViewOfFile2( + HANDLE FileMappingHandle, + HANDLE ProcessHandle, + ULONG64 Offset, + PVOID BaseAddress, + SIZE_T ViewSize, + ULONG AllocationType, + ULONG PageProtection +); + +PVOID MapViewOfFile3( + HANDLE FileMapping, + HANDLE Process, + PVOID BaseAddress, + ULONG64 Offset, + SIZE_T ViewSize, + ULONG AllocationType, + ULONG PageProtection, + MEM_EXTENDED_PARAMETER *ExtendedParameters, + ULONG ParameterCount +); + +PVOID MapViewOfFile3FromApp( + HANDLE FileMapping, + HANDLE Process, + PVOID BaseAddress, + ULONG64 Offset, + SIZE_T ViewSize, + ULONG AllocationType, + ULONG PageProtection, + MEM_EXTENDED_PARAMETER *ExtendedParameters, + ULONG ParameterCount +); + +LPVOID MapViewOfFileEx( + HANDLE hFileMappingObject, + DWORD dwDesiredAccess, + DWORD dwFileOffsetHigh, + DWORD dwFileOffsetLow, + SIZE_T dwNumberOfBytesToMap, + LPVOID lpBaseAddress +); + +PVOID MapViewOfFileFromApp( + HANDLE hFileMappingObject, + ULONG DesiredAccess, + ULONG64 FileOffset, + SIZE_T NumberOfBytesToMap +); + +PVOID MapViewOfFileNuma2( + HANDLE FileMappingHandle, + HANDLE ProcessHandle, + ULONG64 Offset, + PVOID BaseAddress, + SIZE_T ViewSize, + ULONG AllocationType, + ULONG PageProtection, + ULONG PreferredNode +); + +void mapViewOfFile(HANDLE hMapFile) { + { + LPVOID pMapView = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); + char* buffer = reinterpret_cast(pMapView); + sink(buffer); + sink(*buffer); // $ ir + } + + { + LPVOID pMapView = MapViewOfFile2(hMapFile, nullptr, 0, nullptr, 0, 0, 0); + char* buffer = reinterpret_cast(pMapView); + sink(buffer); + sink(*buffer); // $ ir + } + + { + MEM_EXTENDED_PARAMETER extendedParams; + + LPVOID pMapView = MapViewOfFile3(hMapFile, nullptr, 0, 0, 0, 0, 0, &extendedParams, 1); + char* buffer = reinterpret_cast(pMapView); + sink(buffer); + sink(*buffer); // $ ir + } + + { + MEM_EXTENDED_PARAMETER extendedParams; + + LPVOID pMapView = MapViewOfFile3FromApp(hMapFile, nullptr, 0, 0, 0, 0, 0, &extendedParams, 1); + char* buffer = reinterpret_cast(pMapView); + sink(buffer); + sink(*buffer); // $ ir + } + + { + LPVOID pMapView = MapViewOfFileEx(hMapFile, FILE_MAP_READ, 0, 0, 0, nullptr); + char* buffer = reinterpret_cast(pMapView); + sink(buffer); + sink(*buffer); // $ ir + } + + { + LPVOID pMapView = MapViewOfFileFromApp(hMapFile, FILE_MAP_READ, 0, 0); + char* buffer = reinterpret_cast(pMapView); + sink(buffer); + sink(*buffer); // $ ir + } + + { + LPVOID pMapView = MapViewOfFileNuma2(hMapFile, nullptr, 0, nullptr, 0, 0, 0, 0); + char* buffer = reinterpret_cast(pMapView); + sink(buffer); + sink(*buffer); // $ ir + } +} From fd9adc43c230545498f1b8ae070b6678c10e8da9 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 27 May 2025 11:00:48 +0100 Subject: [PATCH 68/86] C++: Add change note. --- cpp/ql/lib/change-notes/2025-05-27-windows-sources-2.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2025-05-27-windows-sources-2.md diff --git a/cpp/ql/lib/change-notes/2025-05-27-windows-sources-2.md b/cpp/ql/lib/change-notes/2025-05-27-windows-sources-2.md new file mode 100644 index 00000000000..423a1a424f9 --- /dev/null +++ b/cpp/ql/lib/change-notes/2025-05-27-windows-sources-2.md @@ -0,0 +1,4 @@ +--- +category: feature +--- +* Added local flow source models for `ReadFile`, `ReadFileEx`, `MapViewOfFile`, `MapViewOfFile2`, `MapViewOfFile3`, `MapViewOfFile3FromApp`, `MapViewOfFileEx`, `MapViewOfFileFromApp`, `MapViewOfFileNuma2`, and `NtReadFile`. \ No newline at end of file From 52280625eeeee973f1b998cfc062caf93cd53e62 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Fri, 23 May 2025 14:20:44 +0200 Subject: [PATCH 69/86] Rust: Add type inference inconsistency counts to the stats summary --- .../internal/TypeInferenceConsistency.qll | 24 +++++++++++++++++++ rust/ql/src/queries/summary/Stats.qll | 15 ++++++++++++ rust/ql/src/queries/summary/SummaryStats.ql | 2 ++ .../TypeInferenceConsistency.expected | 3 +++ 4 files changed, 44 insertions(+) create mode 100644 rust/ql/test/query-tests/security/CWE-089/CONSISTENCY/TypeInferenceConsistency.expected diff --git a/rust/ql/lib/codeql/rust/internal/TypeInferenceConsistency.qll b/rust/ql/lib/codeql/rust/internal/TypeInferenceConsistency.qll index 214ee3e6d49..e9bcf35badc 100644 --- a/rust/ql/lib/codeql/rust/internal/TypeInferenceConsistency.qll +++ b/rust/ql/lib/codeql/rust/internal/TypeInferenceConsistency.qll @@ -2,4 +2,28 @@ * Provides classes for recognizing type inference inconsistencies. */ +private import Type +private import TypeMention +private import TypeInference::Consistency as Consistency import TypeInference::Consistency + +query predicate illFormedTypeMention(TypeMention tm) { + Consistency::illFormedTypeMention(tm) and + // Only include inconsistencies in the source, as we otherwise get + // inconsistencies from library code in every project. + tm.fromSource() +} + +int getTypeInferenceInconsistencyCounts(string type) { + type = "Missing type parameter ID" and + result = count(TypeParameter tp | missingTypeParameterId(tp) | tp) + or + type = "Non-functional type parameter ID" and + result = count(TypeParameter tp | nonFunctionalTypeParameterId(tp) | tp) + or + type = "Non-injective type parameter ID" and + result = count(TypeParameter tp | nonInjectiveTypeParameterId(tp, _) | tp) + or + type = "Ill-formed type mention" and + result = count(TypeMention tm | illFormedTypeMention(tm) | tm) +} diff --git a/rust/ql/src/queries/summary/Stats.qll b/rust/ql/src/queries/summary/Stats.qll index 2199a3ddff0..db0a05629df 100644 --- a/rust/ql/src/queries/summary/Stats.qll +++ b/rust/ql/src/queries/summary/Stats.qll @@ -8,6 +8,7 @@ private import codeql.rust.dataflow.internal.DataFlowImpl private import codeql.rust.dataflow.internal.TaintTrackingImpl private import codeql.rust.internal.AstConsistency as AstConsistency private import codeql.rust.internal.PathResolutionConsistency as PathResolutionConsistency +private import codeql.rust.internal.TypeInferenceConsistency as TypeInferenceConsistency private import codeql.rust.controlflow.internal.CfgConsistency as CfgConsistency private import codeql.rust.dataflow.internal.DataFlowConsistency as DataFlowConsistency private import codeql.rust.dataflow.internal.SsaImpl::Consistency as SsaConsistency @@ -52,6 +53,13 @@ int getTotalPathResolutionInconsistencies() { sum(string type | | PathResolutionConsistency::getPathResolutionInconsistencyCounts(type)) } +/** + * Gets a count of the total number of type inference inconsistencies in the database. + */ +int getTotalTypeInferenceInconsistencies() { + result = sum(string type | | TypeInferenceConsistency::getTypeInferenceInconsistencyCounts(type)) +} + /** * Gets a count of the total number of control flow graph inconsistencies in the database. */ @@ -159,6 +167,13 @@ predicate inconsistencyStats(string key, int value) { key = "Inconsistencies - data flow" and value = getTotalDataFlowInconsistencies() } +/** + * Gets summary statistics about inconsistencies related to type inference. + */ +predicate typeInferenceInconsistencyStats(string key, int value) { + key = "Inconsistencies - Type inference" and value = getTotalTypeInferenceInconsistencies() +} + /** * Gets summary statistics about taint. */ diff --git a/rust/ql/src/queries/summary/SummaryStats.ql b/rust/ql/src/queries/summary/SummaryStats.ql index 57ac5b4004e..515c78c7268 100644 --- a/rust/ql/src/queries/summary/SummaryStats.ql +++ b/rust/ql/src/queries/summary/SummaryStats.ql @@ -17,5 +17,7 @@ where or inconsistencyStats(key, value) or + typeInferenceInconsistencyStats(key, value) + or taintStats(key, value) select key, value order by key diff --git a/rust/ql/test/query-tests/security/CWE-089/CONSISTENCY/TypeInferenceConsistency.expected b/rust/ql/test/query-tests/security/CWE-089/CONSISTENCY/TypeInferenceConsistency.expected new file mode 100644 index 00000000000..9bd56449240 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-089/CONSISTENCY/TypeInferenceConsistency.expected @@ -0,0 +1,3 @@ +illFormedTypeMention +| sqlx.rs:158:13:158:81 | ...::BoxDynError | +| sqlx.rs:160:17:160:86 | ...::BoxDynError | From e406f27bb379fe95c2a2c2723a3ef52cbc41afbb Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 27 May 2025 11:45:18 +0100 Subject: [PATCH 70/86] Update cpp/ql/lib/ext/Windows.model.yml Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com> --- cpp/ql/lib/ext/Windows.model.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp/ql/lib/ext/Windows.model.yml b/cpp/ql/lib/ext/Windows.model.yml index 89127459f96..cdc4d946496 100644 --- a/cpp/ql/lib/ext/Windows.model.yml +++ b/cpp/ql/lib/ext/Windows.model.yml @@ -11,6 +11,7 @@ extensions: - ["", "", False, "GetEnvironmentStringsW", "", "", "ReturnValue[*]", "local", "manual"] - ["", "", False, "GetEnvironmentVariableA", "", "", "Argument[*1]", "local", "manual"] - ["", "", False, "GetEnvironmentVariableW", "", "", "Argument[*1]", "local", "manual"] + # fileapi.h - ["", "", False, "ReadFile", "", "", "Argument[*1]", "local", "manual"] - ["", "", False, "ReadFileEx", "", "", "Argument[*1]", "local", "manual"] - ["", "", False, "MapViewOfFile", "", "", "ReturnValue[*]", "local", "manual"] From 80229644b89fd496dcfc763a7640f6b7de2a504f Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 27 May 2025 11:45:27 +0100 Subject: [PATCH 71/86] Update cpp/ql/lib/ext/Windows.model.yml Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com> --- cpp/ql/lib/ext/Windows.model.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp/ql/lib/ext/Windows.model.yml b/cpp/ql/lib/ext/Windows.model.yml index cdc4d946496..2c07b773fca 100644 --- a/cpp/ql/lib/ext/Windows.model.yml +++ b/cpp/ql/lib/ext/Windows.model.yml @@ -14,6 +14,7 @@ extensions: # fileapi.h - ["", "", False, "ReadFile", "", "", "Argument[*1]", "local", "manual"] - ["", "", False, "ReadFileEx", "", "", "Argument[*1]", "local", "manual"] + # memoryapi.h - ["", "", False, "MapViewOfFile", "", "", "ReturnValue[*]", "local", "manual"] - ["", "", False, "MapViewOfFile2", "", "", "ReturnValue[*]", "local", "manual"] - ["", "", False, "MapViewOfFile3", "", "", "ReturnValue[*]", "local", "manual"] From a05ddca9c94f2ecda541ac583f6c3f8b935d7e20 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 27 May 2025 11:45:35 +0100 Subject: [PATCH 72/86] Update cpp/ql/lib/ext/Windows.model.yml Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com> --- cpp/ql/lib/ext/Windows.model.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp/ql/lib/ext/Windows.model.yml b/cpp/ql/lib/ext/Windows.model.yml index 2c07b773fca..3dcde03f9a1 100644 --- a/cpp/ql/lib/ext/Windows.model.yml +++ b/cpp/ql/lib/ext/Windows.model.yml @@ -22,6 +22,7 @@ extensions: - ["", "", False, "MapViewOfFileEx", "", "", "ReturnValue[*]", "local", "manual"] - ["", "", False, "MapViewOfFileFromApp", "", "", "ReturnValue[*]", "local", "manual"] - ["", "", False, "MapViewOfFileNuma2", "", "", "ReturnValue[*]", "local", "manual"] + # ntifs.h - ["", "", False, "NtReadFile", "", "", "Argument[*5]", "local", "manual"] - addsTo: pack: codeql/cpp-all From ac724d2671df66ad4247850850743949de95db90 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Tue, 27 May 2025 13:08:20 +0200 Subject: [PATCH 73/86] Update rust/extractor/src/main.rs Co-authored-by: Simon Friis Vindum --- rust/extractor/src/main.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/rust/extractor/src/main.rs b/rust/extractor/src/main.rs index fd827f46d7c..928542c5422 100644 --- a/rust/extractor/src/main.rs +++ b/rust/extractor/src/main.rs @@ -277,15 +277,10 @@ fn main() -> anyhow::Result<()> { } else { ResolvePaths::Yes }; - let library_mode = if cfg.extract_dependencies_as_source { - SourceKind::Source + let (library_mode, library_resolve_paths) = if cfg.extract_dependencies_as_source { + (SourceKind::Source, resolve_paths) } else { - SourceKind::Library - }; - let library_resolve_paths = if cfg.extract_dependencies_as_source { - resolve_paths - } else { - ResolvePaths::No + (SourceKind::Library, ResolvePaths::No) }; let mut processed_files: HashSet = HashSet::from_iter(files.iter().cloned()); From c1ee56e4c174893d26059bd6aa65da0ea46d9335 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 27 May 2025 12:05:30 +0100 Subject: [PATCH 74/86] C++: Add ReadFileEx tests with missing flow. --- .../dataflow/external-models/flow.expected | 116 +++++++++--------- .../dataflow/external-models/sources.expected | 24 ++-- .../dataflow/external-models/windows.cpp | 37 ++++++ 3 files changed, 109 insertions(+), 68 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected index c8babcb1454..0560a4da865 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected @@ -48,30 +48,30 @@ edges | windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | provenance | Src:MaD:327 | | windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | windows.cpp:25:10:25:13 | * ... | provenance | | | windows.cpp:28:36:28:38 | GetEnvironmentVariableA output argument | windows.cpp:30:10:30:13 | * ... | provenance | Src:MaD:329 | -| windows.cpp:145:35:145:40 | ReadFile output argument | windows.cpp:147:10:147:16 | * ... | provenance | Src:MaD:331 | -| windows.cpp:154:23:154:28 | ReadFileEx output argument | windows.cpp:156:10:156:16 | * ... | provenance | Src:MaD:332 | -| windows.cpp:168:84:168:89 | NtReadFile output argument | windows.cpp:170:10:170:16 | * ... | provenance | Src:MaD:340 | -| windows.cpp:245:23:245:35 | *call to MapViewOfFile | windows.cpp:245:23:245:35 | *call to MapViewOfFile | provenance | Src:MaD:333 | -| windows.cpp:245:23:245:35 | *call to MapViewOfFile | windows.cpp:246:20:246:52 | *pMapView | provenance | | -| windows.cpp:246:20:246:52 | *pMapView | windows.cpp:248:10:248:16 | * ... | provenance | | -| windows.cpp:252:23:252:36 | *call to MapViewOfFile2 | windows.cpp:252:23:252:36 | *call to MapViewOfFile2 | provenance | Src:MaD:334 | -| windows.cpp:252:23:252:36 | *call to MapViewOfFile2 | windows.cpp:253:20:253:52 | *pMapView | provenance | | -| windows.cpp:253:20:253:52 | *pMapView | windows.cpp:255:10:255:16 | * ... | provenance | | -| windows.cpp:261:23:261:36 | *call to MapViewOfFile3 | windows.cpp:261:23:261:36 | *call to MapViewOfFile3 | provenance | Src:MaD:335 | -| windows.cpp:261:23:261:36 | *call to MapViewOfFile3 | windows.cpp:262:20:262:52 | *pMapView | provenance | | -| windows.cpp:262:20:262:52 | *pMapView | windows.cpp:264:10:264:16 | * ... | provenance | | -| windows.cpp:270:23:270:43 | *call to MapViewOfFile3FromApp | windows.cpp:270:23:270:43 | *call to MapViewOfFile3FromApp | provenance | Src:MaD:336 | -| windows.cpp:270:23:270:43 | *call to MapViewOfFile3FromApp | windows.cpp:271:20:271:52 | *pMapView | provenance | | -| windows.cpp:271:20:271:52 | *pMapView | windows.cpp:273:10:273:16 | * ... | provenance | | -| windows.cpp:277:23:277:37 | *call to MapViewOfFileEx | windows.cpp:277:23:277:37 | *call to MapViewOfFileEx | provenance | Src:MaD:337 | -| windows.cpp:277:23:277:37 | *call to MapViewOfFileEx | windows.cpp:278:20:278:52 | *pMapView | provenance | | -| windows.cpp:278:20:278:52 | *pMapView | windows.cpp:280:10:280:16 | * ... | provenance | | -| windows.cpp:284:23:284:42 | *call to MapViewOfFileFromApp | windows.cpp:284:23:284:42 | *call to MapViewOfFileFromApp | provenance | Src:MaD:338 | -| windows.cpp:284:23:284:42 | *call to MapViewOfFileFromApp | windows.cpp:285:20:285:52 | *pMapView | provenance | | -| windows.cpp:285:20:285:52 | *pMapView | windows.cpp:287:10:287:16 | * ... | provenance | | -| windows.cpp:291:23:291:40 | *call to MapViewOfFileNuma2 | windows.cpp:291:23:291:40 | *call to MapViewOfFileNuma2 | provenance | Src:MaD:339 | -| windows.cpp:291:23:291:40 | *call to MapViewOfFileNuma2 | windows.cpp:292:20:292:52 | *pMapView | provenance | | -| windows.cpp:292:20:292:52 | *pMapView | windows.cpp:294:10:294:16 | * ... | provenance | | +| windows.cpp:164:35:164:40 | ReadFile output argument | windows.cpp:166:10:166:16 | * ... | provenance | Src:MaD:331 | +| windows.cpp:173:23:173:28 | ReadFileEx output argument | windows.cpp:175:10:175:16 | * ... | provenance | Src:MaD:332 | +| windows.cpp:205:84:205:89 | NtReadFile output argument | windows.cpp:207:10:207:16 | * ... | provenance | Src:MaD:340 | +| windows.cpp:282:23:282:35 | *call to MapViewOfFile | windows.cpp:282:23:282:35 | *call to MapViewOfFile | provenance | Src:MaD:333 | +| windows.cpp:282:23:282:35 | *call to MapViewOfFile | windows.cpp:283:20:283:52 | *pMapView | provenance | | +| windows.cpp:283:20:283:52 | *pMapView | windows.cpp:285:10:285:16 | * ... | provenance | | +| windows.cpp:289:23:289:36 | *call to MapViewOfFile2 | windows.cpp:289:23:289:36 | *call to MapViewOfFile2 | provenance | Src:MaD:334 | +| windows.cpp:289:23:289:36 | *call to MapViewOfFile2 | windows.cpp:290:20:290:52 | *pMapView | provenance | | +| windows.cpp:290:20:290:52 | *pMapView | windows.cpp:292:10:292:16 | * ... | provenance | | +| windows.cpp:298:23:298:36 | *call to MapViewOfFile3 | windows.cpp:298:23:298:36 | *call to MapViewOfFile3 | provenance | Src:MaD:335 | +| windows.cpp:298:23:298:36 | *call to MapViewOfFile3 | windows.cpp:299:20:299:52 | *pMapView | provenance | | +| windows.cpp:299:20:299:52 | *pMapView | windows.cpp:301:10:301:16 | * ... | provenance | | +| windows.cpp:307:23:307:43 | *call to MapViewOfFile3FromApp | windows.cpp:307:23:307:43 | *call to MapViewOfFile3FromApp | provenance | Src:MaD:336 | +| windows.cpp:307:23:307:43 | *call to MapViewOfFile3FromApp | windows.cpp:308:20:308:52 | *pMapView | provenance | | +| windows.cpp:308:20:308:52 | *pMapView | windows.cpp:310:10:310:16 | * ... | provenance | | +| windows.cpp:314:23:314:37 | *call to MapViewOfFileEx | windows.cpp:314:23:314:37 | *call to MapViewOfFileEx | provenance | Src:MaD:337 | +| windows.cpp:314:23:314:37 | *call to MapViewOfFileEx | windows.cpp:315:20:315:52 | *pMapView | provenance | | +| windows.cpp:315:20:315:52 | *pMapView | windows.cpp:317:10:317:16 | * ... | provenance | | +| windows.cpp:321:23:321:42 | *call to MapViewOfFileFromApp | windows.cpp:321:23:321:42 | *call to MapViewOfFileFromApp | provenance | Src:MaD:338 | +| windows.cpp:321:23:321:42 | *call to MapViewOfFileFromApp | windows.cpp:322:20:322:52 | *pMapView | provenance | | +| windows.cpp:322:20:322:52 | *pMapView | windows.cpp:324:10:324:16 | * ... | provenance | | +| windows.cpp:328:23:328:40 | *call to MapViewOfFileNuma2 | windows.cpp:328:23:328:40 | *call to MapViewOfFileNuma2 | provenance | Src:MaD:339 | +| windows.cpp:328:23:328:40 | *call to MapViewOfFileNuma2 | windows.cpp:329:20:329:52 | *pMapView | provenance | | +| windows.cpp:329:20:329:52 | *pMapView | windows.cpp:331:10:331:16 | * ... | provenance | | nodes | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | semmle.label | [summary param] *0 in buffer | | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | semmle.label | [summary] to write: ReturnValue in buffer | @@ -127,40 +127,40 @@ nodes | windows.cpp:25:10:25:13 | * ... | semmle.label | * ... | | windows.cpp:28:36:28:38 | GetEnvironmentVariableA output argument | semmle.label | GetEnvironmentVariableA output argument | | windows.cpp:30:10:30:13 | * ... | semmle.label | * ... | -| windows.cpp:145:35:145:40 | ReadFile output argument | semmle.label | ReadFile output argument | -| windows.cpp:147:10:147:16 | * ... | semmle.label | * ... | -| windows.cpp:154:23:154:28 | ReadFileEx output argument | semmle.label | ReadFileEx output argument | -| windows.cpp:156:10:156:16 | * ... | semmle.label | * ... | -| windows.cpp:168:84:168:89 | NtReadFile output argument | semmle.label | NtReadFile output argument | -| windows.cpp:170:10:170:16 | * ... | semmle.label | * ... | -| windows.cpp:245:23:245:35 | *call to MapViewOfFile | semmle.label | *call to MapViewOfFile | -| windows.cpp:245:23:245:35 | *call to MapViewOfFile | semmle.label | *call to MapViewOfFile | -| windows.cpp:246:20:246:52 | *pMapView | semmle.label | *pMapView | -| windows.cpp:248:10:248:16 | * ... | semmle.label | * ... | -| windows.cpp:252:23:252:36 | *call to MapViewOfFile2 | semmle.label | *call to MapViewOfFile2 | -| windows.cpp:252:23:252:36 | *call to MapViewOfFile2 | semmle.label | *call to MapViewOfFile2 | -| windows.cpp:253:20:253:52 | *pMapView | semmle.label | *pMapView | -| windows.cpp:255:10:255:16 | * ... | semmle.label | * ... | -| windows.cpp:261:23:261:36 | *call to MapViewOfFile3 | semmle.label | *call to MapViewOfFile3 | -| windows.cpp:261:23:261:36 | *call to MapViewOfFile3 | semmle.label | *call to MapViewOfFile3 | -| windows.cpp:262:20:262:52 | *pMapView | semmle.label | *pMapView | -| windows.cpp:264:10:264:16 | * ... | semmle.label | * ... | -| windows.cpp:270:23:270:43 | *call to MapViewOfFile3FromApp | semmle.label | *call to MapViewOfFile3FromApp | -| windows.cpp:270:23:270:43 | *call to MapViewOfFile3FromApp | semmle.label | *call to MapViewOfFile3FromApp | -| windows.cpp:271:20:271:52 | *pMapView | semmle.label | *pMapView | -| windows.cpp:273:10:273:16 | * ... | semmle.label | * ... | -| windows.cpp:277:23:277:37 | *call to MapViewOfFileEx | semmle.label | *call to MapViewOfFileEx | -| windows.cpp:277:23:277:37 | *call to MapViewOfFileEx | semmle.label | *call to MapViewOfFileEx | -| windows.cpp:278:20:278:52 | *pMapView | semmle.label | *pMapView | -| windows.cpp:280:10:280:16 | * ... | semmle.label | * ... | -| windows.cpp:284:23:284:42 | *call to MapViewOfFileFromApp | semmle.label | *call to MapViewOfFileFromApp | -| windows.cpp:284:23:284:42 | *call to MapViewOfFileFromApp | semmle.label | *call to MapViewOfFileFromApp | -| windows.cpp:285:20:285:52 | *pMapView | semmle.label | *pMapView | -| windows.cpp:287:10:287:16 | * ... | semmle.label | * ... | -| windows.cpp:291:23:291:40 | *call to MapViewOfFileNuma2 | semmle.label | *call to MapViewOfFileNuma2 | -| windows.cpp:291:23:291:40 | *call to MapViewOfFileNuma2 | semmle.label | *call to MapViewOfFileNuma2 | -| windows.cpp:292:20:292:52 | *pMapView | semmle.label | *pMapView | -| windows.cpp:294:10:294:16 | * ... | semmle.label | * ... | +| windows.cpp:164:35:164:40 | ReadFile output argument | semmle.label | ReadFile output argument | +| windows.cpp:166:10:166:16 | * ... | semmle.label | * ... | +| windows.cpp:173:23:173:28 | ReadFileEx output argument | semmle.label | ReadFileEx output argument | +| windows.cpp:175:10:175:16 | * ... | semmle.label | * ... | +| windows.cpp:205:84:205:89 | NtReadFile output argument | semmle.label | NtReadFile output argument | +| windows.cpp:207:10:207:16 | * ... | semmle.label | * ... | +| windows.cpp:282:23:282:35 | *call to MapViewOfFile | semmle.label | *call to MapViewOfFile | +| windows.cpp:282:23:282:35 | *call to MapViewOfFile | semmle.label | *call to MapViewOfFile | +| windows.cpp:283:20:283:52 | *pMapView | semmle.label | *pMapView | +| windows.cpp:285:10:285:16 | * ... | semmle.label | * ... | +| windows.cpp:289:23:289:36 | *call to MapViewOfFile2 | semmle.label | *call to MapViewOfFile2 | +| windows.cpp:289:23:289:36 | *call to MapViewOfFile2 | semmle.label | *call to MapViewOfFile2 | +| windows.cpp:290:20:290:52 | *pMapView | semmle.label | *pMapView | +| windows.cpp:292:10:292:16 | * ... | semmle.label | * ... | +| windows.cpp:298:23:298:36 | *call to MapViewOfFile3 | semmle.label | *call to MapViewOfFile3 | +| windows.cpp:298:23:298:36 | *call to MapViewOfFile3 | semmle.label | *call to MapViewOfFile3 | +| windows.cpp:299:20:299:52 | *pMapView | semmle.label | *pMapView | +| windows.cpp:301:10:301:16 | * ... | semmle.label | * ... | +| windows.cpp:307:23:307:43 | *call to MapViewOfFile3FromApp | semmle.label | *call to MapViewOfFile3FromApp | +| windows.cpp:307:23:307:43 | *call to MapViewOfFile3FromApp | semmle.label | *call to MapViewOfFile3FromApp | +| windows.cpp:308:20:308:52 | *pMapView | semmle.label | *pMapView | +| windows.cpp:310:10:310:16 | * ... | semmle.label | * ... | +| windows.cpp:314:23:314:37 | *call to MapViewOfFileEx | semmle.label | *call to MapViewOfFileEx | +| windows.cpp:314:23:314:37 | *call to MapViewOfFileEx | semmle.label | *call to MapViewOfFileEx | +| windows.cpp:315:20:315:52 | *pMapView | semmle.label | *pMapView | +| windows.cpp:317:10:317:16 | * ... | semmle.label | * ... | +| windows.cpp:321:23:321:42 | *call to MapViewOfFileFromApp | semmle.label | *call to MapViewOfFileFromApp | +| windows.cpp:321:23:321:42 | *call to MapViewOfFileFromApp | semmle.label | *call to MapViewOfFileFromApp | +| windows.cpp:322:20:322:52 | *pMapView | semmle.label | *pMapView | +| windows.cpp:324:10:324:16 | * ... | semmle.label | * ... | +| windows.cpp:328:23:328:40 | *call to MapViewOfFileNuma2 | semmle.label | *call to MapViewOfFileNuma2 | +| windows.cpp:328:23:328:40 | *call to MapViewOfFileNuma2 | semmle.label | *call to MapViewOfFileNuma2 | +| windows.cpp:329:20:329:52 | *pMapView | semmle.label | *pMapView | +| windows.cpp:331:10:331:16 | * ... | semmle.label | * ... | subpaths | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | asio_streams.cpp:100:44:100:62 | call to buffer | | test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/sources.expected b/cpp/ql/test/library-tests/dataflow/external-models/sources.expected index f8d2da8a002..a50ce484e1c 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/sources.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/sources.expected @@ -3,13 +3,17 @@ | windows.cpp:11:15:11:29 | *call to GetCommandLineA | local | | windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | local | | windows.cpp:28:36:28:38 | GetEnvironmentVariableA output argument | local | -| windows.cpp:145:35:145:40 | ReadFile output argument | local | -| windows.cpp:154:23:154:28 | ReadFileEx output argument | local | -| windows.cpp:168:84:168:89 | NtReadFile output argument | local | -| windows.cpp:245:23:245:35 | *call to MapViewOfFile | local | -| windows.cpp:252:23:252:36 | *call to MapViewOfFile2 | local | -| windows.cpp:261:23:261:36 | *call to MapViewOfFile3 | local | -| windows.cpp:270:23:270:43 | *call to MapViewOfFile3FromApp | local | -| windows.cpp:277:23:277:37 | *call to MapViewOfFileEx | local | -| windows.cpp:284:23:284:42 | *call to MapViewOfFileFromApp | local | -| windows.cpp:291:23:291:40 | *call to MapViewOfFileNuma2 | local | +| windows.cpp:164:35:164:40 | ReadFile output argument | local | +| windows.cpp:173:23:173:28 | ReadFileEx output argument | local | +| windows.cpp:185:21:185:26 | ReadFile output argument | local | +| windows.cpp:188:23:188:29 | ReadFileEx output argument | local | +| windows.cpp:194:21:194:26 | ReadFile output argument | local | +| windows.cpp:197:23:197:29 | ReadFileEx output argument | local | +| windows.cpp:205:84:205:89 | NtReadFile output argument | local | +| windows.cpp:282:23:282:35 | *call to MapViewOfFile | local | +| windows.cpp:289:23:289:36 | *call to MapViewOfFile2 | local | +| windows.cpp:298:23:298:36 | *call to MapViewOfFile3 | local | +| windows.cpp:307:23:307:43 | *call to MapViewOfFile3FromApp | local | +| windows.cpp:314:23:314:37 | *call to MapViewOfFileEx | local | +| windows.cpp:321:23:321:42 | *call to MapViewOfFileFromApp | local | +| windows.cpp:328:23:328:40 | *call to MapViewOfFileNuma2 | local | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp b/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp index 382f534dde8..eb08d9d350a 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp +++ b/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp @@ -137,6 +137,25 @@ void FileIOCompletionRoutine( sink(*buffer); // $ MISSING: ir } +void FileIOCompletionRoutine2( + DWORD dwErrorCode, + DWORD dwNumberOfBytesTransfered, + LPOVERLAPPED lpOverlapped +) { + char* buffer = reinterpret_cast(lpOverlapped->hEvent); + sink(buffer); + sink(*buffer); // $ MISSING: ir +} + +void FileIOCompletionRoutine3( + DWORD dwErrorCode, + DWORD dwNumberOfBytesTransfered, + LPOVERLAPPED lpOverlapped +) { + char c = reinterpret_cast(lpOverlapped->hEvent); + sink(c); // $ MISSING: ir +} + void readFile(HANDLE hFile) { { char buffer[1024]; @@ -159,6 +178,24 @@ void readFile(HANDLE hFile) { sink(p); sink(*p); // $ MISSING: ir } + + { + char buffer[1024]; + OVERLAPPED overlapped; + ReadFile(hFile, buffer, sizeof(buffer), nullptr, nullptr); + overlapped.hEvent = reinterpret_cast(buffer); + char buffer2[1024]; + ReadFileEx(hFile, buffer2, sizeof(buffer2) - 1, &overlapped, FileIOCompletionRoutine2); + } + + { + char buffer[1024]; + OVERLAPPED overlapped; + ReadFile(hFile, buffer, sizeof(buffer), nullptr, nullptr); + overlapped.hEvent = reinterpret_cast(*buffer); + char buffer2[1024]; + ReadFileEx(hFile, buffer2, sizeof(buffer2) - 1, &overlapped, FileIOCompletionRoutine3); + } { char buffer[1024]; From 76c2d24a7ef427282492df98dea2234c50174496 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 27 May 2025 12:09:19 +0100 Subject: [PATCH 75/86] C++: Add summary for ReadFileEx and accept test changes. --- cpp/ql/lib/ext/Windows.model.yml | 2 + .../dataflow/external-models/flow.expected | 78 ++++++++++++++++--- .../external-models/validatemodels.expected | 4 + .../dataflow/external-models/windows.cpp | 4 +- 4 files changed, 74 insertions(+), 14 deletions(-) diff --git a/cpp/ql/lib/ext/Windows.model.yml b/cpp/ql/lib/ext/Windows.model.yml index 3dcde03f9a1..8bfb3f48b91 100644 --- a/cpp/ql/lib/ext/Windows.model.yml +++ b/cpp/ql/lib/ext/Windows.model.yml @@ -31,3 +31,5 @@ extensions: # shellapi.h - ["", "", False, "CommandLineToArgvA", "", "", "Argument[*0]", "ReturnValue[**]", "taint", "manual"] - ["", "", False, "CommandLineToArgvW", "", "", "Argument[*0]", "ReturnValue[**]", "taint", "manual"] + # fileapi.h + - ["", "", False, "ReadFileEx", "", "", "Argument[*3].Field[@hEvent]", "Argument[4].Parameter[*2].Field[@hEvent]", "value", "manual"] \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected index 0560a4da865..4f333d4c36f 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected @@ -10,31 +10,31 @@ edges | asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:6 | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:10 | -| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:23507 | -| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:23508 | -| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:23509 | +| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:23508 | +| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:23509 | +| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:23510 | | test.cpp:7:47:7:52 | value2 | test.cpp:7:64:7:69 | value2 | provenance | | | test.cpp:7:64:7:69 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | provenance | | -| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:10:10:10:18 | call to ymlSource | provenance | Src:MaD:23505 | -| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:14:10:14:10 | x | provenance | Sink:MaD:23506 | +| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:10:10:10:18 | call to ymlSource | provenance | Src:MaD:23506 | +| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:14:10:14:10 | x | provenance | Sink:MaD:23507 | | test.cpp:10:10:10:18 | call to ymlSource | test.cpp:17:24:17:24 | x | provenance | | | test.cpp:10:10:10:18 | call to ymlSource | test.cpp:21:27:21:27 | x | provenance | | | test.cpp:10:10:10:18 | call to ymlSource | test.cpp:25:35:25:35 | x | provenance | | | test.cpp:10:10:10:18 | call to ymlSource | test.cpp:32:41:32:41 | x | provenance | | | test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | | -| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:18:10:18:10 | y | provenance | Sink:MaD:23506 | +| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:18:10:18:10 | y | provenance | Sink:MaD:23507 | | test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | provenance | | -| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:23507 | +| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:23508 | | test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | | -| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:22:10:22:10 | z | provenance | Sink:MaD:23506 | +| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:22:10:22:10 | z | provenance | Sink:MaD:23507 | | test.cpp:21:27:21:27 | x | test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | provenance | | -| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:23508 | +| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:23509 | | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | | -| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:26:10:26:11 | y2 | provenance | Sink:MaD:23506 | +| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:26:10:26:11 | y2 | provenance | Sink:MaD:23507 | | test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | provenance | | -| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:23509 | +| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:23510 | | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | provenance | | -| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:33:10:33:11 | z2 | provenance | Sink:MaD:23506 | +| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:33:10:33:11 | z2 | provenance | Sink:MaD:23507 | | test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | provenance | | | test.cpp:32:41:32:41 | x | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | provenance | | | windows.cpp:6:8:6:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:6:8:6:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:341 | @@ -48,8 +48,35 @@ edges | windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | provenance | Src:MaD:327 | | windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | windows.cpp:25:10:25:13 | * ... | provenance | | | windows.cpp:28:36:28:38 | GetEnvironmentVariableA output argument | windows.cpp:30:10:30:13 | * ... | provenance | Src:MaD:329 | +| windows.cpp:86:6:86:15 | [summary param] *3 in ReadFileEx [*hEvent] | windows.cpp:86:6:86:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | provenance | | +| windows.cpp:86:6:86:15 | [summary param] *3 in ReadFileEx [hEvent] | windows.cpp:86:6:86:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | provenance | | +| windows.cpp:86:6:86:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | provenance | MaD:343 | +| windows.cpp:86:6:86:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | provenance | MaD:343 | +| windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | windows.cpp:143:16:143:27 | *lpOverlapped [*hEvent] | provenance | | +| windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] | windows.cpp:153:16:153:27 | *lpOverlapped [hEvent] | provenance | | +| windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | provenance | | +| windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] | provenance | | +| windows.cpp:143:16:143:27 | *lpOverlapped [*hEvent] | windows.cpp:145:42:145:53 | *lpOverlapped [*hEvent] | provenance | | +| windows.cpp:145:18:145:62 | *hEvent | windows.cpp:145:18:145:62 | *hEvent | provenance | | +| windows.cpp:145:18:145:62 | *hEvent | windows.cpp:147:8:147:14 | * ... | provenance | | +| windows.cpp:145:42:145:53 | *lpOverlapped [*hEvent] | windows.cpp:145:18:145:62 | *hEvent | provenance | | +| windows.cpp:145:42:145:53 | *lpOverlapped [*hEvent] | windows.cpp:145:56:145:61 | *hEvent | provenance | | +| windows.cpp:145:56:145:61 | *hEvent | windows.cpp:145:18:145:62 | *hEvent | provenance | | +| windows.cpp:153:16:153:27 | *lpOverlapped [hEvent] | windows.cpp:155:35:155:46 | *lpOverlapped [hEvent] | provenance | | +| windows.cpp:155:12:155:55 | hEvent | windows.cpp:155:12:155:55 | hEvent | provenance | | +| windows.cpp:155:12:155:55 | hEvent | windows.cpp:156:8:156:8 | c | provenance | | +| windows.cpp:155:35:155:46 | *lpOverlapped [hEvent] | windows.cpp:155:12:155:55 | hEvent | provenance | | +| windows.cpp:155:35:155:46 | *lpOverlapped [hEvent] | windows.cpp:155:12:155:55 | hEvent | provenance | | | windows.cpp:164:35:164:40 | ReadFile output argument | windows.cpp:166:10:166:16 | * ... | provenance | Src:MaD:331 | | windows.cpp:173:23:173:28 | ReadFileEx output argument | windows.cpp:175:10:175:16 | * ... | provenance | Src:MaD:332 | +| windows.cpp:185:21:185:26 | ReadFile output argument | windows.cpp:186:5:186:56 | *... = ... | provenance | Src:MaD:331 | +| windows.cpp:186:5:186:14 | *overlapped [post update] [*hEvent] | windows.cpp:188:53:188:63 | *& ... [*hEvent] | provenance | | +| windows.cpp:186:5:186:56 | *... = ... | windows.cpp:186:5:186:14 | *overlapped [post update] [*hEvent] | provenance | | +| windows.cpp:188:53:188:63 | *& ... [*hEvent] | windows.cpp:86:6:86:15 | [summary param] *3 in ReadFileEx [*hEvent] | provenance | | +| windows.cpp:194:21:194:26 | ReadFile output argument | windows.cpp:195:5:195:57 | ... = ... | provenance | Src:MaD:331 | +| windows.cpp:195:5:195:14 | *overlapped [post update] [hEvent] | windows.cpp:197:53:197:63 | *& ... [hEvent] | provenance | | +| windows.cpp:195:5:195:57 | ... = ... | windows.cpp:195:5:195:14 | *overlapped [post update] [hEvent] | provenance | | +| windows.cpp:197:53:197:63 | *& ... [hEvent] | windows.cpp:86:6:86:15 | [summary param] *3 in ReadFileEx [hEvent] | provenance | | | windows.cpp:205:84:205:89 | NtReadFile output argument | windows.cpp:207:10:207:16 | * ... | provenance | Src:MaD:340 | | windows.cpp:282:23:282:35 | *call to MapViewOfFile | windows.cpp:282:23:282:35 | *call to MapViewOfFile | provenance | Src:MaD:333 | | windows.cpp:282:23:282:35 | *call to MapViewOfFile | windows.cpp:283:20:283:52 | *pMapView | provenance | | @@ -127,10 +154,37 @@ nodes | windows.cpp:25:10:25:13 | * ... | semmle.label | * ... | | windows.cpp:28:36:28:38 | GetEnvironmentVariableA output argument | semmle.label | GetEnvironmentVariableA output argument | | windows.cpp:30:10:30:13 | * ... | semmle.label | * ... | +| windows.cpp:86:6:86:15 | [summary param] *3 in ReadFileEx [*hEvent] | semmle.label | [summary param] *3 in ReadFileEx [*hEvent] | +| windows.cpp:86:6:86:15 | [summary param] *3 in ReadFileEx [hEvent] | semmle.label | [summary param] *3 in ReadFileEx [hEvent] | +| windows.cpp:86:6:86:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | semmle.label | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | +| windows.cpp:86:6:86:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | semmle.label | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | +| windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | semmle.label | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | +| windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] | semmle.label | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] | +| windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | semmle.label | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | +| windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | semmle.label | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | +| windows.cpp:143:16:143:27 | *lpOverlapped [*hEvent] | semmle.label | *lpOverlapped [*hEvent] | +| windows.cpp:145:18:145:62 | *hEvent | semmle.label | *hEvent | +| windows.cpp:145:18:145:62 | *hEvent | semmle.label | *hEvent | +| windows.cpp:145:42:145:53 | *lpOverlapped [*hEvent] | semmle.label | *lpOverlapped [*hEvent] | +| windows.cpp:145:56:145:61 | *hEvent | semmle.label | *hEvent | +| windows.cpp:147:8:147:14 | * ... | semmle.label | * ... | +| windows.cpp:153:16:153:27 | *lpOverlapped [hEvent] | semmle.label | *lpOverlapped [hEvent] | +| windows.cpp:155:12:155:55 | hEvent | semmle.label | hEvent | +| windows.cpp:155:12:155:55 | hEvent | semmle.label | hEvent | +| windows.cpp:155:35:155:46 | *lpOverlapped [hEvent] | semmle.label | *lpOverlapped [hEvent] | +| windows.cpp:156:8:156:8 | c | semmle.label | c | | windows.cpp:164:35:164:40 | ReadFile output argument | semmle.label | ReadFile output argument | | windows.cpp:166:10:166:16 | * ... | semmle.label | * ... | | windows.cpp:173:23:173:28 | ReadFileEx output argument | semmle.label | ReadFileEx output argument | | windows.cpp:175:10:175:16 | * ... | semmle.label | * ... | +| windows.cpp:185:21:185:26 | ReadFile output argument | semmle.label | ReadFile output argument | +| windows.cpp:186:5:186:14 | *overlapped [post update] [*hEvent] | semmle.label | *overlapped [post update] [*hEvent] | +| windows.cpp:186:5:186:56 | *... = ... | semmle.label | *... = ... | +| windows.cpp:188:53:188:63 | *& ... [*hEvent] | semmle.label | *& ... [*hEvent] | +| windows.cpp:194:21:194:26 | ReadFile output argument | semmle.label | ReadFile output argument | +| windows.cpp:195:5:195:14 | *overlapped [post update] [hEvent] | semmle.label | *overlapped [post update] [hEvent] | +| windows.cpp:195:5:195:57 | ... = ... | semmle.label | ... = ... | +| windows.cpp:197:53:197:63 | *& ... [hEvent] | semmle.label | *& ... [hEvent] | | windows.cpp:205:84:205:89 | NtReadFile output argument | semmle.label | NtReadFile output argument | | windows.cpp:207:10:207:16 | * ... | semmle.label | * ... | | windows.cpp:282:23:282:35 | *call to MapViewOfFile | semmle.label | *call to MapViewOfFile | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected b/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected index ff5ad36e15c..a1511035d9e 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected @@ -3771,3 +3771,7 @@ | Dubious signature "(wchar_t *)" in summary model. | | Dubious signature "(wchar_t, const CStringT &)" in summary model. | | Dubious signature "(wchar_t,const CStringT &)" in summary model. | +| Unrecognized input specification "Field[****hEvent]" in summary model. | +| Unrecognized input specification "Field[***hEvent]" in summary model. | +| Unrecognized output specification "Field[****hEvent]" in summary model. | +| Unrecognized output specification "Field[***hEvent]" in summary model. | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp b/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp index eb08d9d350a..3d45afc6609 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp +++ b/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp @@ -144,7 +144,7 @@ void FileIOCompletionRoutine2( ) { char* buffer = reinterpret_cast(lpOverlapped->hEvent); sink(buffer); - sink(*buffer); // $ MISSING: ir + sink(*buffer); // $ ir } void FileIOCompletionRoutine3( @@ -153,7 +153,7 @@ void FileIOCompletionRoutine3( LPOVERLAPPED lpOverlapped ) { char c = reinterpret_cast(lpOverlapped->hEvent); - sink(c); // $ MISSING: ir + sink(c); // $ ir } void readFile(HANDLE hFile) { From c236084043b7ae57e3196d293ee162a7e7f0c5f4 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 27 May 2025 14:58:18 +0100 Subject: [PATCH 76/86] Go: Explicitly check whether proxy env vars are empty --- go/extractor/util/registryproxy.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/go/extractor/util/registryproxy.go b/go/extractor/util/registryproxy.go index 43eaa461032..301d45896d2 100644 --- a/go/extractor/util/registryproxy.go +++ b/go/extractor/util/registryproxy.go @@ -50,8 +50,8 @@ func parseRegistryConfigs(str string) ([]RegistryConfig, error) { func getEnvVars() []string { var result []string - if proxy_host, proxy_host_set := os.LookupEnv(PROXY_HOST); proxy_host_set { - if proxy_port, proxy_port_set := os.LookupEnv(PROXY_PORT); proxy_port_set { + if proxy_host, proxy_host_set := os.LookupEnv(PROXY_HOST); proxy_host_set && proxy_host != "" { + if proxy_port, proxy_port_set := os.LookupEnv(PROXY_PORT); proxy_port_set && proxy_port != "" { proxy_address = fmt.Sprintf("http://%s:%s", proxy_host, proxy_port) result = append(result, fmt.Sprintf("HTTP_PROXY=%s", proxy_address), fmt.Sprintf("HTTPS_PROXY=%s", proxy_address)) @@ -59,7 +59,7 @@ func getEnvVars() []string { } } - if proxy_cert, proxy_cert_set := os.LookupEnv(PROXY_CA_CERTIFICATE); proxy_cert_set { + if proxy_cert, proxy_cert_set := os.LookupEnv(PROXY_CA_CERTIFICATE); proxy_cert_set && proxy_cert != "" { // Write the certificate to a temporary file slog.Info("Found certificate") @@ -82,7 +82,7 @@ func getEnvVars() []string { } } - if proxy_urls, proxy_urls_set := os.LookupEnv(PROXY_URLS); proxy_urls_set { + if proxy_urls, proxy_urls_set := os.LookupEnv(PROXY_URLS); proxy_urls_set && proxy_urls != "" { val, err := parseRegistryConfigs(proxy_urls) if err != nil { slog.Error("Unable to parse proxy configurations", slog.String("error", err.Error())) From ae67948a677395dd7d7ef23536cb50a13d1cae7f Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 27 May 2025 16:55:26 +0200 Subject: [PATCH 77/86] C++: Fix formatting in model files --- cpp/ql/lib/ext/Boost.Asio.model.yml | 2 +- cpp/ql/lib/ext/Windows.model.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/ext/Boost.Asio.model.yml b/cpp/ql/lib/ext/Boost.Asio.model.yml index 3b6fb77071f..f6ba957d259 100644 --- a/cpp/ql/lib/ext/Boost.Asio.model.yml +++ b/cpp/ql/lib/ext/Boost.Asio.model.yml @@ -1,4 +1,4 @@ - # partial model of the Boost::Asio network library +# partial model of the Boost::Asio network library extensions: - addsTo: pack: codeql/cpp-all diff --git a/cpp/ql/lib/ext/Windows.model.yml b/cpp/ql/lib/ext/Windows.model.yml index 8bfb3f48b91..810a98de85d 100644 --- a/cpp/ql/lib/ext/Windows.model.yml +++ b/cpp/ql/lib/ext/Windows.model.yml @@ -1,4 +1,4 @@ - # partial model of windows system calls +# partial model of windows system calls extensions: - addsTo: pack: codeql/cpp-all From ae266546a650395584abcbfdaa85d38bad4c78ef Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 27 May 2025 16:57:23 +0200 Subject: [PATCH 78/86] C++: Minor test clean up --- .../dataflow/external-models/flow.expected | 276 +++++++++--------- .../dataflow/external-models/sources.expected | 34 +-- .../dataflow/external-models/steps.expected | 2 +- .../dataflow/external-models/windows.cpp | 26 +- 4 files changed, 171 insertions(+), 167 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected index 4f333d4c36f..a4f7767db56 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected @@ -37,68 +37,68 @@ edges | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:33:10:33:11 | z2 | provenance | Sink:MaD:23507 | | test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | provenance | | | test.cpp:32:41:32:41 | x | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | provenance | | -| windows.cpp:6:8:6:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:6:8:6:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:341 | -| windows.cpp:11:15:11:29 | *call to GetCommandLineA | windows.cpp:11:15:11:29 | *call to GetCommandLineA | provenance | Src:MaD:325 | -| windows.cpp:11:15:11:29 | *call to GetCommandLineA | windows.cpp:13:8:13:11 | * ... | provenance | | -| windows.cpp:11:15:11:29 | *call to GetCommandLineA | windows.cpp:16:36:16:38 | *cmd | provenance | | -| windows.cpp:16:17:16:34 | **call to CommandLineToArgvA | windows.cpp:16:17:16:34 | **call to CommandLineToArgvA | provenance | | -| windows.cpp:16:17:16:34 | **call to CommandLineToArgvA | windows.cpp:19:8:19:15 | * ... | provenance | | -| windows.cpp:16:36:16:38 | *cmd | windows.cpp:6:8:6:25 | [summary param] *0 in CommandLineToArgvA | provenance | | -| windows.cpp:16:36:16:38 | *cmd | windows.cpp:16:17:16:34 | **call to CommandLineToArgvA | provenance | MaD:341 | -| windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | provenance | Src:MaD:327 | -| windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | windows.cpp:25:10:25:13 | * ... | provenance | | -| windows.cpp:28:36:28:38 | GetEnvironmentVariableA output argument | windows.cpp:30:10:30:13 | * ... | provenance | Src:MaD:329 | -| windows.cpp:86:6:86:15 | [summary param] *3 in ReadFileEx [*hEvent] | windows.cpp:86:6:86:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | provenance | | -| windows.cpp:86:6:86:15 | [summary param] *3 in ReadFileEx [hEvent] | windows.cpp:86:6:86:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | provenance | | -| windows.cpp:86:6:86:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | provenance | MaD:343 | -| windows.cpp:86:6:86:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | provenance | MaD:343 | -| windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | windows.cpp:143:16:143:27 | *lpOverlapped [*hEvent] | provenance | | -| windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] | windows.cpp:153:16:153:27 | *lpOverlapped [hEvent] | provenance | | -| windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | provenance | | -| windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] | provenance | | -| windows.cpp:143:16:143:27 | *lpOverlapped [*hEvent] | windows.cpp:145:42:145:53 | *lpOverlapped [*hEvent] | provenance | | -| windows.cpp:145:18:145:62 | *hEvent | windows.cpp:145:18:145:62 | *hEvent | provenance | | -| windows.cpp:145:18:145:62 | *hEvent | windows.cpp:147:8:147:14 | * ... | provenance | | -| windows.cpp:145:42:145:53 | *lpOverlapped [*hEvent] | windows.cpp:145:18:145:62 | *hEvent | provenance | | -| windows.cpp:145:42:145:53 | *lpOverlapped [*hEvent] | windows.cpp:145:56:145:61 | *hEvent | provenance | | -| windows.cpp:145:56:145:61 | *hEvent | windows.cpp:145:18:145:62 | *hEvent | provenance | | -| windows.cpp:153:16:153:27 | *lpOverlapped [hEvent] | windows.cpp:155:35:155:46 | *lpOverlapped [hEvent] | provenance | | -| windows.cpp:155:12:155:55 | hEvent | windows.cpp:155:12:155:55 | hEvent | provenance | | -| windows.cpp:155:12:155:55 | hEvent | windows.cpp:156:8:156:8 | c | provenance | | -| windows.cpp:155:35:155:46 | *lpOverlapped [hEvent] | windows.cpp:155:12:155:55 | hEvent | provenance | | -| windows.cpp:155:35:155:46 | *lpOverlapped [hEvent] | windows.cpp:155:12:155:55 | hEvent | provenance | | -| windows.cpp:164:35:164:40 | ReadFile output argument | windows.cpp:166:10:166:16 | * ... | provenance | Src:MaD:331 | -| windows.cpp:173:23:173:28 | ReadFileEx output argument | windows.cpp:175:10:175:16 | * ... | provenance | Src:MaD:332 | -| windows.cpp:185:21:185:26 | ReadFile output argument | windows.cpp:186:5:186:56 | *... = ... | provenance | Src:MaD:331 | -| windows.cpp:186:5:186:14 | *overlapped [post update] [*hEvent] | windows.cpp:188:53:188:63 | *& ... [*hEvent] | provenance | | -| windows.cpp:186:5:186:56 | *... = ... | windows.cpp:186:5:186:14 | *overlapped [post update] [*hEvent] | provenance | | -| windows.cpp:188:53:188:63 | *& ... [*hEvent] | windows.cpp:86:6:86:15 | [summary param] *3 in ReadFileEx [*hEvent] | provenance | | -| windows.cpp:194:21:194:26 | ReadFile output argument | windows.cpp:195:5:195:57 | ... = ... | provenance | Src:MaD:331 | -| windows.cpp:195:5:195:14 | *overlapped [post update] [hEvent] | windows.cpp:197:53:197:63 | *& ... [hEvent] | provenance | | -| windows.cpp:195:5:195:57 | ... = ... | windows.cpp:195:5:195:14 | *overlapped [post update] [hEvent] | provenance | | -| windows.cpp:197:53:197:63 | *& ... [hEvent] | windows.cpp:86:6:86:15 | [summary param] *3 in ReadFileEx [hEvent] | provenance | | -| windows.cpp:205:84:205:89 | NtReadFile output argument | windows.cpp:207:10:207:16 | * ... | provenance | Src:MaD:340 | -| windows.cpp:282:23:282:35 | *call to MapViewOfFile | windows.cpp:282:23:282:35 | *call to MapViewOfFile | provenance | Src:MaD:333 | -| windows.cpp:282:23:282:35 | *call to MapViewOfFile | windows.cpp:283:20:283:52 | *pMapView | provenance | | -| windows.cpp:283:20:283:52 | *pMapView | windows.cpp:285:10:285:16 | * ... | provenance | | -| windows.cpp:289:23:289:36 | *call to MapViewOfFile2 | windows.cpp:289:23:289:36 | *call to MapViewOfFile2 | provenance | Src:MaD:334 | -| windows.cpp:289:23:289:36 | *call to MapViewOfFile2 | windows.cpp:290:20:290:52 | *pMapView | provenance | | -| windows.cpp:290:20:290:52 | *pMapView | windows.cpp:292:10:292:16 | * ... | provenance | | -| windows.cpp:298:23:298:36 | *call to MapViewOfFile3 | windows.cpp:298:23:298:36 | *call to MapViewOfFile3 | provenance | Src:MaD:335 | -| windows.cpp:298:23:298:36 | *call to MapViewOfFile3 | windows.cpp:299:20:299:52 | *pMapView | provenance | | -| windows.cpp:299:20:299:52 | *pMapView | windows.cpp:301:10:301:16 | * ... | provenance | | -| windows.cpp:307:23:307:43 | *call to MapViewOfFile3FromApp | windows.cpp:307:23:307:43 | *call to MapViewOfFile3FromApp | provenance | Src:MaD:336 | -| windows.cpp:307:23:307:43 | *call to MapViewOfFile3FromApp | windows.cpp:308:20:308:52 | *pMapView | provenance | | -| windows.cpp:308:20:308:52 | *pMapView | windows.cpp:310:10:310:16 | * ... | provenance | | -| windows.cpp:314:23:314:37 | *call to MapViewOfFileEx | windows.cpp:314:23:314:37 | *call to MapViewOfFileEx | provenance | Src:MaD:337 | -| windows.cpp:314:23:314:37 | *call to MapViewOfFileEx | windows.cpp:315:20:315:52 | *pMapView | provenance | | -| windows.cpp:315:20:315:52 | *pMapView | windows.cpp:317:10:317:16 | * ... | provenance | | -| windows.cpp:321:23:321:42 | *call to MapViewOfFileFromApp | windows.cpp:321:23:321:42 | *call to MapViewOfFileFromApp | provenance | Src:MaD:338 | -| windows.cpp:321:23:321:42 | *call to MapViewOfFileFromApp | windows.cpp:322:20:322:52 | *pMapView | provenance | | -| windows.cpp:322:20:322:52 | *pMapView | windows.cpp:324:10:324:16 | * ... | provenance | | -| windows.cpp:328:23:328:40 | *call to MapViewOfFileNuma2 | windows.cpp:328:23:328:40 | *call to MapViewOfFileNuma2 | provenance | Src:MaD:339 | -| windows.cpp:328:23:328:40 | *call to MapViewOfFileNuma2 | windows.cpp:329:20:329:52 | *pMapView | provenance | | -| windows.cpp:329:20:329:52 | *pMapView | windows.cpp:331:10:331:16 | * ... | provenance | | +| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:341 | +| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:22:15:22:29 | *call to GetCommandLineA | provenance | Src:MaD:325 | +| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:24:8:24:11 | * ... | provenance | | +| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:27:36:27:38 | *cmd | provenance | | +| windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | provenance | | +| windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | windows.cpp:30:8:30:15 | * ... | provenance | | +| windows.cpp:27:36:27:38 | *cmd | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | provenance | | +| windows.cpp:27:36:27:38 | *cmd | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | provenance | MaD:341 | +| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | provenance | Src:MaD:327 | +| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | windows.cpp:36:10:36:13 | * ... | provenance | | +| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | windows.cpp:41:10:41:13 | * ... | provenance | Src:MaD:329 | +| windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [*hEvent] | windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | provenance | | +| windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [hEvent] | windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | provenance | | +| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | provenance | MaD:343 | +| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | provenance | MaD:343 | +| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | windows.cpp:147:16:147:27 | *lpOverlapped [*hEvent] | provenance | | +| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] | windows.cpp:157:16:157:27 | *lpOverlapped [hEvent] | provenance | | +| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | provenance | | +| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] | provenance | | +| windows.cpp:147:16:147:27 | *lpOverlapped [*hEvent] | windows.cpp:149:42:149:53 | *lpOverlapped [*hEvent] | provenance | | +| windows.cpp:149:18:149:62 | *hEvent | windows.cpp:149:18:149:62 | *hEvent | provenance | | +| windows.cpp:149:18:149:62 | *hEvent | windows.cpp:151:8:151:14 | * ... | provenance | | +| windows.cpp:149:42:149:53 | *lpOverlapped [*hEvent] | windows.cpp:149:18:149:62 | *hEvent | provenance | | +| windows.cpp:149:42:149:53 | *lpOverlapped [*hEvent] | windows.cpp:149:56:149:61 | *hEvent | provenance | | +| windows.cpp:149:56:149:61 | *hEvent | windows.cpp:149:18:149:62 | *hEvent | provenance | | +| windows.cpp:157:16:157:27 | *lpOverlapped [hEvent] | windows.cpp:159:35:159:46 | *lpOverlapped [hEvent] | provenance | | +| windows.cpp:159:12:159:55 | hEvent | windows.cpp:159:12:159:55 | hEvent | provenance | | +| windows.cpp:159:12:159:55 | hEvent | windows.cpp:160:8:160:8 | c | provenance | | +| windows.cpp:159:35:159:46 | *lpOverlapped [hEvent] | windows.cpp:159:12:159:55 | hEvent | provenance | | +| windows.cpp:159:35:159:46 | *lpOverlapped [hEvent] | windows.cpp:159:12:159:55 | hEvent | provenance | | +| windows.cpp:168:35:168:40 | ReadFile output argument | windows.cpp:170:10:170:16 | * ... | provenance | Src:MaD:331 | +| windows.cpp:177:23:177:28 | ReadFileEx output argument | windows.cpp:179:10:179:16 | * ... | provenance | Src:MaD:332 | +| windows.cpp:189:21:189:26 | ReadFile output argument | windows.cpp:190:5:190:56 | *... = ... | provenance | Src:MaD:331 | +| windows.cpp:190:5:190:14 | *overlapped [post update] [*hEvent] | windows.cpp:192:53:192:63 | *& ... [*hEvent] | provenance | | +| windows.cpp:190:5:190:56 | *... = ... | windows.cpp:190:5:190:14 | *overlapped [post update] [*hEvent] | provenance | | +| windows.cpp:192:53:192:63 | *& ... [*hEvent] | windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [*hEvent] | provenance | | +| windows.cpp:198:21:198:26 | ReadFile output argument | windows.cpp:199:5:199:57 | ... = ... | provenance | Src:MaD:331 | +| windows.cpp:199:5:199:14 | *overlapped [post update] [hEvent] | windows.cpp:201:53:201:63 | *& ... [hEvent] | provenance | | +| windows.cpp:199:5:199:57 | ... = ... | windows.cpp:199:5:199:14 | *overlapped [post update] [hEvent] | provenance | | +| windows.cpp:201:53:201:63 | *& ... [hEvent] | windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [hEvent] | provenance | | +| windows.cpp:209:84:209:89 | NtReadFile output argument | windows.cpp:211:10:211:16 | * ... | provenance | Src:MaD:340 | +| windows.cpp:286:23:286:35 | *call to MapViewOfFile | windows.cpp:286:23:286:35 | *call to MapViewOfFile | provenance | Src:MaD:333 | +| windows.cpp:286:23:286:35 | *call to MapViewOfFile | windows.cpp:287:20:287:52 | *pMapView | provenance | | +| windows.cpp:287:20:287:52 | *pMapView | windows.cpp:289:10:289:16 | * ... | provenance | | +| windows.cpp:293:23:293:36 | *call to MapViewOfFile2 | windows.cpp:293:23:293:36 | *call to MapViewOfFile2 | provenance | Src:MaD:334 | +| windows.cpp:293:23:293:36 | *call to MapViewOfFile2 | windows.cpp:294:20:294:52 | *pMapView | provenance | | +| windows.cpp:294:20:294:52 | *pMapView | windows.cpp:296:10:296:16 | * ... | provenance | | +| windows.cpp:302:23:302:36 | *call to MapViewOfFile3 | windows.cpp:302:23:302:36 | *call to MapViewOfFile3 | provenance | Src:MaD:335 | +| windows.cpp:302:23:302:36 | *call to MapViewOfFile3 | windows.cpp:303:20:303:52 | *pMapView | provenance | | +| windows.cpp:303:20:303:52 | *pMapView | windows.cpp:305:10:305:16 | * ... | provenance | | +| windows.cpp:311:23:311:43 | *call to MapViewOfFile3FromApp | windows.cpp:311:23:311:43 | *call to MapViewOfFile3FromApp | provenance | Src:MaD:336 | +| windows.cpp:311:23:311:43 | *call to MapViewOfFile3FromApp | windows.cpp:312:20:312:52 | *pMapView | provenance | | +| windows.cpp:312:20:312:52 | *pMapView | windows.cpp:314:10:314:16 | * ... | provenance | | +| windows.cpp:318:23:318:37 | *call to MapViewOfFileEx | windows.cpp:318:23:318:37 | *call to MapViewOfFileEx | provenance | Src:MaD:337 | +| windows.cpp:318:23:318:37 | *call to MapViewOfFileEx | windows.cpp:319:20:319:52 | *pMapView | provenance | | +| windows.cpp:319:20:319:52 | *pMapView | windows.cpp:321:10:321:16 | * ... | provenance | | +| windows.cpp:325:23:325:42 | *call to MapViewOfFileFromApp | windows.cpp:325:23:325:42 | *call to MapViewOfFileFromApp | provenance | Src:MaD:338 | +| windows.cpp:325:23:325:42 | *call to MapViewOfFileFromApp | windows.cpp:326:20:326:52 | *pMapView | provenance | | +| windows.cpp:326:20:326:52 | *pMapView | windows.cpp:328:10:328:16 | * ... | provenance | | +| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | provenance | Src:MaD:339 | +| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | windows.cpp:333:20:333:52 | *pMapView | provenance | | +| windows.cpp:333:20:333:52 | *pMapView | windows.cpp:335:10:335:16 | * ... | provenance | | nodes | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | semmle.label | [summary param] *0 in buffer | | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | semmle.label | [summary] to write: ReturnValue in buffer | @@ -140,85 +140,85 @@ nodes | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | semmle.label | call to ymlStepGenerated_with_body | | test.cpp:32:41:32:41 | x | semmle.label | x | | test.cpp:33:10:33:11 | z2 | semmle.label | z2 | -| windows.cpp:6:8:6:25 | [summary param] *0 in CommandLineToArgvA | semmle.label | [summary param] *0 in CommandLineToArgvA | -| windows.cpp:6:8:6:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | semmle.label | [summary] to write: ReturnValue[**] in CommandLineToArgvA | -| windows.cpp:11:15:11:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA | -| windows.cpp:11:15:11:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA | -| windows.cpp:13:8:13:11 | * ... | semmle.label | * ... | -| windows.cpp:16:17:16:34 | **call to CommandLineToArgvA | semmle.label | **call to CommandLineToArgvA | -| windows.cpp:16:17:16:34 | **call to CommandLineToArgvA | semmle.label | **call to CommandLineToArgvA | -| windows.cpp:16:36:16:38 | *cmd | semmle.label | *cmd | -| windows.cpp:19:8:19:15 | * ... | semmle.label | * ... | -| windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | semmle.label | *call to GetEnvironmentStringsA | -| windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | semmle.label | *call to GetEnvironmentStringsA | -| windows.cpp:25:10:25:13 | * ... | semmle.label | * ... | -| windows.cpp:28:36:28:38 | GetEnvironmentVariableA output argument | semmle.label | GetEnvironmentVariableA output argument | -| windows.cpp:30:10:30:13 | * ... | semmle.label | * ... | -| windows.cpp:86:6:86:15 | [summary param] *3 in ReadFileEx [*hEvent] | semmle.label | [summary param] *3 in ReadFileEx [*hEvent] | -| windows.cpp:86:6:86:15 | [summary param] *3 in ReadFileEx [hEvent] | semmle.label | [summary param] *3 in ReadFileEx [hEvent] | -| windows.cpp:86:6:86:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | semmle.label | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | -| windows.cpp:86:6:86:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | semmle.label | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | -| windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | semmle.label | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | -| windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] | semmle.label | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] | -| windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | semmle.label | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | -| windows.cpp:86:6:86:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | semmle.label | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | -| windows.cpp:143:16:143:27 | *lpOverlapped [*hEvent] | semmle.label | *lpOverlapped [*hEvent] | -| windows.cpp:145:18:145:62 | *hEvent | semmle.label | *hEvent | -| windows.cpp:145:18:145:62 | *hEvent | semmle.label | *hEvent | -| windows.cpp:145:42:145:53 | *lpOverlapped [*hEvent] | semmle.label | *lpOverlapped [*hEvent] | -| windows.cpp:145:56:145:61 | *hEvent | semmle.label | *hEvent | -| windows.cpp:147:8:147:14 | * ... | semmle.label | * ... | -| windows.cpp:153:16:153:27 | *lpOverlapped [hEvent] | semmle.label | *lpOverlapped [hEvent] | -| windows.cpp:155:12:155:55 | hEvent | semmle.label | hEvent | -| windows.cpp:155:12:155:55 | hEvent | semmle.label | hEvent | -| windows.cpp:155:35:155:46 | *lpOverlapped [hEvent] | semmle.label | *lpOverlapped [hEvent] | -| windows.cpp:156:8:156:8 | c | semmle.label | c | -| windows.cpp:164:35:164:40 | ReadFile output argument | semmle.label | ReadFile output argument | -| windows.cpp:166:10:166:16 | * ... | semmle.label | * ... | -| windows.cpp:173:23:173:28 | ReadFileEx output argument | semmle.label | ReadFileEx output argument | -| windows.cpp:175:10:175:16 | * ... | semmle.label | * ... | -| windows.cpp:185:21:185:26 | ReadFile output argument | semmle.label | ReadFile output argument | -| windows.cpp:186:5:186:14 | *overlapped [post update] [*hEvent] | semmle.label | *overlapped [post update] [*hEvent] | -| windows.cpp:186:5:186:56 | *... = ... | semmle.label | *... = ... | -| windows.cpp:188:53:188:63 | *& ... [*hEvent] | semmle.label | *& ... [*hEvent] | -| windows.cpp:194:21:194:26 | ReadFile output argument | semmle.label | ReadFile output argument | -| windows.cpp:195:5:195:14 | *overlapped [post update] [hEvent] | semmle.label | *overlapped [post update] [hEvent] | -| windows.cpp:195:5:195:57 | ... = ... | semmle.label | ... = ... | -| windows.cpp:197:53:197:63 | *& ... [hEvent] | semmle.label | *& ... [hEvent] | -| windows.cpp:205:84:205:89 | NtReadFile output argument | semmle.label | NtReadFile output argument | -| windows.cpp:207:10:207:16 | * ... | semmle.label | * ... | -| windows.cpp:282:23:282:35 | *call to MapViewOfFile | semmle.label | *call to MapViewOfFile | -| windows.cpp:282:23:282:35 | *call to MapViewOfFile | semmle.label | *call to MapViewOfFile | -| windows.cpp:283:20:283:52 | *pMapView | semmle.label | *pMapView | -| windows.cpp:285:10:285:16 | * ... | semmle.label | * ... | -| windows.cpp:289:23:289:36 | *call to MapViewOfFile2 | semmle.label | *call to MapViewOfFile2 | -| windows.cpp:289:23:289:36 | *call to MapViewOfFile2 | semmle.label | *call to MapViewOfFile2 | -| windows.cpp:290:20:290:52 | *pMapView | semmle.label | *pMapView | -| windows.cpp:292:10:292:16 | * ... | semmle.label | * ... | -| windows.cpp:298:23:298:36 | *call to MapViewOfFile3 | semmle.label | *call to MapViewOfFile3 | -| windows.cpp:298:23:298:36 | *call to MapViewOfFile3 | semmle.label | *call to MapViewOfFile3 | -| windows.cpp:299:20:299:52 | *pMapView | semmle.label | *pMapView | -| windows.cpp:301:10:301:16 | * ... | semmle.label | * ... | -| windows.cpp:307:23:307:43 | *call to MapViewOfFile3FromApp | semmle.label | *call to MapViewOfFile3FromApp | -| windows.cpp:307:23:307:43 | *call to MapViewOfFile3FromApp | semmle.label | *call to MapViewOfFile3FromApp | -| windows.cpp:308:20:308:52 | *pMapView | semmle.label | *pMapView | -| windows.cpp:310:10:310:16 | * ... | semmle.label | * ... | -| windows.cpp:314:23:314:37 | *call to MapViewOfFileEx | semmle.label | *call to MapViewOfFileEx | -| windows.cpp:314:23:314:37 | *call to MapViewOfFileEx | semmle.label | *call to MapViewOfFileEx | -| windows.cpp:315:20:315:52 | *pMapView | semmle.label | *pMapView | -| windows.cpp:317:10:317:16 | * ... | semmle.label | * ... | -| windows.cpp:321:23:321:42 | *call to MapViewOfFileFromApp | semmle.label | *call to MapViewOfFileFromApp | -| windows.cpp:321:23:321:42 | *call to MapViewOfFileFromApp | semmle.label | *call to MapViewOfFileFromApp | -| windows.cpp:322:20:322:52 | *pMapView | semmle.label | *pMapView | -| windows.cpp:324:10:324:16 | * ... | semmle.label | * ... | -| windows.cpp:328:23:328:40 | *call to MapViewOfFileNuma2 | semmle.label | *call to MapViewOfFileNuma2 | -| windows.cpp:328:23:328:40 | *call to MapViewOfFileNuma2 | semmle.label | *call to MapViewOfFileNuma2 | -| windows.cpp:329:20:329:52 | *pMapView | semmle.label | *pMapView | -| windows.cpp:331:10:331:16 | * ... | semmle.label | * ... | +| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | semmle.label | [summary param] *0 in CommandLineToArgvA | +| windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | semmle.label | [summary] to write: ReturnValue[**] in CommandLineToArgvA | +| windows.cpp:22:15:22:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA | +| windows.cpp:22:15:22:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA | +| windows.cpp:24:8:24:11 | * ... | semmle.label | * ... | +| windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | semmle.label | **call to CommandLineToArgvA | +| windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | semmle.label | **call to CommandLineToArgvA | +| windows.cpp:27:36:27:38 | *cmd | semmle.label | *cmd | +| windows.cpp:30:8:30:15 | * ... | semmle.label | * ... | +| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | semmle.label | *call to GetEnvironmentStringsA | +| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | semmle.label | *call to GetEnvironmentStringsA | +| windows.cpp:36:10:36:13 | * ... | semmle.label | * ... | +| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | semmle.label | GetEnvironmentVariableA output argument | +| windows.cpp:41:10:41:13 | * ... | semmle.label | * ... | +| windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [*hEvent] | semmle.label | [summary param] *3 in ReadFileEx [*hEvent] | +| windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [hEvent] | semmle.label | [summary param] *3 in ReadFileEx [hEvent] | +| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | semmle.label | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | +| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | semmle.label | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | +| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | semmle.label | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | +| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] | semmle.label | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] | +| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | semmle.label | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | +| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | semmle.label | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | +| windows.cpp:147:16:147:27 | *lpOverlapped [*hEvent] | semmle.label | *lpOverlapped [*hEvent] | +| windows.cpp:149:18:149:62 | *hEvent | semmle.label | *hEvent | +| windows.cpp:149:18:149:62 | *hEvent | semmle.label | *hEvent | +| windows.cpp:149:42:149:53 | *lpOverlapped [*hEvent] | semmle.label | *lpOverlapped [*hEvent] | +| windows.cpp:149:56:149:61 | *hEvent | semmle.label | *hEvent | +| windows.cpp:151:8:151:14 | * ... | semmle.label | * ... | +| windows.cpp:157:16:157:27 | *lpOverlapped [hEvent] | semmle.label | *lpOverlapped [hEvent] | +| windows.cpp:159:12:159:55 | hEvent | semmle.label | hEvent | +| windows.cpp:159:12:159:55 | hEvent | semmle.label | hEvent | +| windows.cpp:159:35:159:46 | *lpOverlapped [hEvent] | semmle.label | *lpOverlapped [hEvent] | +| windows.cpp:160:8:160:8 | c | semmle.label | c | +| windows.cpp:168:35:168:40 | ReadFile output argument | semmle.label | ReadFile output argument | +| windows.cpp:170:10:170:16 | * ... | semmle.label | * ... | +| windows.cpp:177:23:177:28 | ReadFileEx output argument | semmle.label | ReadFileEx output argument | +| windows.cpp:179:10:179:16 | * ... | semmle.label | * ... | +| windows.cpp:189:21:189:26 | ReadFile output argument | semmle.label | ReadFile output argument | +| windows.cpp:190:5:190:14 | *overlapped [post update] [*hEvent] | semmle.label | *overlapped [post update] [*hEvent] | +| windows.cpp:190:5:190:56 | *... = ... | semmle.label | *... = ... | +| windows.cpp:192:53:192:63 | *& ... [*hEvent] | semmle.label | *& ... [*hEvent] | +| windows.cpp:198:21:198:26 | ReadFile output argument | semmle.label | ReadFile output argument | +| windows.cpp:199:5:199:14 | *overlapped [post update] [hEvent] | semmle.label | *overlapped [post update] [hEvent] | +| windows.cpp:199:5:199:57 | ... = ... | semmle.label | ... = ... | +| windows.cpp:201:53:201:63 | *& ... [hEvent] | semmle.label | *& ... [hEvent] | +| windows.cpp:209:84:209:89 | NtReadFile output argument | semmle.label | NtReadFile output argument | +| windows.cpp:211:10:211:16 | * ... | semmle.label | * ... | +| windows.cpp:286:23:286:35 | *call to MapViewOfFile | semmle.label | *call to MapViewOfFile | +| windows.cpp:286:23:286:35 | *call to MapViewOfFile | semmle.label | *call to MapViewOfFile | +| windows.cpp:287:20:287:52 | *pMapView | semmle.label | *pMapView | +| windows.cpp:289:10:289:16 | * ... | semmle.label | * ... | +| windows.cpp:293:23:293:36 | *call to MapViewOfFile2 | semmle.label | *call to MapViewOfFile2 | +| windows.cpp:293:23:293:36 | *call to MapViewOfFile2 | semmle.label | *call to MapViewOfFile2 | +| windows.cpp:294:20:294:52 | *pMapView | semmle.label | *pMapView | +| windows.cpp:296:10:296:16 | * ... | semmle.label | * ... | +| windows.cpp:302:23:302:36 | *call to MapViewOfFile3 | semmle.label | *call to MapViewOfFile3 | +| windows.cpp:302:23:302:36 | *call to MapViewOfFile3 | semmle.label | *call to MapViewOfFile3 | +| windows.cpp:303:20:303:52 | *pMapView | semmle.label | *pMapView | +| windows.cpp:305:10:305:16 | * ... | semmle.label | * ... | +| windows.cpp:311:23:311:43 | *call to MapViewOfFile3FromApp | semmle.label | *call to MapViewOfFile3FromApp | +| windows.cpp:311:23:311:43 | *call to MapViewOfFile3FromApp | semmle.label | *call to MapViewOfFile3FromApp | +| windows.cpp:312:20:312:52 | *pMapView | semmle.label | *pMapView | +| windows.cpp:314:10:314:16 | * ... | semmle.label | * ... | +| windows.cpp:318:23:318:37 | *call to MapViewOfFileEx | semmle.label | *call to MapViewOfFileEx | +| windows.cpp:318:23:318:37 | *call to MapViewOfFileEx | semmle.label | *call to MapViewOfFileEx | +| windows.cpp:319:20:319:52 | *pMapView | semmle.label | *pMapView | +| windows.cpp:321:10:321:16 | * ... | semmle.label | * ... | +| windows.cpp:325:23:325:42 | *call to MapViewOfFileFromApp | semmle.label | *call to MapViewOfFileFromApp | +| windows.cpp:325:23:325:42 | *call to MapViewOfFileFromApp | semmle.label | *call to MapViewOfFileFromApp | +| windows.cpp:326:20:326:52 | *pMapView | semmle.label | *pMapView | +| windows.cpp:328:10:328:16 | * ... | semmle.label | * ... | +| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | semmle.label | *call to MapViewOfFileNuma2 | +| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | semmle.label | *call to MapViewOfFileNuma2 | +| windows.cpp:333:20:333:52 | *pMapView | semmle.label | *pMapView | +| windows.cpp:335:10:335:16 | * ... | semmle.label | * ... | subpaths | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | asio_streams.cpp:100:44:100:62 | call to buffer | | test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual | | test.cpp:21:27:21:27 | x | test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | test.cpp:21:10:21:25 | call to ymlStepGenerated | | test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | | test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | -| windows.cpp:16:36:16:38 | *cmd | windows.cpp:6:8:6:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:6:8:6:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | windows.cpp:16:17:16:34 | **call to CommandLineToArgvA | +| windows.cpp:27:36:27:38 | *cmd | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/sources.expected b/cpp/ql/test/library-tests/dataflow/external-models/sources.expected index a50ce484e1c..8730083d016 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/sources.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/sources.expected @@ -1,19 +1,19 @@ | asio_streams.cpp:87:34:87:44 | read_until output argument | remote | | test.cpp:10:10:10:18 | call to ymlSource | local | -| windows.cpp:11:15:11:29 | *call to GetCommandLineA | local | -| windows.cpp:23:17:23:38 | *call to GetEnvironmentStringsA | local | -| windows.cpp:28:36:28:38 | GetEnvironmentVariableA output argument | local | -| windows.cpp:164:35:164:40 | ReadFile output argument | local | -| windows.cpp:173:23:173:28 | ReadFileEx output argument | local | -| windows.cpp:185:21:185:26 | ReadFile output argument | local | -| windows.cpp:188:23:188:29 | ReadFileEx output argument | local | -| windows.cpp:194:21:194:26 | ReadFile output argument | local | -| windows.cpp:197:23:197:29 | ReadFileEx output argument | local | -| windows.cpp:205:84:205:89 | NtReadFile output argument | local | -| windows.cpp:282:23:282:35 | *call to MapViewOfFile | local | -| windows.cpp:289:23:289:36 | *call to MapViewOfFile2 | local | -| windows.cpp:298:23:298:36 | *call to MapViewOfFile3 | local | -| windows.cpp:307:23:307:43 | *call to MapViewOfFile3FromApp | local | -| windows.cpp:314:23:314:37 | *call to MapViewOfFileEx | local | -| windows.cpp:321:23:321:42 | *call to MapViewOfFileFromApp | local | -| windows.cpp:328:23:328:40 | *call to MapViewOfFileNuma2 | local | +| windows.cpp:22:15:22:29 | *call to GetCommandLineA | local | +| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | local | +| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | local | +| windows.cpp:168:35:168:40 | ReadFile output argument | local | +| windows.cpp:177:23:177:28 | ReadFileEx output argument | local | +| windows.cpp:189:21:189:26 | ReadFile output argument | local | +| windows.cpp:192:23:192:29 | ReadFileEx output argument | local | +| windows.cpp:198:21:198:26 | ReadFile output argument | local | +| windows.cpp:201:23:201:29 | ReadFileEx output argument | local | +| windows.cpp:209:84:209:89 | NtReadFile output argument | local | +| windows.cpp:286:23:286:35 | *call to MapViewOfFile | local | +| windows.cpp:293:23:293:36 | *call to MapViewOfFile2 | local | +| windows.cpp:302:23:302:36 | *call to MapViewOfFile3 | local | +| windows.cpp:311:23:311:43 | *call to MapViewOfFile3FromApp | local | +| windows.cpp:318:23:318:37 | *call to MapViewOfFileEx | local | +| windows.cpp:325:23:325:42 | *call to MapViewOfFileFromApp | local | +| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | local | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/steps.expected b/cpp/ql/test/library-tests/dataflow/external-models/steps.expected index ccdec4aefcb..ce5dd687caf 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/steps.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/steps.expected @@ -5,4 +5,4 @@ | test.cpp:28:35:28:35 | 0 | test.cpp:28:11:28:33 | call to ymlStepManual_with_body | | test.cpp:32:38:32:38 | 0 | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | | test.cpp:35:38:35:38 | x | test.cpp:35:11:35:36 | call to ymlStepGenerated_with_body | -| windows.cpp:16:36:16:38 | *cmd | windows.cpp:16:17:16:34 | **call to CommandLineToArgvA | +| windows.cpp:27:36:27:38 | *cmd | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp b/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp index 3d45afc6609..b97ac833102 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp +++ b/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp @@ -2,10 +2,21 @@ void sink(char); void sink(char*); void sink(char**); -char* GetCommandLineA(); -char** CommandLineToArgvA(char*, int*); -char* GetEnvironmentStringsA(); -int GetEnvironmentVariableA(const char*, char*, int); +using HANDLE = void*; +using DWORD = unsigned long; +using LPCH = char*; +using LPSTR = char*; +using LPCSTR = const char*; +using LPVOID = void*; +using LPDWORD = unsigned long*; +using PVOID = void*; +using ULONG_PTR = unsigned long*; +using SIZE_T = decltype(sizeof(0)); + +LPSTR GetCommandLineA(); +LPSTR* CommandLineToArgvA(LPSTR, int*); +LPCH GetEnvironmentStringsA(); +DWORD GetEnvironmentVariableA(LPCSTR, LPSTR, DWORD); void getCommandLine() { char* cmd = GetCommandLineA(); @@ -30,13 +41,6 @@ void getEnvironment() { sink(*buf); // $ ir } -using HANDLE = void*; -using DWORD = unsigned long; -using LPVOID = void*; -using LPDWORD = unsigned long*; -using PVOID = void*; -using ULONG_PTR = unsigned long*; -using SIZE_T = decltype(sizeof(0)); typedef struct _OVERLAPPED { ULONG_PTR Internal; ULONG_PTR InternalHigh; From ece075c214faed16aab174dec8f53f24dbdf8d4d Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 27 May 2025 16:43:28 +0200 Subject: [PATCH 79/86] Rust: add more macro expansion tests --- rust/ql/integration-tests/.gitignore | 1 + .../macro-expansion/Cargo.lock | 53 ------------------- .../macro-expansion/Cargo.toml | 10 +--- .../macro-expansion/attributes/Cargo.toml | 7 +++ .../{ => attributes}/src/lib.rs | 4 +- .../macro-expansion/calls/Cargo.toml | 6 +++ .../macro-expansion/calls/src/included.rs | 3 ++ .../macro-expansion/calls/src/lib.rs | 30 +++++++++++ .../macro-expansion/calls/src/some.txt | 1 + .../macro-expansion/diagnostics.expected | 2 +- .../{macros => proc_macros}/Cargo.toml | 2 +- .../{macros => proc_macros}/src/lib.rs | 0 .../macro-expansion/source_archive.expected | 6 ++- .../macro-expansion/summary.expected | 16 ------ .../macro-expansion/summary.qlref | 1 - .../macro-expansion/test.expected | 51 ++++++++++++------ .../integration-tests/macro-expansion/test.ql | 16 ++++-- .../generated/MacroCall/some.txt | 1 + 18 files changed, 105 insertions(+), 105 deletions(-) delete mode 100644 rust/ql/integration-tests/macro-expansion/Cargo.lock create mode 100644 rust/ql/integration-tests/macro-expansion/attributes/Cargo.toml rename rust/ql/integration-tests/macro-expansion/{ => attributes}/src/lib.rs (67%) create mode 100644 rust/ql/integration-tests/macro-expansion/calls/Cargo.toml create mode 100644 rust/ql/integration-tests/macro-expansion/calls/src/included.rs create mode 100644 rust/ql/integration-tests/macro-expansion/calls/src/lib.rs create mode 100644 rust/ql/integration-tests/macro-expansion/calls/src/some.txt rename rust/ql/integration-tests/macro-expansion/{macros => proc_macros}/Cargo.toml (88%) rename rust/ql/integration-tests/macro-expansion/{macros => proc_macros}/src/lib.rs (100%) delete mode 100644 rust/ql/integration-tests/macro-expansion/summary.expected delete mode 100644 rust/ql/integration-tests/macro-expansion/summary.qlref create mode 100644 rust/ql/test/extractor-tests/generated/MacroCall/some.txt diff --git a/rust/ql/integration-tests/.gitignore b/rust/ql/integration-tests/.gitignore index 2f7896d1d13..2c96eb1b651 100644 --- a/rust/ql/integration-tests/.gitignore +++ b/rust/ql/integration-tests/.gitignore @@ -1 +1,2 @@ target/ +Cargo.lock diff --git a/rust/ql/integration-tests/macro-expansion/Cargo.lock b/rust/ql/integration-tests/macro-expansion/Cargo.lock deleted file mode 100644 index 976dc5e7def..00000000000 --- a/rust/ql/integration-tests/macro-expansion/Cargo.lock +++ /dev/null @@ -1,53 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "macro_expansion" -version = "0.1.0" -dependencies = [ - "macros", -] - -[[package]] -name = "macros" -version = "0.1.0" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "proc-macro2" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "syn" -version = "2.0.101" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "unicode-ident" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" diff --git a/rust/ql/integration-tests/macro-expansion/Cargo.toml b/rust/ql/integration-tests/macro-expansion/Cargo.toml index b7ce204e07f..9be2ec64b57 100644 --- a/rust/ql/integration-tests/macro-expansion/Cargo.toml +++ b/rust/ql/integration-tests/macro-expansion/Cargo.toml @@ -1,11 +1,3 @@ [workspace] -members = ["macros"] +members = [ "attributes", "calls", "proc_macros"] resolver = "2" - -[package] -name = "macro_expansion" -version = "0.1.0" -edition = "2024" - -[dependencies] -macros = { path = "macros" } diff --git a/rust/ql/integration-tests/macro-expansion/attributes/Cargo.toml b/rust/ql/integration-tests/macro-expansion/attributes/Cargo.toml new file mode 100644 index 00000000000..b475ead960a --- /dev/null +++ b/rust/ql/integration-tests/macro-expansion/attributes/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "attributes" +version = "0.1.0" +edition = "2024" + +[dependencies] +proc_macros = { path = "../proc_macros" } diff --git a/rust/ql/integration-tests/macro-expansion/src/lib.rs b/rust/ql/integration-tests/macro-expansion/attributes/src/lib.rs similarity index 67% rename from rust/ql/integration-tests/macro-expansion/src/lib.rs rename to rust/ql/integration-tests/macro-expansion/attributes/src/lib.rs index 2007d3b111a..682083aa10a 100644 --- a/rust/ql/integration-tests/macro-expansion/src/lib.rs +++ b/rust/ql/integration-tests/macro-expansion/attributes/src/lib.rs @@ -1,8 +1,8 @@ -use macros::repeat; +use proc_macros::repeat; #[repeat(3)] fn foo() { - println!("Hello, world!"); + _ = concat!("Hello ", "world!"); #[repeat(2)] fn inner() {} diff --git a/rust/ql/integration-tests/macro-expansion/calls/Cargo.toml b/rust/ql/integration-tests/macro-expansion/calls/Cargo.toml new file mode 100644 index 00000000000..d38cf944489 --- /dev/null +++ b/rust/ql/integration-tests/macro-expansion/calls/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "calls" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/rust/ql/integration-tests/macro-expansion/calls/src/included.rs b/rust/ql/integration-tests/macro-expansion/calls/src/included.rs new file mode 100644 index 00000000000..7397e24bd81 --- /dev/null +++ b/rust/ql/integration-tests/macro-expansion/calls/src/included.rs @@ -0,0 +1,3 @@ +fn included() { + _ = concat!("Hello", " ", "world!"); // this doesn't expand (in included.rs) since 0.0.274 +} diff --git a/rust/ql/integration-tests/macro-expansion/calls/src/lib.rs b/rust/ql/integration-tests/macro-expansion/calls/src/lib.rs new file mode 100644 index 00000000000..df3fccb7c40 --- /dev/null +++ b/rust/ql/integration-tests/macro-expansion/calls/src/lib.rs @@ -0,0 +1,30 @@ +struct S; + +macro_rules! def_x { + () => { + fn x() {} + }; +} + +impl S { + def_x!(); // this doesn't expand since 0.0.274 +} + +macro_rules! my_macro { + ($head:expr, $($tail:tt)*) => { format!($head, $($tail)*) }; +} + + +fn test() { + _ = concat!("x", "y"); + + _ = my_macro!( + concat!("<", "{}", ">"), // this doesn't expand since 0.0.274 + "hi", + ); +} + +include!("included.rs"); + +#[doc = include_str!("some.txt")] // this doesn't expand since 0.0.274 +fn documented() {} diff --git a/rust/ql/integration-tests/macro-expansion/calls/src/some.txt b/rust/ql/integration-tests/macro-expansion/calls/src/some.txt new file mode 100644 index 00000000000..4c5477a837a --- /dev/null +++ b/rust/ql/integration-tests/macro-expansion/calls/src/some.txt @@ -0,0 +1 @@ +Hey! diff --git a/rust/ql/integration-tests/macro-expansion/diagnostics.expected b/rust/ql/integration-tests/macro-expansion/diagnostics.expected index c98f923b463..511bd49f1a5 100644 --- a/rust/ql/integration-tests/macro-expansion/diagnostics.expected +++ b/rust/ql/integration-tests/macro-expansion/diagnostics.expected @@ -38,7 +38,7 @@ "pretty": "__REDACTED__" } }, - "numberOfFiles": 2, + "numberOfFiles": 4, "numberOfManifests": 1 }, "severity": "note", diff --git a/rust/ql/integration-tests/macro-expansion/macros/Cargo.toml b/rust/ql/integration-tests/macro-expansion/proc_macros/Cargo.toml similarity index 88% rename from rust/ql/integration-tests/macro-expansion/macros/Cargo.toml rename to rust/ql/integration-tests/macro-expansion/proc_macros/Cargo.toml index a503d3fb903..712f7ba3393 100644 --- a/rust/ql/integration-tests/macro-expansion/macros/Cargo.toml +++ b/rust/ql/integration-tests/macro-expansion/proc_macros/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "macros" +name = "proc_macros" version = "0.1.0" edition = "2024" diff --git a/rust/ql/integration-tests/macro-expansion/macros/src/lib.rs b/rust/ql/integration-tests/macro-expansion/proc_macros/src/lib.rs similarity index 100% rename from rust/ql/integration-tests/macro-expansion/macros/src/lib.rs rename to rust/ql/integration-tests/macro-expansion/proc_macros/src/lib.rs diff --git a/rust/ql/integration-tests/macro-expansion/source_archive.expected b/rust/ql/integration-tests/macro-expansion/source_archive.expected index ec61af6032b..c1700a0a300 100644 --- a/rust/ql/integration-tests/macro-expansion/source_archive.expected +++ b/rust/ql/integration-tests/macro-expansion/source_archive.expected @@ -1,2 +1,4 @@ -macros/src/lib.rs -src/lib.rs +attributes/src/lib.rs +calls/src/included.rs +calls/src/lib.rs +proc_macros/src/lib.rs diff --git a/rust/ql/integration-tests/macro-expansion/summary.expected b/rust/ql/integration-tests/macro-expansion/summary.expected deleted file mode 100644 index 6917d67b1cf..00000000000 --- a/rust/ql/integration-tests/macro-expansion/summary.expected +++ /dev/null @@ -1,16 +0,0 @@ -| Extraction errors | 0 | -| Extraction warnings | 0 | -| Files extracted - total | 2 | -| Files extracted - with errors | 0 | -| Files extracted - without errors | 2 | -| Files extracted - without errors % | 100 | -| Inconsistencies - AST | 0 | -| Inconsistencies - CFG | 0 | -| Inconsistencies - Path resolution | 0 | -| Inconsistencies - SSA | 0 | -| Inconsistencies - data flow | 0 | -| Lines of code extracted | 29 | -| Lines of user code extracted | 29 | -| Macro calls - resolved | 52 | -| Macro calls - total | 53 | -| Macro calls - unresolved | 1 | diff --git a/rust/ql/integration-tests/macro-expansion/summary.qlref b/rust/ql/integration-tests/macro-expansion/summary.qlref deleted file mode 100644 index 926fc790391..00000000000 --- a/rust/ql/integration-tests/macro-expansion/summary.qlref +++ /dev/null @@ -1 +0,0 @@ -queries/summary/SummaryStatsReduced.ql diff --git a/rust/ql/integration-tests/macro-expansion/test.expected b/rust/ql/integration-tests/macro-expansion/test.expected index 83edecf5d5d..24d95c99b35 100644 --- a/rust/ql/integration-tests/macro-expansion/test.expected +++ b/rust/ql/integration-tests/macro-expansion/test.expected @@ -1,17 +1,34 @@ -| src/lib.rs:3:1:9:1 | fn foo | 0 | src/lib.rs:4:1:8:16 | fn foo_0 | -| src/lib.rs:3:1:9:1 | fn foo | 1 | src/lib.rs:4:1:8:16 | fn foo_1 | -| src/lib.rs:3:1:9:1 | fn foo | 2 | src/lib.rs:4:1:8:16 | fn foo_2 | -| src/lib.rs:7:5:8:16 | fn inner | 0 | src/lib.rs:8:5:8:16 | fn inner_0 | -| src/lib.rs:7:5:8:16 | fn inner | 0 | src/lib.rs:8:5:8:16 | fn inner_0 | -| src/lib.rs:7:5:8:16 | fn inner | 0 | src/lib.rs:8:5:8:16 | fn inner_0 | -| src/lib.rs:7:5:8:16 | fn inner | 1 | src/lib.rs:8:5:8:16 | fn inner_1 | -| src/lib.rs:7:5:8:16 | fn inner | 1 | src/lib.rs:8:5:8:16 | fn inner_1 | -| src/lib.rs:7:5:8:16 | fn inner | 1 | src/lib.rs:8:5:8:16 | fn inner_1 | -| src/lib.rs:11:1:13:11 | fn bar | 0 | src/lib.rs:12:1:13:10 | fn bar_0 | -| src/lib.rs:11:1:13:11 | fn bar | 1 | src/lib.rs:12:1:13:10 | fn bar_1 | -| src/lib.rs:12:1:13:10 | fn bar_0 | 0 | src/lib.rs:13:1:13:10 | fn bar_0_0 | -| src/lib.rs:12:1:13:10 | fn bar_0 | 1 | src/lib.rs:13:1:13:10 | fn bar_0_1 | -| src/lib.rs:12:1:13:10 | fn bar_0 | 2 | src/lib.rs:13:1:13:10 | fn bar_0_2 | -| src/lib.rs:12:1:13:10 | fn bar_1 | 0 | src/lib.rs:13:1:13:10 | fn bar_1_0 | -| src/lib.rs:12:1:13:10 | fn bar_1 | 1 | src/lib.rs:13:1:13:10 | fn bar_1_1 | -| src/lib.rs:12:1:13:10 | fn bar_1 | 2 | src/lib.rs:13:1:13:10 | fn bar_1_2 | +attribute_macros +| attributes/src/lib.rs:3:1:9:1 | fn foo | 0 | attributes/src/lib.rs:4:1:8:16 | fn foo_0 | +| attributes/src/lib.rs:3:1:9:1 | fn foo | 1 | attributes/src/lib.rs:4:1:8:16 | fn foo_1 | +| attributes/src/lib.rs:3:1:9:1 | fn foo | 2 | attributes/src/lib.rs:4:1:8:16 | fn foo_2 | +| attributes/src/lib.rs:7:5:8:16 | fn inner | 0 | attributes/src/lib.rs:8:5:8:16 | fn inner_0 | +| attributes/src/lib.rs:7:5:8:16 | fn inner | 0 | attributes/src/lib.rs:8:5:8:16 | fn inner_0 | +| attributes/src/lib.rs:7:5:8:16 | fn inner | 0 | attributes/src/lib.rs:8:5:8:16 | fn inner_0 | +| attributes/src/lib.rs:7:5:8:16 | fn inner | 1 | attributes/src/lib.rs:8:5:8:16 | fn inner_1 | +| attributes/src/lib.rs:7:5:8:16 | fn inner | 1 | attributes/src/lib.rs:8:5:8:16 | fn inner_1 | +| attributes/src/lib.rs:7:5:8:16 | fn inner | 1 | attributes/src/lib.rs:8:5:8:16 | fn inner_1 | +| attributes/src/lib.rs:11:1:13:11 | fn bar | 0 | attributes/src/lib.rs:12:1:13:10 | fn bar_0 | +| attributes/src/lib.rs:11:1:13:11 | fn bar | 1 | attributes/src/lib.rs:12:1:13:10 | fn bar_1 | +| attributes/src/lib.rs:12:1:13:10 | fn bar_0 | 0 | attributes/src/lib.rs:13:1:13:10 | fn bar_0_0 | +| attributes/src/lib.rs:12:1:13:10 | fn bar_0 | 1 | attributes/src/lib.rs:13:1:13:10 | fn bar_0_1 | +| attributes/src/lib.rs:12:1:13:10 | fn bar_0 | 2 | attributes/src/lib.rs:13:1:13:10 | fn bar_0_2 | +| attributes/src/lib.rs:12:1:13:10 | fn bar_1 | 0 | attributes/src/lib.rs:13:1:13:10 | fn bar_1_0 | +| attributes/src/lib.rs:12:1:13:10 | fn bar_1 | 1 | attributes/src/lib.rs:13:1:13:10 | fn bar_1_1 | +| attributes/src/lib.rs:12:1:13:10 | fn bar_1 | 2 | attributes/src/lib.rs:13:1:13:10 | fn bar_1_2 | +macro_calls +| attributes/src/lib.rs:5:9:5:34 | concat!... | attributes/src/lib.rs:5:17:5:34 | "Hello world!" | +| attributes/src/lib.rs:5:9:5:34 | concat!... | attributes/src/lib.rs:5:17:5:34 | "Hello world!" | +| attributes/src/lib.rs:5:9:5:34 | concat!... | attributes/src/lib.rs:5:17:5:34 | "Hello world!" | +| calls/src/included.rs:2:9:2:39 | concat!... | calls/src/included.rs:2:17:2:38 | "Hello world!" | +| calls/src/lib.rs:10:5:10:13 | def_x!... | calls/src/lib.rs:10:5:10:13 | MacroItems | +| calls/src/lib.rs:19:9:19:25 | concat!... | calls/src/lib.rs:19:17:19:24 | "xy" | +| calls/src/lib.rs:21:9:24:5 | my_macro!... | calls/src/lib.rs:22:9:23:13 | MacroExpr | +| calls/src/lib.rs:22:9:22:31 | concat!... | calls/src/lib.rs:22:17:22:30 | "<{}>" | +| calls/src/lib.rs:22:9:23:13 | ...::format_args!... | calls/src/lib.rs:22:9:23:13 | FormatArgsExpr | +| calls/src/lib.rs:22:9:23:13 | format!... | calls/src/lib.rs:22:9:23:13 | ...::must_use(...) | +| calls/src/lib.rs:27:1:27:24 | concat!... | calls/src/lib.rs:27:1:27:24 | "Hello world!" | +| calls/src/lib.rs:27:1:27:24 | include!... | calls/src/lib.rs:27:1:27:24 | MacroItems | +| calls/src/lib.rs:29:9:29:32 | include_str!... | calls/src/lib.rs:29:22:29:31 | "" | +unexpanded_macro_calls +| attributes/src/lib.rs:5:9:5:35 | concat!... | diff --git a/rust/ql/integration-tests/macro-expansion/test.ql b/rust/ql/integration-tests/macro-expansion/test.ql index 3369acc3a28..439ffab9a29 100644 --- a/rust/ql/integration-tests/macro-expansion/test.ql +++ b/rust/ql/integration-tests/macro-expansion/test.ql @@ -1,5 +1,15 @@ import rust -from Item i, MacroItems items, int index, Item expanded -where i.fromSource() and i.getAttributeMacroExpansion() = items and items.getItem(index) = expanded -select i, index, expanded +query predicate attribute_macros(Item i, int index, Item expanded) { + i.fromSource() and expanded = i.getAttributeMacroExpansion().getItem(index) +} + +query predicate macro_calls(MacroCall c, AstNode expansion) { + c.fromSource() and + not c.getLocation().getFile().getAbsolutePath().matches("%proc_macros%") and + expansion = c.getMacroCallExpansion() +} + +query predicate unexpanded_macro_calls(MacroCall c) { + c.fromSource() and not c.hasMacroCallExpansion() +} diff --git a/rust/ql/test/extractor-tests/generated/MacroCall/some.txt b/rust/ql/test/extractor-tests/generated/MacroCall/some.txt new file mode 100644 index 00000000000..10ddd6d257e --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/MacroCall/some.txt @@ -0,0 +1 @@ +Hello! From 0796184573355d69b26647f2d8532e5c52f37a2c Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Wed, 28 May 2025 14:16:47 +0200 Subject: [PATCH 80/86] C++: Specify GNU version on min/max test The `?` operators where removed in g++ in version 4.3, and the latest version of our our frontend enforces this through a version check. Hence, to keep the test working, we not to explicitly specify a version. --- cpp/ql/test/library-tests/exprs/min_max/expr.expected | 8 ++++---- cpp/ql/test/library-tests/exprs/min_max/test.cpp | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cpp/ql/test/library-tests/exprs/min_max/expr.expected b/cpp/ql/test/library-tests/exprs/min_max/expr.expected index ebd03f8b699..b2ce8fb6e40 100644 --- a/cpp/ql/test/library-tests/exprs/min_max/expr.expected +++ b/cpp/ql/test/library-tests/exprs/min_max/expr.expected @@ -1,6 +1,6 @@ -| test.cpp:3:13:3:13 | i | -| test.cpp:3:13:3:18 | ... ? ... | +| test.cpp:4:13:4:18 | ... ? ... | +| test.cpp:5:18:5:18 | j | diff --git a/cpp/ql/test/library-tests/exprs/min_max/test.cpp b/cpp/ql/test/library-tests/exprs/min_max/test.cpp index d8be21af82a..f62e08974ce 100644 --- a/cpp/ql/test/library-tests/exprs/min_max/test.cpp +++ b/cpp/ql/test/library-tests/exprs/min_max/test.cpp @@ -1,3 +1,4 @@ +// semmle-extractor-options: --gnu_version 40200 void f(int i, int j) { int k = i Date: Wed, 28 May 2025 14:13:21 +0200 Subject: [PATCH 81/86] Rust: fix gzip compression --- rust/extractor/src/config.rs | 2 +- rust/extractor/src/trap.rs | 14 ++++++++------ .../hello-project/test_project.py | 17 ++++++++++++++++- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/rust/extractor/src/config.rs b/rust/extractor/src/config.rs index 3f6b86d1f1f..3f3a37cf5f0 100644 --- a/rust/extractor/src/config.rs +++ b/rust/extractor/src/config.rs @@ -55,7 +55,7 @@ pub struct Config { pub cargo_all_targets: bool, pub logging_flamegraph: Option, pub logging_verbosity: Option, - pub compression: Compression, + pub trap_compression: Compression, pub inputs: Vec, pub qltest: bool, pub qltest_cargo_check: bool, diff --git a/rust/extractor/src/trap.rs b/rust/extractor/src/trap.rs index ce739e067f0..2206c4c067b 100644 --- a/rust/extractor/src/trap.rs +++ b/rust/extractor/src/trap.rs @@ -1,4 +1,3 @@ -use crate::config::Compression; use crate::{config, generated}; use codeql_extractor::{extractor, file_paths, trap}; use ra_ap_ide_db::line_index::LineCol; @@ -9,7 +8,7 @@ use std::path::{Path, PathBuf}; use tracing::debug; pub use trap::Label as UntypedLabel; -pub use trap::Writer; +pub use trap::{Compression, Writer}; pub trait AsTrapKeyPart { fn as_key_part(&self) -> String; @@ -245,8 +244,7 @@ impl TrapFile { pub fn commit(&self) -> std::io::Result<()> { std::fs::create_dir_all(self.path.parent().unwrap())?; - self.writer - .write_to_file(&self.path, self.compression.into()) + self.writer.write_to_file(&self.path, self.compression) } } @@ -261,12 +259,16 @@ impl TrapFileProvider { std::fs::create_dir_all(&trap_dir)?; Ok(TrapFileProvider { trap_dir, - compression: cfg.compression, + compression: cfg.trap_compression.into(), }) } pub fn create(&self, category: &str, key: impl AsRef) -> TrapFile { - let path = file_paths::path_for(&self.trap_dir.join(category), key.as_ref(), "trap"); + let path = file_paths::path_for( + &self.trap_dir.join(category), + key.as_ref(), + self.compression.extension(), + ); debug!("creating trap file {}", path.display()); let mut writer = trap::Writer::new(); extractor::populate_empty_location(&mut writer); diff --git a/rust/ql/integration-tests/hello-project/test_project.py b/rust/ql/integration-tests/hello-project/test_project.py index 5509bc3a93d..5b0eae903ac 100644 --- a/rust/ql/integration-tests/hello-project/test_project.py +++ b/rust/ql/integration-tests/hello-project/test_project.py @@ -10,7 +10,22 @@ def test_rust_project(codeql, rust, rust_project, check_source_archive, rust_che codeql.database.create() @pytest.mark.ql_test(None) -def test_do_not_print_env(codeql, rust, cargo, check_env_not_dumped, rust_check_diagnostics): +# parametrizing `rust_edition` allows us to skip the default parametrization over all editions +@pytest.mark.parametrize("rust_edition", [2024]) +def test_do_not_print_env(codeql, rust, rust_edition, cargo, check_env_not_dumped, rust_check_diagnostics): codeql.database.create(_env={ "CODEQL_EXTRACTOR_RUST_VERBOSE": "2", }) + +@pytest.mark.ql_test("steps.ql", expected=".cargo.expected") +@pytest.mark.parametrize(("rust_edition", "compression", "suffix"), [ + pytest.param(2024, "gzip", ".gz", id="gzip"), +]) +def test_compression(codeql, rust, rust_edition, compression, suffix, cargo, rust_check_diagnostics, cwd): + codeql.database.create(cleanup=False, _env={ + "CODEQL_EXTRACTOR_RUST_TRAP_COMPRESSION": compression, + }) + trap_files = [*(cwd / "test-db" / "trap").rglob("*.trap*")] + assert trap_files + files_with_wrong_format = [f for f in trap_files if f.suffix != suffix and f.name != "metadata.trap.gz"] + assert not files_with_wrong_format, f"Found trap files with wrong format: {files_with_wrong_format}" From 4a9e31ebd87c8b74ea9fa4b4a43ad899c57696ad Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 28 May 2025 14:15:44 +0200 Subject: [PATCH 82/86] Shared: add zstd crate to tree-sitter-extractor dependencies --- Cargo.lock | 46 +++++ MODULE.bazel | 1 + .../tree_sitter_extractors_deps/BUILD.bazel | 12 ++ .../BUILD.cc-1.2.7.bazel | 41 ++++- .../BUILD.jobserver-0.1.32.bazel | 158 ++++++++++++++++++ .../BUILD.pkg-config-0.3.32.bazel | 83 +++++++++ .../BUILD.zstd-0.13.3.bazel | 92 ++++++++++ .../BUILD.zstd-safe-7.2.4.bazel | 158 ++++++++++++++++++ .../BUILD.zstd-sys-2.0.15+zstd.1.5.7.bazel | 157 +++++++++++++++++ .../tree_sitter_extractors_deps/defs.bzl | 52 ++++++ shared/tree-sitter-extractor/Cargo.toml | 1 + 11 files changed, 800 insertions(+), 1 deletion(-) create mode 100644 misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.jobserver-0.1.32.bazel create mode 100644 misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.pkg-config-0.3.32.bazel create mode 100644 misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zstd-0.13.3.bazel create mode 100644 misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zstd-safe-7.2.4.bazel create mode 100644 misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zstd-sys-2.0.15+zstd.1.5.7.bazel diff --git a/Cargo.lock b/Cargo.lock index f425373ceea..934cae590c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -242,6 +242,8 @@ version = "1.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" dependencies = [ + "jobserver", + "libc", "shlex", ] @@ -390,6 +392,7 @@ dependencies = [ "tree-sitter", "tree-sitter-json", "tree-sitter-ql", + "zstd", ] [[package]] @@ -983,6 +986,15 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + [[package]] name = "jod-thread" version = "0.1.2" @@ -1334,6 +1346,12 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + [[package]] name = "portable-atomic" version = "1.11.0" @@ -3027,3 +3045,31 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.15+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/MODULE.bazel b/MODULE.bazel index 49ea49975bb..764eb6abe72 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -124,6 +124,7 @@ use_repo( "vendor_ts__tree-sitter-ruby-0.23.1", "vendor_ts__triomphe-0.1.14", "vendor_ts__ungrammar-1.16.1", + "vendor_ts__zstd-0.13.3", ) http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel index 1f97bfd967f..52ebf159f01 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel @@ -672,3 +672,15 @@ alias( actual = "@vendor_ts__ungrammar-1.16.1//:ungrammar", tags = ["manual"], ) + +alias( + name = "zstd-0.13.3", + actual = "@vendor_ts__zstd-0.13.3//:zstd", + tags = ["manual"], +) + +alias( + name = "zstd", + actual = "@vendor_ts__zstd-0.13.3//:zstd", + tags = ["manual"], +) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cc-1.2.7.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cc-1.2.7.bazel index 56be5f5153b..54aab54c9ca 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cc-1.2.7.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cc-1.2.7.bazel @@ -28,6 +28,9 @@ rust_library( "WORKSPACE.bazel", ], ), + crate_features = [ + "parallel", + ], crate_root = "src/lib.rs", edition = "2018", rustc_flags = [ @@ -81,6 +84,42 @@ rust_library( }), version = "1.2.7", deps = [ + "@vendor_ts__jobserver-0.1.32//:jobserver", "@vendor_ts__shlex-1.3.0//:shlex", - ], + ] + select({ + "@rules_rust//rust/platform:aarch64-apple-darwin": [ + "@vendor_ts__libc-0.2.171//:libc", # aarch64-apple-darwin + ], + "@rules_rust//rust/platform:aarch64-unknown-linux-gnu": [ + "@vendor_ts__libc-0.2.171//:libc", # aarch64-unknown-linux-gnu + ], + "@rules_rust//rust/platform:aarch64-unknown-nixos-gnu": [ + "@vendor_ts__libc-0.2.171//:libc", # aarch64-unknown-linux-gnu, aarch64-unknown-nixos-gnu + ], + "@rules_rust//rust/platform:arm-unknown-linux-gnueabi": [ + "@vendor_ts__libc-0.2.171//:libc", # arm-unknown-linux-gnueabi + ], + "@rules_rust//rust/platform:i686-unknown-linux-gnu": [ + "@vendor_ts__libc-0.2.171//:libc", # i686-unknown-linux-gnu + ], + "@rules_rust//rust/platform:powerpc-unknown-linux-gnu": [ + "@vendor_ts__libc-0.2.171//:libc", # powerpc-unknown-linux-gnu + ], + "@rules_rust//rust/platform:s390x-unknown-linux-gnu": [ + "@vendor_ts__libc-0.2.171//:libc", # s390x-unknown-linux-gnu + ], + "@rules_rust//rust/platform:x86_64-apple-darwin": [ + "@vendor_ts__libc-0.2.171//:libc", # x86_64-apple-darwin + ], + "@rules_rust//rust/platform:x86_64-unknown-freebsd": [ + "@vendor_ts__libc-0.2.171//:libc", # x86_64-unknown-freebsd + ], + "@rules_rust//rust/platform:x86_64-unknown-linux-gnu": [ + "@vendor_ts__libc-0.2.171//:libc", # x86_64-unknown-linux-gnu + ], + "@rules_rust//rust/platform:x86_64-unknown-nixos-gnu": [ + "@vendor_ts__libc-0.2.171//:libc", # x86_64-unknown-linux-gnu, x86_64-unknown-nixos-gnu + ], + "//conditions:default": [], + }), ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.jobserver-0.1.32.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.jobserver-0.1.32.bazel new file mode 100644 index 00000000000..7e041e35b8c --- /dev/null +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.jobserver-0.1.32.bazel @@ -0,0 +1,158 @@ +############################################################################### +# @generated +# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To +# regenerate this file, run the following: +# +# bazel run @@//misc/bazel/3rdparty:vendor_tree_sitter_extractors +############################################################################### + +load("@rules_rust//rust:defs.bzl", "rust_library") + +package(default_visibility = ["//visibility:public"]) + +rust_library( + name = "jobserver", + srcs = glob( + include = ["**/*.rs"], + allow_empty = True, + ), + compile_data = glob( + include = ["**"], + allow_empty = True, + exclude = [ + "**/* *", + ".tmp_git_root/**/*", + "BUILD", + "BUILD.bazel", + "WORKSPACE", + "WORKSPACE.bazel", + ], + ), + crate_root = "src/lib.rs", + edition = "2021", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-bazel", + "crate-name=jobserver", + "manual", + "noclippy", + "norustfmt", + ], + target_compatible_with = select({ + "@rules_rust//rust/platform:aarch64-apple-darwin": [], + "@rules_rust//rust/platform:aarch64-apple-ios": [], + "@rules_rust//rust/platform:aarch64-apple-ios-sim": [], + "@rules_rust//rust/platform:aarch64-linux-android": [], + "@rules_rust//rust/platform:aarch64-pc-windows-msvc": [], + "@rules_rust//rust/platform:aarch64-unknown-fuchsia": [], + "@rules_rust//rust/platform:aarch64-unknown-linux-gnu": [], + "@rules_rust//rust/platform:aarch64-unknown-nixos-gnu": [], + "@rules_rust//rust/platform:aarch64-unknown-nto-qnx710": [], + "@rules_rust//rust/platform:aarch64-unknown-uefi": [], + "@rules_rust//rust/platform:arm-unknown-linux-gnueabi": [], + "@rules_rust//rust/platform:armv7-linux-androideabi": [], + "@rules_rust//rust/platform:armv7-unknown-linux-gnueabi": [], + "@rules_rust//rust/platform:i686-apple-darwin": [], + "@rules_rust//rust/platform:i686-linux-android": [], + "@rules_rust//rust/platform:i686-pc-windows-msvc": [], + "@rules_rust//rust/platform:i686-unknown-freebsd": [], + "@rules_rust//rust/platform:i686-unknown-linux-gnu": [], + "@rules_rust//rust/platform:powerpc-unknown-linux-gnu": [], + "@rules_rust//rust/platform:riscv32imc-unknown-none-elf": [], + "@rules_rust//rust/platform:riscv64gc-unknown-none-elf": [], + "@rules_rust//rust/platform:s390x-unknown-linux-gnu": [], + "@rules_rust//rust/platform:thumbv7em-none-eabi": [], + "@rules_rust//rust/platform:thumbv8m.main-none-eabi": [], + "@rules_rust//rust/platform:wasm32-unknown-unknown": [], + "@rules_rust//rust/platform:wasm32-wasip1": [], + "@rules_rust//rust/platform:x86_64-apple-darwin": [], + "@rules_rust//rust/platform:x86_64-apple-ios": [], + "@rules_rust//rust/platform:x86_64-linux-android": [], + "@rules_rust//rust/platform:x86_64-pc-windows-msvc": [], + "@rules_rust//rust/platform:x86_64-unknown-freebsd": [], + "@rules_rust//rust/platform:x86_64-unknown-fuchsia": [], + "@rules_rust//rust/platform:x86_64-unknown-linux-gnu": [], + "@rules_rust//rust/platform:x86_64-unknown-nixos-gnu": [], + "@rules_rust//rust/platform:x86_64-unknown-none": [], + "@rules_rust//rust/platform:x86_64-unknown-uefi": [], + "//conditions:default": ["@platforms//:incompatible"], + }), + version = "0.1.32", + deps = select({ + "@rules_rust//rust/platform:aarch64-apple-darwin": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:aarch64-apple-ios": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:aarch64-apple-ios-sim": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:aarch64-linux-android": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:aarch64-unknown-fuchsia": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:aarch64-unknown-linux-gnu": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:aarch64-unknown-nixos-gnu": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:aarch64-unknown-nto-qnx710": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:arm-unknown-linux-gnueabi": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:armv7-linux-androideabi": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:armv7-unknown-linux-gnueabi": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:i686-apple-darwin": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:i686-linux-android": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:i686-unknown-freebsd": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:i686-unknown-linux-gnu": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:powerpc-unknown-linux-gnu": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:s390x-unknown-linux-gnu": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:x86_64-apple-darwin": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:x86_64-apple-ios": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:x86_64-linux-android": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:x86_64-unknown-freebsd": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:x86_64-unknown-fuchsia": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:x86_64-unknown-linux-gnu": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "@rules_rust//rust/platform:x86_64-unknown-nixos-gnu": [ + "@vendor_ts__libc-0.2.171//:libc", # cfg(unix) + ], + "//conditions:default": [], + }), +) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.pkg-config-0.3.32.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.pkg-config-0.3.32.bazel new file mode 100644 index 00000000000..8fb981887a7 --- /dev/null +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.pkg-config-0.3.32.bazel @@ -0,0 +1,83 @@ +############################################################################### +# @generated +# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To +# regenerate this file, run the following: +# +# bazel run @@//misc/bazel/3rdparty:vendor_tree_sitter_extractors +############################################################################### + +load("@rules_rust//rust:defs.bzl", "rust_library") + +package(default_visibility = ["//visibility:public"]) + +rust_library( + name = "pkg_config", + srcs = glob( + include = ["**/*.rs"], + allow_empty = True, + ), + compile_data = glob( + include = ["**"], + allow_empty = True, + exclude = [ + "**/* *", + ".tmp_git_root/**/*", + "BUILD", + "BUILD.bazel", + "WORKSPACE", + "WORKSPACE.bazel", + ], + ), + crate_root = "src/lib.rs", + edition = "2018", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-bazel", + "crate-name=pkg-config", + "manual", + "noclippy", + "norustfmt", + ], + target_compatible_with = select({ + "@rules_rust//rust/platform:aarch64-apple-darwin": [], + "@rules_rust//rust/platform:aarch64-apple-ios": [], + "@rules_rust//rust/platform:aarch64-apple-ios-sim": [], + "@rules_rust//rust/platform:aarch64-linux-android": [], + "@rules_rust//rust/platform:aarch64-pc-windows-msvc": [], + "@rules_rust//rust/platform:aarch64-unknown-fuchsia": [], + "@rules_rust//rust/platform:aarch64-unknown-linux-gnu": [], + "@rules_rust//rust/platform:aarch64-unknown-nixos-gnu": [], + "@rules_rust//rust/platform:aarch64-unknown-nto-qnx710": [], + "@rules_rust//rust/platform:aarch64-unknown-uefi": [], + "@rules_rust//rust/platform:arm-unknown-linux-gnueabi": [], + "@rules_rust//rust/platform:armv7-linux-androideabi": [], + "@rules_rust//rust/platform:armv7-unknown-linux-gnueabi": [], + "@rules_rust//rust/platform:i686-apple-darwin": [], + "@rules_rust//rust/platform:i686-linux-android": [], + "@rules_rust//rust/platform:i686-pc-windows-msvc": [], + "@rules_rust//rust/platform:i686-unknown-freebsd": [], + "@rules_rust//rust/platform:i686-unknown-linux-gnu": [], + "@rules_rust//rust/platform:powerpc-unknown-linux-gnu": [], + "@rules_rust//rust/platform:riscv32imc-unknown-none-elf": [], + "@rules_rust//rust/platform:riscv64gc-unknown-none-elf": [], + "@rules_rust//rust/platform:s390x-unknown-linux-gnu": [], + "@rules_rust//rust/platform:thumbv7em-none-eabi": [], + "@rules_rust//rust/platform:thumbv8m.main-none-eabi": [], + "@rules_rust//rust/platform:wasm32-unknown-unknown": [], + "@rules_rust//rust/platform:wasm32-wasip1": [], + "@rules_rust//rust/platform:x86_64-apple-darwin": [], + "@rules_rust//rust/platform:x86_64-apple-ios": [], + "@rules_rust//rust/platform:x86_64-linux-android": [], + "@rules_rust//rust/platform:x86_64-pc-windows-msvc": [], + "@rules_rust//rust/platform:x86_64-unknown-freebsd": [], + "@rules_rust//rust/platform:x86_64-unknown-fuchsia": [], + "@rules_rust//rust/platform:x86_64-unknown-linux-gnu": [], + "@rules_rust//rust/platform:x86_64-unknown-nixos-gnu": [], + "@rules_rust//rust/platform:x86_64-unknown-none": [], + "@rules_rust//rust/platform:x86_64-unknown-uefi": [], + "//conditions:default": ["@platforms//:incompatible"], + }), + version = "0.3.32", +) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zstd-0.13.3.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zstd-0.13.3.bazel new file mode 100644 index 00000000000..2ba80632d93 --- /dev/null +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zstd-0.13.3.bazel @@ -0,0 +1,92 @@ +############################################################################### +# @generated +# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To +# regenerate this file, run the following: +# +# bazel run @@//misc/bazel/3rdparty:vendor_tree_sitter_extractors +############################################################################### + +load("@rules_rust//rust:defs.bzl", "rust_library") + +package(default_visibility = ["//visibility:public"]) + +rust_library( + name = "zstd", + srcs = glob( + include = ["**/*.rs"], + allow_empty = True, + ), + compile_data = glob( + include = ["**"], + allow_empty = True, + exclude = [ + "**/* *", + ".tmp_git_root/**/*", + "BUILD", + "BUILD.bazel", + "WORKSPACE", + "WORKSPACE.bazel", + ], + ), + crate_features = [ + "arrays", + "default", + "legacy", + "zdict_builder", + ], + crate_root = "src/lib.rs", + edition = "2018", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-bazel", + "crate-name=zstd", + "manual", + "noclippy", + "norustfmt", + ], + target_compatible_with = select({ + "@rules_rust//rust/platform:aarch64-apple-darwin": [], + "@rules_rust//rust/platform:aarch64-apple-ios": [], + "@rules_rust//rust/platform:aarch64-apple-ios-sim": [], + "@rules_rust//rust/platform:aarch64-linux-android": [], + "@rules_rust//rust/platform:aarch64-pc-windows-msvc": [], + "@rules_rust//rust/platform:aarch64-unknown-fuchsia": [], + "@rules_rust//rust/platform:aarch64-unknown-linux-gnu": [], + "@rules_rust//rust/platform:aarch64-unknown-nixos-gnu": [], + "@rules_rust//rust/platform:aarch64-unknown-nto-qnx710": [], + "@rules_rust//rust/platform:aarch64-unknown-uefi": [], + "@rules_rust//rust/platform:arm-unknown-linux-gnueabi": [], + "@rules_rust//rust/platform:armv7-linux-androideabi": [], + "@rules_rust//rust/platform:armv7-unknown-linux-gnueabi": [], + "@rules_rust//rust/platform:i686-apple-darwin": [], + "@rules_rust//rust/platform:i686-linux-android": [], + "@rules_rust//rust/platform:i686-pc-windows-msvc": [], + "@rules_rust//rust/platform:i686-unknown-freebsd": [], + "@rules_rust//rust/platform:i686-unknown-linux-gnu": [], + "@rules_rust//rust/platform:powerpc-unknown-linux-gnu": [], + "@rules_rust//rust/platform:riscv32imc-unknown-none-elf": [], + "@rules_rust//rust/platform:riscv64gc-unknown-none-elf": [], + "@rules_rust//rust/platform:s390x-unknown-linux-gnu": [], + "@rules_rust//rust/platform:thumbv7em-none-eabi": [], + "@rules_rust//rust/platform:thumbv8m.main-none-eabi": [], + "@rules_rust//rust/platform:wasm32-unknown-unknown": [], + "@rules_rust//rust/platform:wasm32-wasip1": [], + "@rules_rust//rust/platform:x86_64-apple-darwin": [], + "@rules_rust//rust/platform:x86_64-apple-ios": [], + "@rules_rust//rust/platform:x86_64-linux-android": [], + "@rules_rust//rust/platform:x86_64-pc-windows-msvc": [], + "@rules_rust//rust/platform:x86_64-unknown-freebsd": [], + "@rules_rust//rust/platform:x86_64-unknown-fuchsia": [], + "@rules_rust//rust/platform:x86_64-unknown-linux-gnu": [], + "@rules_rust//rust/platform:x86_64-unknown-nixos-gnu": [], + "@rules_rust//rust/platform:x86_64-unknown-none": [], + "@rules_rust//rust/platform:x86_64-unknown-uefi": [], + "//conditions:default": ["@platforms//:incompatible"], + }), + version = "0.13.3", + deps = [ + "@vendor_ts__zstd-safe-7.2.4//:zstd_safe", + ], +) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zstd-safe-7.2.4.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zstd-safe-7.2.4.bazel new file mode 100644 index 00000000000..265b6514b70 --- /dev/null +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zstd-safe-7.2.4.bazel @@ -0,0 +1,158 @@ +############################################################################### +# @generated +# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To +# regenerate this file, run the following: +# +# bazel run @@//misc/bazel/3rdparty:vendor_tree_sitter_extractors +############################################################################### + +load("@rules_rust//cargo:defs.bzl", "cargo_build_script") +load("@rules_rust//rust:defs.bzl", "rust_library") + +package(default_visibility = ["//visibility:public"]) + +rust_library( + name = "zstd_safe", + srcs = glob( + include = ["**/*.rs"], + allow_empty = True, + ), + compile_data = glob( + include = ["**"], + allow_empty = True, + exclude = [ + "**/* *", + ".tmp_git_root/**/*", + "BUILD", + "BUILD.bazel", + "WORKSPACE", + "WORKSPACE.bazel", + ], + ), + crate_features = [ + "arrays", + "legacy", + "std", + "zdict_builder", + ], + crate_root = "src/lib.rs", + edition = "2018", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-bazel", + "crate-name=zstd-safe", + "manual", + "noclippy", + "norustfmt", + ], + target_compatible_with = select({ + "@rules_rust//rust/platform:aarch64-apple-darwin": [], + "@rules_rust//rust/platform:aarch64-apple-ios": [], + "@rules_rust//rust/platform:aarch64-apple-ios-sim": [], + "@rules_rust//rust/platform:aarch64-linux-android": [], + "@rules_rust//rust/platform:aarch64-pc-windows-msvc": [], + "@rules_rust//rust/platform:aarch64-unknown-fuchsia": [], + "@rules_rust//rust/platform:aarch64-unknown-linux-gnu": [], + "@rules_rust//rust/platform:aarch64-unknown-nixos-gnu": [], + "@rules_rust//rust/platform:aarch64-unknown-nto-qnx710": [], + "@rules_rust//rust/platform:aarch64-unknown-uefi": [], + "@rules_rust//rust/platform:arm-unknown-linux-gnueabi": [], + "@rules_rust//rust/platform:armv7-linux-androideabi": [], + "@rules_rust//rust/platform:armv7-unknown-linux-gnueabi": [], + "@rules_rust//rust/platform:i686-apple-darwin": [], + "@rules_rust//rust/platform:i686-linux-android": [], + "@rules_rust//rust/platform:i686-pc-windows-msvc": [], + "@rules_rust//rust/platform:i686-unknown-freebsd": [], + "@rules_rust//rust/platform:i686-unknown-linux-gnu": [], + "@rules_rust//rust/platform:powerpc-unknown-linux-gnu": [], + "@rules_rust//rust/platform:riscv32imc-unknown-none-elf": [], + "@rules_rust//rust/platform:riscv64gc-unknown-none-elf": [], + "@rules_rust//rust/platform:s390x-unknown-linux-gnu": [], + "@rules_rust//rust/platform:thumbv7em-none-eabi": [], + "@rules_rust//rust/platform:thumbv8m.main-none-eabi": [], + "@rules_rust//rust/platform:wasm32-unknown-unknown": [], + "@rules_rust//rust/platform:wasm32-wasip1": [], + "@rules_rust//rust/platform:x86_64-apple-darwin": [], + "@rules_rust//rust/platform:x86_64-apple-ios": [], + "@rules_rust//rust/platform:x86_64-linux-android": [], + "@rules_rust//rust/platform:x86_64-pc-windows-msvc": [], + "@rules_rust//rust/platform:x86_64-unknown-freebsd": [], + "@rules_rust//rust/platform:x86_64-unknown-fuchsia": [], + "@rules_rust//rust/platform:x86_64-unknown-linux-gnu": [], + "@rules_rust//rust/platform:x86_64-unknown-nixos-gnu": [], + "@rules_rust//rust/platform:x86_64-unknown-none": [], + "@rules_rust//rust/platform:x86_64-unknown-uefi": [], + "//conditions:default": ["@platforms//:incompatible"], + }), + version = "7.2.4", + deps = [ + "@vendor_ts__zstd-safe-7.2.4//:build_script_build", + "@vendor_ts__zstd-sys-2.0.15-zstd.1.5.7//:zstd_sys", + ], +) + +cargo_build_script( + name = "_bs", + srcs = glob( + include = ["**/*.rs"], + allow_empty = True, + ), + compile_data = glob( + include = ["**"], + allow_empty = True, + exclude = [ + "**/* *", + "**/*.rs", + ".tmp_git_root/**/*", + "BUILD", + "BUILD.bazel", + "WORKSPACE", + "WORKSPACE.bazel", + ], + ), + crate_features = [ + "arrays", + "legacy", + "std", + "zdict_builder", + ], + crate_name = "build_script_build", + crate_root = "build.rs", + data = glob( + include = ["**"], + allow_empty = True, + exclude = [ + "**/* *", + ".tmp_git_root/**/*", + "BUILD", + "BUILD.bazel", + "WORKSPACE", + "WORKSPACE.bazel", + ], + ), + edition = "2018", + link_deps = [ + "@vendor_ts__zstd-sys-2.0.15-zstd.1.5.7//:zstd_sys", + ], + pkg_name = "zstd-safe", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-bazel", + "crate-name=zstd-safe", + "manual", + "noclippy", + "norustfmt", + ], + version = "7.2.4", + visibility = ["//visibility:private"], +) + +alias( + name = "build_script_build", + actual = ":_bs", + tags = ["manual"], +) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zstd-sys-2.0.15+zstd.1.5.7.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zstd-sys-2.0.15+zstd.1.5.7.bazel new file mode 100644 index 00000000000..7db2ad80d02 --- /dev/null +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zstd-sys-2.0.15+zstd.1.5.7.bazel @@ -0,0 +1,157 @@ +############################################################################### +# @generated +# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To +# regenerate this file, run the following: +# +# bazel run @@//misc/bazel/3rdparty:vendor_tree_sitter_extractors +############################################################################### + +load("@rules_rust//cargo:defs.bzl", "cargo_build_script") +load("@rules_rust//rust:defs.bzl", "rust_library") + +package(default_visibility = ["//visibility:public"]) + +rust_library( + name = "zstd_sys", + srcs = glob( + include = ["**/*.rs"], + allow_empty = True, + ), + compile_data = glob( + include = ["**"], + allow_empty = True, + exclude = [ + "**/* *", + ".tmp_git_root/**/*", + "BUILD", + "BUILD.bazel", + "WORKSPACE", + "WORKSPACE.bazel", + ], + ), + crate_features = [ + "legacy", + "std", + "zdict_builder", + ], + crate_root = "src/lib.rs", + edition = "2018", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-bazel", + "crate-name=zstd-sys", + "manual", + "noclippy", + "norustfmt", + ], + target_compatible_with = select({ + "@rules_rust//rust/platform:aarch64-apple-darwin": [], + "@rules_rust//rust/platform:aarch64-apple-ios": [], + "@rules_rust//rust/platform:aarch64-apple-ios-sim": [], + "@rules_rust//rust/platform:aarch64-linux-android": [], + "@rules_rust//rust/platform:aarch64-pc-windows-msvc": [], + "@rules_rust//rust/platform:aarch64-unknown-fuchsia": [], + "@rules_rust//rust/platform:aarch64-unknown-linux-gnu": [], + "@rules_rust//rust/platform:aarch64-unknown-nixos-gnu": [], + "@rules_rust//rust/platform:aarch64-unknown-nto-qnx710": [], + "@rules_rust//rust/platform:aarch64-unknown-uefi": [], + "@rules_rust//rust/platform:arm-unknown-linux-gnueabi": [], + "@rules_rust//rust/platform:armv7-linux-androideabi": [], + "@rules_rust//rust/platform:armv7-unknown-linux-gnueabi": [], + "@rules_rust//rust/platform:i686-apple-darwin": [], + "@rules_rust//rust/platform:i686-linux-android": [], + "@rules_rust//rust/platform:i686-pc-windows-msvc": [], + "@rules_rust//rust/platform:i686-unknown-freebsd": [], + "@rules_rust//rust/platform:i686-unknown-linux-gnu": [], + "@rules_rust//rust/platform:powerpc-unknown-linux-gnu": [], + "@rules_rust//rust/platform:riscv32imc-unknown-none-elf": [], + "@rules_rust//rust/platform:riscv64gc-unknown-none-elf": [], + "@rules_rust//rust/platform:s390x-unknown-linux-gnu": [], + "@rules_rust//rust/platform:thumbv7em-none-eabi": [], + "@rules_rust//rust/platform:thumbv8m.main-none-eabi": [], + "@rules_rust//rust/platform:wasm32-unknown-unknown": [], + "@rules_rust//rust/platform:wasm32-wasip1": [], + "@rules_rust//rust/platform:x86_64-apple-darwin": [], + "@rules_rust//rust/platform:x86_64-apple-ios": [], + "@rules_rust//rust/platform:x86_64-linux-android": [], + "@rules_rust//rust/platform:x86_64-pc-windows-msvc": [], + "@rules_rust//rust/platform:x86_64-unknown-freebsd": [], + "@rules_rust//rust/platform:x86_64-unknown-fuchsia": [], + "@rules_rust//rust/platform:x86_64-unknown-linux-gnu": [], + "@rules_rust//rust/platform:x86_64-unknown-nixos-gnu": [], + "@rules_rust//rust/platform:x86_64-unknown-none": [], + "@rules_rust//rust/platform:x86_64-unknown-uefi": [], + "//conditions:default": ["@platforms//:incompatible"], + }), + version = "2.0.15+zstd.1.5.7", + deps = [ + "@vendor_ts__zstd-sys-2.0.15-zstd.1.5.7//:build_script_build", + ], +) + +cargo_build_script( + name = "_bs", + srcs = glob( + include = ["**/*.rs"], + allow_empty = True, + ), + compile_data = glob( + include = ["**"], + allow_empty = True, + exclude = [ + "**/* *", + "**/*.rs", + ".tmp_git_root/**/*", + "BUILD", + "BUILD.bazel", + "WORKSPACE", + "WORKSPACE.bazel", + ], + ), + crate_features = [ + "legacy", + "std", + "zdict_builder", + ], + crate_name = "build_script_build", + crate_root = "build.rs", + data = glob( + include = ["**"], + allow_empty = True, + exclude = [ + "**/* *", + ".tmp_git_root/**/*", + "BUILD", + "BUILD.bazel", + "WORKSPACE", + "WORKSPACE.bazel", + ], + ), + edition = "2018", + links = "zstd", + pkg_name = "zstd-sys", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-bazel", + "crate-name=zstd-sys", + "manual", + "noclippy", + "norustfmt", + ], + version = "2.0.15+zstd.1.5.7", + visibility = ["//visibility:private"], + deps = [ + "@vendor_ts__cc-1.2.7//:cc", + "@vendor_ts__pkg-config-0.3.32//:pkg_config", + ], +) + +alias( + name = "build_script_build", + actual = ":_bs", + tags = ["manual"], +) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl b/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl index ee2044468e7..0247ee36d9f 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl @@ -381,6 +381,7 @@ _NORMAL_DEPENDENCIES = { "tracing": Label("@vendor_ts__tracing-0.1.41//:tracing"), "tracing-subscriber": Label("@vendor_ts__tracing-subscriber-0.3.19//:tracing_subscriber"), "tree-sitter": Label("@vendor_ts__tree-sitter-0.24.6//:tree_sitter"), + "zstd": Label("@vendor_ts__zstd-0.13.3//:zstd"), }, }, } @@ -1658,6 +1659,16 @@ def crate_repositories(): build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.itoa-1.0.15.bazel"), ) + maybe( + http_archive, + name = "vendor_ts__jobserver-0.1.32", + sha256 = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0", + type = "tar.gz", + urls = ["https://static.crates.io/crates/jobserver/0.1.32/download"], + strip_prefix = "jobserver-0.1.32", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.jobserver-0.1.32.bazel"), + ) + maybe( http_archive, name = "vendor_ts__jod-thread-0.1.2", @@ -2048,6 +2059,16 @@ def crate_repositories(): build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.pin-project-lite-0.2.16.bazel"), ) + maybe( + http_archive, + name = "vendor_ts__pkg-config-0.3.32", + sha256 = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c", + type = "tar.gz", + urls = ["https://static.crates.io/crates/pkg-config/0.3.32/download"], + strip_prefix = "pkg-config-0.3.32", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.pkg-config-0.3.32.bazel"), + ) + maybe( http_archive, name = "vendor_ts__portable-atomic-1.11.0", @@ -3647,6 +3668,36 @@ def crate_repositories(): build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.zerocopy-derive-0.8.20.bazel"), ) + maybe( + http_archive, + name = "vendor_ts__zstd-0.13.3", + sha256 = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a", + type = "tar.gz", + urls = ["https://static.crates.io/crates/zstd/0.13.3/download"], + strip_prefix = "zstd-0.13.3", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.zstd-0.13.3.bazel"), + ) + + maybe( + http_archive, + name = "vendor_ts__zstd-safe-7.2.4", + sha256 = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d", + type = "tar.gz", + urls = ["https://static.crates.io/crates/zstd-safe/7.2.4/download"], + strip_prefix = "zstd-safe-7.2.4", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.zstd-safe-7.2.4.bazel"), + ) + + maybe( + http_archive, + name = "vendor_ts__zstd-sys-2.0.15-zstd.1.5.7", + sha256 = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237", + type = "tar.gz", + urls = ["https://static.crates.io/crates/zstd-sys/2.0.15+zstd.1.5.7/download"], + strip_prefix = "zstd-sys-2.0.15+zstd.1.5.7", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.zstd-sys-2.0.15+zstd.1.5.7.bazel"), + ) + return [ struct(repo = "vendor_ts__anyhow-1.0.97", is_dev_dep = False), struct(repo = "vendor_ts__argfile-0.2.1", is_dev_dep = False), @@ -3698,6 +3749,7 @@ def crate_repositories(): struct(repo = "vendor_ts__tree-sitter-ruby-0.23.1", is_dev_dep = False), struct(repo = "vendor_ts__triomphe-0.1.14", is_dev_dep = False), struct(repo = "vendor_ts__ungrammar-1.16.1", is_dev_dep = False), + struct(repo = "vendor_ts__zstd-0.13.3", is_dev_dep = False), struct(repo = "vendor_ts__rand-0.9.0", is_dev_dep = True), struct(repo = "vendor_ts__tree-sitter-json-0.24.8", is_dev_dep = True), struct(repo = "vendor_ts__tree-sitter-ql-0.23.1", is_dev_dep = True), diff --git a/shared/tree-sitter-extractor/Cargo.toml b/shared/tree-sitter-extractor/Cargo.toml index 6bbda6dc83b..3bda73a774d 100644 --- a/shared/tree-sitter-extractor/Cargo.toml +++ b/shared/tree-sitter-extractor/Cargo.toml @@ -19,6 +19,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" chrono = { version = "0.4.40", features = ["serde"] } num_cpus = "1.16.0" +zstd = "0.13.3" [dev-dependencies] tree-sitter-ql = "0.23.1" From 923a2854cb3c9718f98bbff24fbcda3db23c7885 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 28 May 2025 16:09:03 +0200 Subject: [PATCH 83/86] Ruby, Rust: add `zstd` compression option --- ruby/codeql-extractor.yml | 6 +++--- rust/codeql-extractor.yml | 6 +++--- rust/extractor/src/config.rs | 2 ++ .../hello-project/test_project.py | 1 + shared/tree-sitter-extractor/src/trap.rs | 17 +++++++++++++++-- 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/ruby/codeql-extractor.yml b/ruby/codeql-extractor.yml index 9b949a1a4ab..abb50db2a29 100644 --- a/ruby/codeql-extractor.yml +++ b/ruby/codeql-extractor.yml @@ -27,7 +27,7 @@ options: title: Controls compression for the TRAP files written by the extractor. description: > This option is only intended for use in debugging the extractor. Accepted - values are 'gzip' (the default, to write gzip-compressed TRAP) and 'none' - (to write uncompressed TRAP). + values are 'gzip' (the default, to write gzip-compressed TRAP) 'zstd' (to + write Zstandard-compressed TRAP) and 'none' (to write uncompressed TRAP). type: string - pattern: "^(none|gzip)$" + pattern: "^(none|gzip|zstd)$" diff --git a/rust/codeql-extractor.yml b/rust/codeql-extractor.yml index 0ba77ee88d1..464a13e1c09 100644 --- a/rust/codeql-extractor.yml +++ b/rust/codeql-extractor.yml @@ -23,10 +23,10 @@ options: title: Controls compression for the TRAP files written by the extractor. description: > This option is only intended for use in debugging the extractor. Accepted - values are 'gzip' (to write gzip-compressed TRAP) and 'none' - (currently the default, to write uncompressed TRAP). + values are 'gzip' (the default, to write gzip-compressed TRAP) 'zstd' (to + write Zstandard-compressed TRAP) and 'none' (to write uncompressed TRAP). type: string - pattern: "^(none|gzip)$" + pattern: "^(none|gzip|zstd)$" cargo_target_dir: title: Directory to use for cargo output files. description: > diff --git a/rust/extractor/src/config.rs b/rust/extractor/src/config.rs index 3f3a37cf5f0..8124f825da3 100644 --- a/rust/extractor/src/config.rs +++ b/rust/extractor/src/config.rs @@ -29,6 +29,7 @@ pub enum Compression { #[default] // TODO make gzip default None, Gzip, + Zstd, } impl From for trap::Compression { @@ -36,6 +37,7 @@ impl From for trap::Compression { match val { Compression::None => Self::None, Compression::Gzip => Self::Gzip, + Compression::Zstd => Self::Zstd, } } } diff --git a/rust/ql/integration-tests/hello-project/test_project.py b/rust/ql/integration-tests/hello-project/test_project.py index 5b0eae903ac..a8c5e3384fb 100644 --- a/rust/ql/integration-tests/hello-project/test_project.py +++ b/rust/ql/integration-tests/hello-project/test_project.py @@ -20,6 +20,7 @@ def test_do_not_print_env(codeql, rust, rust_edition, cargo, check_env_not_dumpe @pytest.mark.ql_test("steps.ql", expected=".cargo.expected") @pytest.mark.parametrize(("rust_edition", "compression", "suffix"), [ pytest.param(2024, "gzip", ".gz", id="gzip"), + pytest.param(2024, "zstd", ".zst", id="zstd"), ]) def test_compression(codeql, rust, rust_edition, compression, suffix, cargo, rust_check_diagnostics, cwd): codeql.database.create(cleanup=False, _env={ diff --git a/shared/tree-sitter-extractor/src/trap.rs b/shared/tree-sitter-extractor/src/trap.rs index 4ad1e48eb6b..a636dc88551 100644 --- a/shared/tree-sitter-extractor/src/trap.rs +++ b/shared/tree-sitter-extractor/src/trap.rs @@ -96,10 +96,17 @@ impl Writer { self.write_trap_entries(&mut trap_file) } Compression::Gzip => { - let trap_file = GzEncoder::new(trap_file, flate2::Compression::fast()); + let trap_file = GzEncoder::new(trap_file, Compression::GZIP_LEVEL); let mut trap_file = BufWriter::new(trap_file); self.write_trap_entries(&mut trap_file) } + Compression::Zstd => { + let trap_file = zstd::stream::Encoder::new(trap_file, Compression::ZSTD_LEVEL)?; + let mut trap_file = BufWriter::new(trap_file); + self.write_trap_entries(&mut trap_file)?; + trap_file.into_inner()?.finish()?; + Ok(()) + } } } @@ -107,7 +114,7 @@ impl Writer { for trap_entry in &self.trap_output { writeln!(file, "{}", trap_entry)?; } - std::io::Result::Ok(()) + Ok(()) } } @@ -280,9 +287,13 @@ fn limit_string(string: &str, max_size: usize) -> &str { pub enum Compression { None, Gzip, + Zstd, } impl Compression { + pub const ZSTD_LEVEL: i32 = 2; + pub const GZIP_LEVEL: flate2::Compression = flate2::Compression::fast(); + pub fn from_env(var_name: &str) -> Result { match std::env::var(var_name) { Ok(method) => match Compression::from_string(&method) { @@ -298,6 +309,7 @@ impl Compression { match s.to_lowercase().as_ref() { "none" => Some(Compression::None), "gzip" => Some(Compression::Gzip), + "zstd" => Some(Compression::Zstd), _ => None, } } @@ -306,6 +318,7 @@ impl Compression { match self { Compression::None => "trap", Compression::Gzip => "trap.gz", + Compression::Zstd => "trap.zst", } } } From 8248c50bdfeae82310104bb5e4705f80c579fab4 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 28 May 2025 16:38:25 +0200 Subject: [PATCH 84/86] Rust: add `none` compression integration test --- .../hello-project/test_project.py | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/rust/ql/integration-tests/hello-project/test_project.py b/rust/ql/integration-tests/hello-project/test_project.py index a8c5e3384fb..7f53e78f7d4 100644 --- a/rust/ql/integration-tests/hello-project/test_project.py +++ b/rust/ql/integration-tests/hello-project/test_project.py @@ -19,14 +19,25 @@ def test_do_not_print_env(codeql, rust, rust_edition, cargo, check_env_not_dumpe @pytest.mark.ql_test("steps.ql", expected=".cargo.expected") @pytest.mark.parametrize(("rust_edition", "compression", "suffix"), [ - pytest.param(2024, "gzip", ".gz", id="gzip"), - pytest.param(2024, "zstd", ".zst", id="zstd"), + pytest.param(2024, "none", [], id="none"), + pytest.param(2024, "gzip", [".gz"], id="gzip"), + pytest.param(2024, "zstd", [".zst"], id="zstd"), ]) def test_compression(codeql, rust, rust_edition, compression, suffix, cargo, rust_check_diagnostics, cwd): - codeql.database.create(cleanup=False, _env={ - "CODEQL_EXTRACTOR_RUST_TRAP_COMPRESSION": compression, - }) + codeql.database.create( + _env={ + "CODEQL_EXTRACTOR_RUST_OPTION_TRAP_COMPRESSION": compression, + } + ) trap_files = [*(cwd / "test-db" / "trap").rglob("*.trap*")] - assert trap_files - files_with_wrong_format = [f for f in trap_files if f.suffix != suffix and f.name != "metadata.trap.gz"] - assert not files_with_wrong_format, f"Found trap files with wrong format: {files_with_wrong_format}" + assert trap_files, "No trap files found" + expected_suffixes = [".trap"] + suffix + + def is_of_expected_format(file): + return file.name == "metadata.trap.gz" or \ + file.suffixes[-len(expected_suffixes):] == expected_suffixes + + files_with_wrong_format = [ + f for f in trap_files if not is_of_expected_format(f) + ] + assert not files_with_wrong_format, f"Found trap files with wrong format" From fd00ed502d40e261e33d37dd8f9a5d6b7a39060c Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 28 May 2025 16:38:36 +0200 Subject: [PATCH 85/86] Ruby: add compression integration test --- .../compression/methods.expected | 1 + .../integration-tests/compression/methods.ql | 4 +++ .../integration-tests/compression/source.rb | 3 +++ ruby/ql/integration-tests/compression/test.py | 26 +++++++++++++++++++ 4 files changed, 34 insertions(+) create mode 100644 ruby/ql/integration-tests/compression/methods.expected create mode 100644 ruby/ql/integration-tests/compression/methods.ql create mode 100644 ruby/ql/integration-tests/compression/source.rb create mode 100644 ruby/ql/integration-tests/compression/test.py diff --git a/ruby/ql/integration-tests/compression/methods.expected b/ruby/ql/integration-tests/compression/methods.expected new file mode 100644 index 00000000000..2bdc091c80d --- /dev/null +++ b/ruby/ql/integration-tests/compression/methods.expected @@ -0,0 +1 @@ +| source.rb:1:1:3:3 | f | diff --git a/ruby/ql/integration-tests/compression/methods.ql b/ruby/ql/integration-tests/compression/methods.ql new file mode 100644 index 00000000000..208d26dee63 --- /dev/null +++ b/ruby/ql/integration-tests/compression/methods.ql @@ -0,0 +1,4 @@ +import codeql.ruby.AST + +from Method m +select m diff --git a/ruby/ql/integration-tests/compression/source.rb b/ruby/ql/integration-tests/compression/source.rb new file mode 100644 index 00000000000..360eabdab75 --- /dev/null +++ b/ruby/ql/integration-tests/compression/source.rb @@ -0,0 +1,3 @@ +def f + puts "hello" +end diff --git a/ruby/ql/integration-tests/compression/test.py b/ruby/ql/integration-tests/compression/test.py new file mode 100644 index 00000000000..6976b063d3e --- /dev/null +++ b/ruby/ql/integration-tests/compression/test.py @@ -0,0 +1,26 @@ +import pytest + + +@pytest.mark.parametrize(("compression", "suffix"), [ + pytest.param("none", [], id="none"), + pytest.param("gzip", [".gz"], id="gzip"), + pytest.param("zstd", [".zst"], id="zstd"), +]) +def test(codeql, ruby, compression, suffix, cwd): + codeql.database.create( + _env={ + "CODEQL_EXTRACTOR_RUBY_OPTION_TRAP_COMPRESSION": compression, + } + ) + trap_files = [*(cwd / "test-db" / "trap").rglob("*.trap*")] + assert trap_files, "No trap files found" + expected_suffixes = [".trap"] + suffix + + def is_of_expected_format(file): + return file.name == "metadata.trap.gz" or \ + file.suffixes[-len(expected_suffixes):] == expected_suffixes + + files_with_wrong_format = [ + f for f in trap_files if not is_of_expected_format(f) + ] + assert not files_with_wrong_format, f"Found trap files with wrong format" From c8f5e26200f8eb91650185ed41395d8424ab2952 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 28 May 2025 16:48:02 +0200 Subject: [PATCH 86/86] Rust: fix compression option description --- rust/codeql-extractor.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rust/codeql-extractor.yml b/rust/codeql-extractor.yml index 464a13e1c09..ce876e8d3ff 100644 --- a/rust/codeql-extractor.yml +++ b/rust/codeql-extractor.yml @@ -23,8 +23,9 @@ options: title: Controls compression for the TRAP files written by the extractor. description: > This option is only intended for use in debugging the extractor. Accepted - values are 'gzip' (the default, to write gzip-compressed TRAP) 'zstd' (to - write Zstandard-compressed TRAP) and 'none' (to write uncompressed TRAP). + values are 'gzip' (to write gzip-compressed TRAP) 'zstd' (to write + Zstandard-compressed TRAP) and 'none' (the default, to write uncompressed + TRAP). type: string pattern: "^(none|gzip|zstd)$" cargo_target_dir: