diff --git a/Cargo.lock b/Cargo.lock index 2d1aa7a7786..ea3c0b74f75 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4778,6 +4778,7 @@ dependencies = [ "aptos-framework", "aptos-gas-algebra", "aptos-gas-schedule", + "aptos-logger", "aptos-move-stdlib", "aptos-native-interface", "aptos-table-natives", diff --git a/aptos-move/aptos-release-builder/src/components/feature_flags.rs b/aptos-move/aptos-release-builder/src/components/feature_flags.rs index 512fd30cbf0..ad14f1838ef 100644 --- a/aptos-move/aptos-release-builder/src/components/feature_flags.rs +++ b/aptos-move/aptos-release-builder/src/components/feature_flags.rs @@ -368,7 +368,7 @@ impl From for AptosFeatureFlag { }, FeatureFlag::EnableEnumTypes => AptosFeatureFlag::ENABLE_ENUM_TYPES, FeatureFlag::EnableResourceAccessControl => { - AptosFeatureFlag::ENABLE_RESOURCE_ACCESS_CONTROL + AptosFeatureFlag::_DEPRECATED_ENABLE_RESOURCE_ACCESS_CONTROL }, FeatureFlag::RejectUnstableBytecodeForScript => { AptosFeatureFlag::_REJECT_UNSTABLE_BYTECODE_FOR_SCRIPT @@ -554,7 +554,7 @@ impl From for FeatureFlag { FeatureFlag::UseCompatibilityCheckerV2 }, AptosFeatureFlag::ENABLE_ENUM_TYPES => FeatureFlag::EnableEnumTypes, - AptosFeatureFlag::ENABLE_RESOURCE_ACCESS_CONTROL => { + AptosFeatureFlag::_DEPRECATED_ENABLE_RESOURCE_ACCESS_CONTROL => { FeatureFlag::EnableResourceAccessControl }, AptosFeatureFlag::_REJECT_UNSTABLE_BYTECODE_FOR_SCRIPT => { diff --git a/aptos-move/aptos-vm-environment/Cargo.toml b/aptos-move/aptos-vm-environment/Cargo.toml index 90322871d99..37d33c0c57d 100644 --- a/aptos-move/aptos-vm-environment/Cargo.toml +++ b/aptos-move/aptos-vm-environment/Cargo.toml @@ -16,6 +16,7 @@ rust-version = { workspace = true } aptos-framework = { workspace = true } aptos-gas-algebra = { workspace = true } aptos-gas-schedule = { workspace = true } +aptos-logger = { workspace = true } aptos-move-stdlib = { workspace = true } aptos-native-interface = { workspace = true } aptos-table-natives = { workspace = true } diff --git a/aptos-move/aptos-vm-environment/src/prod_configs.rs b/aptos-move/aptos-vm-environment/src/prod_configs.rs index e6856b7ceac..0291dfd3fbc 100644 --- a/aptos-move/aptos-vm-environment/src/prod_configs.rs +++ b/aptos-move/aptos-vm-environment/src/prod_configs.rs @@ -6,6 +6,7 @@ use aptos_gas_schedule::{ gas_feature_versions::{RELEASE_V1_15, RELEASE_V1_30, RELEASE_V1_34, RELEASE_V1_38}, AptosGasParameters, }; +use aptos_logger::warn; use aptos_types::{ on_chain_config::{ randomness_api_v0_config::{AllowCustomMaxGasFlag, RequiredGasDeposit}, @@ -122,8 +123,14 @@ pub fn aptos_prod_verifier_config(gas_feature_version: u64, features: &Features) features.is_enabled(FeatureFlag::SIGNATURE_CHECKER_V2_SCRIPT_FIX); let sig_checker_v2_fix_function_signatures = gas_feature_version >= RELEASE_V1_34; let enable_enum_types = features.is_enabled(FeatureFlag::ENABLE_ENUM_TYPES); - let enable_resource_access_control = - features.is_enabled(FeatureFlag::ENABLE_RESOURCE_ACCESS_CONTROL); + // Resource access control has been removed from the VM, so the on-chain flag no longer has + // any effect: access specifiers are rejected at verification and never enforced at runtime. + if features.is_enabled(FeatureFlag::_DEPRECATED_ENABLE_RESOURCE_ACCESS_CONTROL) { + warn!( + "On-chain feature ENABLE_RESOURCE_ACCESS_CONTROL is enabled but has been \ + removed; ignoring it." + ); + } let enable_function_values = features.is_enabled(FeatureFlag::ENABLE_FUNCTION_VALUES); // Note: we reuse the `enable_function_values` flag to set various stricter limits on types. @@ -153,7 +160,7 @@ pub fn aptos_prod_verifier_config(gas_feature_version: u64, features: &Features) sig_checker_v2_fix_script_ty_param_count, sig_checker_v2_fix_function_signatures, enable_enum_types, - enable_resource_access_control, + _enable_resource_access_control: false, enable_function_values, max_function_return_values: if enable_function_values { Some(128) diff --git a/aptos-move/e2e-move-tests/src/tests/move_feature_gating.rs b/aptos-move/e2e-move-tests/src/tests/move_feature_gating.rs index 22484567903..98f3e4d7a75 100644 --- a/aptos-move/e2e-move-tests/src/tests/move_feature_gating.rs +++ b/aptos-move/e2e-move-tests/src/tests/move_feature_gating.rs @@ -44,38 +44,6 @@ fn enum_types(enabled: Vec, disabled: Vec) { } } -#[rstest(enabled, disabled, - case(vec![], vec![FeatureFlag::ENABLE_RESOURCE_ACCESS_CONTROL]), - case(vec![FeatureFlag::ENABLE_RESOURCE_ACCESS_CONTROL], vec![]), -)] -fn resource_access_control(enabled: Vec, disabled: Vec) { - let positive_test = !enabled.is_empty(); - let mut h = MoveHarness::new_with_features(enabled, disabled); - let acc = h.new_account_at(AccountAddress::from_hex_literal("0x815").unwrap()); - - let mut builder = PackageBuilder::new("Package"); - let source = r#" - module 0x815::m { - struct R has key, copy {} - fun read(a: address): R reads R { - *borrow_global(a) - } - } - "#; - builder.add_source("m.move", source); - let path = builder.write_to_temp().unwrap(); - let result = h.publish_package_with_options( - &acc, - path.path(), - BuildOptions::move_2().set_latest_language(), - ); - if positive_test { - assert_success!(result); - } else { - assert_vm_status!(result, StatusCode::FEATURE_NOT_ENABLED); - } -} - #[test] fn function_values() { let sources = &[ diff --git a/third_party/move/move-binary-format/src/proptest_types.rs b/third_party/move/move-binary-format/src/proptest_types.rs index 13bb5d968b3..0961b6f70af 100644 --- a/third_party/move/move-binary-format/src/proptest_types.rs +++ b/third_party/move/move-binary-format/src/proptest_types.rs @@ -89,7 +89,6 @@ pub struct CompiledModuleStrategyGen { parameters_count: SizeRange, return_count: SizeRange, func_type_params: SizeRange, - access_specifiers_count: SizeRange, acquires_count: SizeRange, random_sigs_count: SizeRange, tokens_per_random_sig_count: SizeRange, @@ -106,7 +105,6 @@ impl CompiledModuleStrategyGen { parameters_count: (0..4).into(), return_count: (0..3).into(), func_type_params: (0..3).into(), - access_specifiers_count: (0..8).into(), acquires_count: (0..2).into(), random_sigs_count: (0..5).into(), tokens_per_random_sig_count: (0..5).into(), @@ -185,7 +183,6 @@ impl CompiledModuleStrategyGen { self.parameters_count.clone(), self.return_count.clone(), self.func_type_params.clone(), - self.access_specifiers_count.clone(), ), 1..=self.size, ); diff --git a/third_party/move/move-binary-format/src/proptest_types/functions.rs b/third_party/move/move-binary-format/src/proptest_types/functions.rs index bd41e1b1fce..dfa55fb38d8 100644 --- a/third_party/move/move-binary-format/src/proptest_types/functions.rs +++ b/third_party/move/move-binary-format/src/proptest_types/functions.rs @@ -4,7 +4,7 @@ use crate::{ file_format::{ - AccessSpecifier, Bytecode, CodeOffset, CodeUnit, ConstantPoolIndex, FieldHandle, + Bytecode, CodeOffset, CodeUnit, ConstantPoolIndex, FieldHandle, FieldHandleIndex, FieldInstantiation, FieldInstantiationIndex, FunctionDefinition, FunctionHandle, FunctionHandleIndex, FunctionInstantiation, FunctionInstantiationIndex, IdentifierIndex, LocalIndex, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, @@ -24,7 +24,6 @@ use crate::{ use move_core_types::{ability::AbilitySet, int256::U256}; use proptest::{ collection::{vec, SizeRange}, - option::of, prelude::*, sample::{select, Index as PropIndex}, }; @@ -168,7 +167,6 @@ pub struct FunctionHandleGen { parameters: SignatureGen, return_: SignatureGen, type_parameters: Vec, - access_specifiers: Option>, } impl FunctionHandleGen { @@ -176,7 +174,6 @@ impl FunctionHandleGen { param_count: impl Into, return_count: impl Into, type_parameter_count: impl Into, - access_specifiers_count: impl Into, ) -> impl Strategy { let return_count = return_count.into(); let param_count = param_count.into(); @@ -186,18 +183,14 @@ impl FunctionHandleGen { SignatureGen::strategy(param_count), SignatureGen::strategy(return_count), vec(AbilitySetGen::strategy(), type_parameter_count), - of(vec(any::(), access_specifiers_count)), ) - .prop_map( - |(module, name, parameters, return_, type_parameters, access_specifiers)| Self { - module, - name, - parameters, - return_, - type_parameters, - access_specifiers, - }, - ) + .prop_map(|(module, name, parameters, return_, type_parameters)| Self { + module, + name, + parameters, + return_, + type_parameters, + }) } pub fn materialize(self, state: &mut FnHandleMaterializeState) -> Option { @@ -227,7 +220,8 @@ impl FunctionHandleGen { parameters: params_idx, return_: return_idx, type_parameters, - access_specifiers: self.access_specifiers, + // Resource access control has been removed; the verifier rejects any specifiers. + access_specifiers: None, attributes: vec![], }) } diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/access_specifier_tests.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/access_specifier_tests.rs new file mode 100644 index 00000000000..41089db8293 --- /dev/null +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/access_specifier_tests.rs @@ -0,0 +1,74 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! Resource access control has been removed, so access specifiers are rejected regardless of +//! configuration. Only hand-crafted bytecode can still carry them; no compiler emits them. + +use move_binary_format::{ + file_format::{ + basic_test_module, empty_script, AccessKind, AccessSpecifier, AddressIdentifierIndex, + AddressSpecifier, ResourceSpecifier, TableIndex, + }, + CompiledModule, +}; +use move_bytecode_verifier::VerifierConfig; +use move_core_types::{account_address::AccountAddress, vm_status::StatusCode}; + +/// An access specifier reading any resource declared at the address added to `addresses`. +fn reads_any_at_new_address(addresses: &mut Vec) -> AccessSpecifier { + let addr = AddressIdentifierIndex::new(addresses.len() as TableIndex); + addresses.push(AccountAddress::ONE); + AccessSpecifier { + kind: AccessKind::Reads, + negated: false, + resource: ResourceSpecifier::DeclaredAtAddress(addr), + address: AddressSpecifier::Any, + } +} + +fn module_with_access_specifiers() -> CompiledModule { + let mut m = basic_test_module(); + let specifier = reads_any_at_new_address(&mut m.address_identifiers); + m.function_handles[0].access_specifiers = Some(vec![specifier]); + m +} + +#[test] +fn module_access_specifiers_are_rejected() { + let m = module_with_access_specifiers(); + let err = move_bytecode_verifier::verify_module_with_config(&VerifierConfig::production(), &m) + .unwrap_err(); + assert_eq!(err.major_status(), StatusCode::FEATURE_NOT_ENABLED); +} + +#[test] +fn script_access_specifiers_are_rejected() { + let mut s = empty_script(); + let specifier = reads_any_at_new_address(&mut s.address_identifiers); + s.access_specifiers = Some(vec![specifier]); + let err = move_bytecode_verifier::verify_script_with_config(&VerifierConfig::production(), &s) + .unwrap_err(); + assert_eq!(err.major_status(), StatusCode::FEATURE_NOT_ENABLED); +} + +/// The same module without access specifiers must verify, so that the rejections above are +/// attributable to the specifiers rather than to an unrelated defect in the test fixtures. +#[test] +fn module_without_access_specifiers_is_accepted() { + let mut m = module_with_access_specifiers(); + m.function_handles[0].access_specifiers = None; + assert!( + move_bytecode_verifier::verify_module_with_config(&VerifierConfig::production(), &m) + .is_ok() + ); +} + +#[test] +fn script_without_access_specifiers_is_accepted() { + let s = empty_script(); + assert!(s.access_specifiers.is_none()); + assert!( + move_bytecode_verifier::verify_script_with_config(&VerifierConfig::production(), &s) + .is_ok() + ); +} diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/mod.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/mod.rs index 5eed1537473..9eaf7004b5c 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/mod.rs +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/mod.rs @@ -2,6 +2,7 @@ // Copyright (c) The Move Contributors // SPDX-License-Identifier: Apache-2.0 +pub mod access_specifier_tests; pub mod binary_samples; pub mod bounds_tests; pub mod catch_unwind; diff --git a/third_party/move/move-bytecode-verifier/src/features.rs b/third_party/move/move-bytecode-verifier/src/features.rs index 3376d1ea1fb..e0b11922fd3 100644 --- a/third_party/move/move-bytecode-verifier/src/features.rs +++ b/third_party/move/move-bytecode-verifier/src/features.rs @@ -55,9 +55,9 @@ impl<'a> FeatureVerifier<'a> { }; verifier.verify_signatures()?; verifier.verify_function_handles()?; - if !config.enable_resource_access_control && script.access_specifiers.is_some() { + if script.access_specifiers.is_some() { return Err(PartialVMError::new(StatusCode::FEATURE_NOT_ENABLED) - .with_message("resource access control feature not enabled".to_string())); + .with_message("resource access control is not supported".to_string())); } verifier.verify_code(&script.code.code, None) } @@ -106,20 +106,16 @@ impl<'a> FeatureVerifier<'a> { } fn verify_function_handles(&self) -> PartialVMResult<()> { - if !self.config.enable_resource_access_control || !self.config.enable_function_values { - for (idx, function_handle) in self.code.function_handles().iter().enumerate() { - if !self.config.enable_resource_access_control - && function_handle.access_specifiers.is_some() - { - return Err(PartialVMError::new(StatusCode::FEATURE_NOT_ENABLED) - .at_index(IndexKind::FunctionHandle, idx as u16) - .with_message("resource access control feature not enabled".to_string())); - } - if !self.config.enable_function_values && !function_handle.attributes.is_empty() { - return Err(PartialVMError::new(StatusCode::FEATURE_NOT_ENABLED) - .at_index(IndexKind::FunctionDefinition, idx as u16) - .with_message("function value feature not enabled".to_string())); - } + for (idx, function_handle) in self.code.function_handles().iter().enumerate() { + if function_handle.access_specifiers.is_some() { + return Err(PartialVMError::new(StatusCode::FEATURE_NOT_ENABLED) + .at_index(IndexKind::FunctionHandle, idx as u16) + .with_message("resource access control is not supported".to_string())); + } + if !self.config.enable_function_values && !function_handle.attributes.is_empty() { + return Err(PartialVMError::new(StatusCode::FEATURE_NOT_ENABLED) + .at_index(IndexKind::FunctionDefinition, idx as u16) + .with_message("function value feature not enabled".to_string())); } } Ok(()) diff --git a/third_party/move/move-bytecode-verifier/src/verifier.rs b/third_party/move/move-bytecode-verifier/src/verifier.rs index cb1efd45341..a429c0e0f00 100644 --- a/third_party/move/move-bytecode-verifier/src/verifier.rs +++ b/third_party/move/move-bytecode-verifier/src/verifier.rs @@ -55,7 +55,10 @@ pub struct VerifierConfig { pub _use_signature_checker_v2: bool, pub sig_checker_v2_fix_script_ty_param_count: bool, pub enable_enum_types: bool, - pub enable_resource_access_control: bool, + // Deprecated: resource access control has been removed. Access specifiers are always + // rejected, regardless of this field, which is kept only to preserve the serialized + // layout of this config. + pub _enable_resource_access_control: bool, pub enable_function_values: bool, /// Maximum number of function return values. pub max_function_return_values: Option, @@ -263,7 +266,7 @@ impl Default for VerifierConfig { sig_checker_v2_fix_function_signatures: true, enable_enum_types: true, - enable_resource_access_control: true, + _enable_resource_access_control: false, enable_function_values: true, max_function_return_values: None, @@ -312,7 +315,7 @@ impl VerifierConfig { sig_checker_v2_fix_function_signatures: true, enable_enum_types: true, - enable_resource_access_control: true, + _enable_resource_access_control: false, enable_function_values: true, max_function_return_values: Some(128), diff --git a/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/ast.rs b/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/ast.rs index 19b16bf754e..3aa0a7b9fe2 100644 --- a/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/ast.rs +++ b/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/ast.rs @@ -224,43 +224,10 @@ pub struct Function { pub entry: Option, pub signature: FunctionSignature, pub acquires: Vec, - // Only v2 compiler - pub access_specifiers: Option>, pub body: FunctionBody, pub specs: BTreeMap, } -#[derive(PartialEq, Clone, Debug)] -pub struct AccessSpecifier_ { - pub kind: AccessSpecifierKind, - pub negated: bool, - pub module_address: Option
, - pub module_name: Option, - pub resource_name: Option, - pub type_args: Option>, - pub address: AddressSpecifier, -} - -#[derive(PartialEq, Clone, Debug)] -pub enum AccessSpecifierKind { - Reads, - Writes, - LegacyAcquires, -} - -pub type AccessSpecifier = Spanned; - -#[derive(PartialEq, Clone, Debug)] -pub enum AddressSpecifier_ { - Any, - Empty, - Literal(NumericalAddress), - Name(Name), - Call(ModuleAccess, Option>, Name), -} - -pub type AddressSpecifier = Spanned; - //************************************************************************************************** // Constants //************************************************************************************************** @@ -1384,7 +1351,6 @@ impl AstDebug for (FunctionName, &Function) { entry, signature, acquires, - access_specifiers: _, body, specs: _specs, }, diff --git a/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/translate.rs b/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/translate.rs index 2cb48f12e88..0fa75fe2b59 100644 --- a/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/translate.rs +++ b/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/translate.rs @@ -10,15 +10,14 @@ use crate::{ expansion::{ aliases::{AliasMap, AliasSet}, ast::{ - self as E, AccessSpecifierKind, Address, Fields, LValueOrDotDot_, LValue_, - ModuleAccess_, ModuleIdent, ModuleIdent_, SequenceItem_, SpecId, + self as E, Address, Fields, LValueOrDotDot_, LValue_, ModuleAccess_, ModuleIdent, + ModuleIdent_, SequenceItem_, SpecId, }, byte_string, hex_string, }, parser::ast::{ - self as P, Ability, AccessSpecifier_, AddressSpecifier_, CallKind, ConstantName, Field, - FunctionName, LeadingNameAccess_, ModuleMember, ModuleName, NameAccessChain, - NameAccessChain_, StructName, Var, + self as P, Ability, AccessSpecifier_, CallKind, ConstantName, Field, FunctionName, + LeadingNameAccess_, ModuleMember, ModuleName, StructName, Var, }, shared::{ builtins, @@ -1640,7 +1639,14 @@ fn function_(context: &mut Context, pfunction: P::Function) -> (FunctionName, E: let attributes = flatten_attributes(context, AttributePosition::Function, pattributes); let visibility = visibility(pvisibility); let (old_aliases, signature) = function_signature(context, psignature); - let (acquires, access_specifiers) = (vec![], access_specifier_list(context, access_specifiers)); + let acquires = access_specifiers + .unwrap_or_default() + .into_iter() + .filter_map(|specifier| { + let AccessSpecifier_(chain) = specifier.value; + name_access_chain(context, Access::Type, chain, Some(DeprecatedItem::Struct)) + }) + .collect(); let body = function_body(context, pbody); let specs = context.extract_exp_specs(); let fdef = E::Function { @@ -1651,7 +1657,6 @@ fn function_(context: &mut Context, pfunction: P::Function) -> (FunctionName, E: entry, signature, acquires, - access_specifiers, body, specs, }; @@ -1660,18 +1665,6 @@ fn function_(context: &mut Context, pfunction: P::Function) -> (FunctionName, E: (name, fdef) } -fn access_specifier_list( - context: &mut Context, - access_specifiers: Option>, -) -> Option> { - access_specifiers.map(|specs| { - specs - .into_iter() - .map(|s| access_specifier(context, s)) - .collect::>() - }) -} - fn invalid_variant_access(context: &mut Context, loc: Loc) { context.env.add_diag(diag!( Syntax::InvalidVariantAccess, @@ -1679,173 +1672,6 @@ fn invalid_variant_access(context: &mut Context, loc: Loc) { )); } -fn access_specifier(context: &mut Context, specifier: P::AccessSpecifier) -> E::AccessSpecifier { - let (negated, kind, chain, type_args, address) = match specifier.value { - AccessSpecifier_::Acquires(negated, chain, type_args, address) => ( - negated, - AccessSpecifierKind::LegacyAcquires, - chain, - type_args, - address, - ), - AccessSpecifier_::Reads(negated, chain, type_args, address) => ( - negated, - AccessSpecifierKind::Reads, - chain, - type_args, - address, - ), - AccessSpecifier_::Writes(negated, chain, type_args, address) => ( - negated, - AccessSpecifierKind::Writes, - chain, - type_args, - address, - ), - }; - let (module_address, module_name, resource_name) = - access_specifier_name_access_chain(context, chain); - let type_args = optional_types(context, type_args); - let address = address_specifier(context, address); - sp(specifier.loc, E::AccessSpecifier_ { - kind, - negated, - module_address, - module_name, - resource_name, - type_args, - address, - }) -} - -fn access_specifier_name_access_chain( - context: &mut Context, - chain: NameAccessChain, -) -> (Option
, Option, Option) { - match chain.value { - NameAccessChain_::Four(..) => { - invalid_variant_access(context, chain.loc); - (None, None, None) - }, - NameAccessChain_::One(name) if name.value.as_str() == "*" => { - // A single wildcard means any resource at the specified address, e.g. `*(0x2)` - (None, None, None) - }, - NameAccessChain_::One(name) => { - // A single name is resolved as a member - match context.aliases.member_alias_get(&name) { - Some((mident, mem)) => ( - Some(mident.value.address), - Some(mident.value.module), - Some(mem), - ), - None => (None, None, Some(name)), - } - }, - NameAccessChain_::Two(leading, second) => { - match leading.value { - LeadingNameAccess_::AnonymousAddress(_) => { - // An address with just one following name cannot be a resource, - // so we reject it - context.env.add_diag(diag!( - Syntax::InvalidAccessSpecifier, - ( - chain.loc, - "address followed by single name is not a valid access specifier" - .to_owned() - ) - )); - (None, None, None) - }, - LeadingNameAccess_::Name(name) => { - if context - .named_address_mapping - .as_ref() - .unwrap() - .get(&name.value) - .is_some() - { - // This resolves as an address, so the second name must be a module, - // which we reject. - context.env.add_diag(diag!( - Syntax::InvalidAccessSpecifier, - ( - chain.loc, - format!( - "`{}` is an address alias which followed by a name is \ - not a valid access specifier", - name.value - ) - ) - )); - (None, None, None) - } else if let Some(ident) = context.aliases.module_alias_get(&name) { - // Resolves as a module alias - let ModuleIdent_ { address, module } = ident.value; - (Some(address), Some(module), Some(second)) - } else { - context.env.add_diag(diag!( - NameResolution::UnboundModule, - (name.loc, format!("Unbound module alias '{}'", name)) - )); - (None, None, None) - } - }, - } - }, - NameAccessChain_::Three(prefix, third) => { - // This case is determined to be an address followed by module followed by resource - let (leading, second) = prefix.value; - let addr = match leading.value { - LeadingNameAccess_::AnonymousAddress(addr) => addr, - LeadingNameAccess_::Name(name) => { - if let Some(addr) = context - .named_address_mapping - .as_ref() - .unwrap() - .get(&name.value) - { - *addr - } else { - context - .env - .add_diag(address_without_value_error(false, name.loc, &name)); - NumericalAddress::DEFAULT_ERROR_ADDRESS - } - }, - }; - ( - Some(Address::Numerical(None, sp(leading.loc, addr))), - Some(ModuleName(second)), - Some(third), - ) - }, - } -} - -fn address_specifier(context: &mut Context, specifier: P::AddressSpecifier) -> E::AddressSpecifier { - let s = match specifier.value { - AddressSpecifier_::Empty => E::AddressSpecifier_::Empty, - AddressSpecifier_::Any => E::AddressSpecifier_::Any, - AddressSpecifier_::Literal(addr) => E::AddressSpecifier_::Literal(addr), - AddressSpecifier_::Name(name) => E::AddressSpecifier_::Name(name), - AddressSpecifier_::Call(chain, type_args, name) => { - if let Some(maccess) = name_access_chain( - context, - Access::ApplyPositional, - chain, - Some(DeprecatedItem::Function), - ) { - E::AddressSpecifier_::Call(maccess, optional_types(context, type_args), name) - } else { - debug_assert!(context.env.has_errors()); - E::AddressSpecifier_::Any - } - }, - }; - sp(specifier.loc, s) -} - fn visibility(pvisibility: P::Visibility) -> E::Visibility { match pvisibility { P::Visibility::Public(loc) => E::Visibility::Public(loc), diff --git a/third_party/move/move-compiler-v2/legacy-move-compiler/src/parser/ast.rs b/third_party/move/move-compiler-v2/legacy-move-compiler/src/parser/ast.rs index 0fb02075971..c9ff2e503cd 100644 --- a/third_party/move/move-compiler-v2/legacy-move-compiler/src/parser/ast.rs +++ b/third_party/move/move-compiler-v2/legacy-move-compiler/src/parser/ast.rs @@ -248,35 +248,12 @@ pub const NATIVE_MODIFIER: &str = "native"; pub const ENTRY_MODIFIER: &str = "entry"; pub const ENUM_MODIFIER: &str = "enum"; -/// An access specifier describes the resources being accessed by a function. -/// In contrast to regular `NameAccessChain`, the identifiers inside of the -/// chain can be wildcards (`*`). +/// An access specifier describes a resource acquired by a function. #[derive(Debug, Clone, PartialEq)] -pub enum AccessSpecifier_ { - Acquires(bool, NameAccessChain, Option>, AddressSpecifier), - Reads(bool, NameAccessChain, Option>, AddressSpecifier), - Writes(bool, NameAccessChain, Option>, AddressSpecifier), -} +pub struct AccessSpecifier_(pub NameAccessChain); pub type AccessSpecifier = Spanned; -/// An address specifier specifies the address at which a resource is accessed. -#[derive(Debug, Clone, PartialEq)] -pub enum AddressSpecifier_ { - /// Represents that no address was specified, as in `Resource` - Empty, - /// Represents that the specified address is a wildcard, as in `Resource(*)`. - Any, - /// Represents the precise address. - Literal(NumericalAddress), - /// Represents a parameter name. - Name(Name), - /// Represents a function applied to a parameter name. - Call(NameAccessChain, Option>, Name), -} - -pub type AddressSpecifier = Spanned; - #[derive(PartialEq, Clone, Debug)] pub struct FunctionSignature { pub type_parameters: Vec<(Name, Vec)>, diff --git a/third_party/move/move-compiler-v2/legacy-move-compiler/src/parser/syntax.rs b/third_party/move/move-compiler-v2/legacy-move-compiler/src/parser/syntax.rs index 0ec285f7f28..5f3c006aaf2 100644 --- a/third_party/move/move-compiler-v2/legacy-move-compiler/src/parser/syntax.rs +++ b/third_party/move/move-compiler-v2/legacy-move-compiler/src/parser/syntax.rs @@ -2860,71 +2860,12 @@ fn parse_function_decl( sp(name.loc(), Type_::Unit) }; - // "pure" | ( ( "!" )? ("acquires" | "reads" | "writes" ) )* - let mut access_specifiers = vec![]; - let mut pure_loc = None; - loop { - let negated = if context.tokens.peek() == Tok::Exclaim { - require_move_2_and_advance(context, "access specifiers")?; - true - } else { - false - }; - match context.tokens.peek() { - Tok::Acquires => { - context.tokens.advance()?; - access_specifiers.extend(parse_access_specifier_list( - context, - negated, - &AccessSpecifier_::Acquires, - )?) - }, - Tok::Identifier if context.tokens.content() == "reads" => { - require_move_2_and_advance(context, "access specifiers")?; - access_specifiers.extend(parse_access_specifier_list( - context, - negated, - &AccessSpecifier_::Reads, - )?) - }, - Tok::Identifier if context.tokens.content() == "writes" => { - require_move_2_and_advance(context, "access specifiers")?; - access_specifiers.extend(parse_access_specifier_list( - context, - negated, - &AccessSpecifier_::Writes, - )?) - }, - Tok::Identifier if context.tokens.content() == "pure" => { - pure_loc = Some(current_token_loc(context.tokens)); - require_move_2_and_advance(context, "access specifiers")?; - if negated { - return Err(Box::new(diag!( - Syntax::InvalidAccessSpecifier, - (pure_loc.unwrap(), "'pure' cannot be negated") - ))); - } - }, - _ => break, - } - } - let access_specifiers = if let Some(loc) = pure_loc { - if !access_specifiers.is_empty() { - return Err(Box::new(diag!( - Syntax::InvalidAccessSpecifier, - ( - loc, - "'pure' cannot be mixed with 'acquires'/`reads'/'writes'" - ) - ))); - } - // pure is represented by an empty access list - Some(vec![]) - } else if access_specifiers.is_empty() { - // no specifiers is represented as None - None + // ("acquires" ("," )*)? + let access_specifiers = if context.tokens.peek() == Tok::Acquires { + context.tokens.advance()?; + Some(parse_acquires_list(context)?) } else { - Some(access_specifiers) + None }; let body = match native { @@ -2977,23 +2918,20 @@ fn parse_parameter(context: &mut Context) -> Result<(Var, Type), Box Ok((v, t)) } -// Parse an access specifier list: -// AccessSpecifierList = ( "," )* ","? -fn parse_access_specifier_list( - context: &mut Context, - negated: bool, - ctor: &impl Fn(bool, NameAccessChain, Option>, AddressSpecifier) -> AccessSpecifier_, -) -> Result, Box> { - let mut chain = vec![]; +// Parse an acquires list: +// AcquiresList = ( "," )* ","? +fn parse_acquires_list(context: &mut Context) -> Result, Box> { + let mut acquires = vec![]; loop { - chain.push(parse_access_specifier(context, negated, ctor)?); + let start_loc = context.tokens.start_loc(); + let resource = parse_name_access_chain(context, false, || "an access specifier")?; + let end_loc = context.tokens.previous_end_loc(); + let loc = make_loc(context.tokens.file_hash(), start_loc, end_loc); + acquires.push(sp(loc, AccessSpecifier_(resource))); if context.tokens.peek() == Tok::Comma { context.tokens.advance()?; - // Trailing comma allowed, check FIRST() - if matches!( - context.tokens.peek(), - Tok::Identifier | Tok::Star | Tok::NumValue - ) { + // Trailing comma allowed, check FIRST(). + if matches!(context.tokens.peek(), Tok::Identifier | Tok::NumValue) { continue; } else { break; @@ -3002,72 +2940,7 @@ fn parse_access_specifier_list( break; } } - Ok(chain) -} - -// Parse an access specifier: -// AccessSpecifier = -fn parse_access_specifier( - context: &mut Context, - negated: bool, - ctor: &impl Fn(bool, NameAccessChain, Option>, AddressSpecifier) -> AccessSpecifier_, -) -> Result> { - let start = context.tokens.start_loc(); - let name_chain = parse_name_access_chain(context, true, || "an access specifier")?; - let type_args = parse_optional_type_args(context)?; - let address = parse_address_specifier(context)?; - let loc = make_loc( - context.tokens.file_hash(), - start, - address.loc.end() as usize, - ); - Ok(sp(loc, (*ctor)(negated, name_chain, type_args, address))) -} - -// Parse an address specifier: -// AddressSpecifier = | "(" ")" -// AddressSpecifierArg = "*" | | ( ? "(" ")" )? -fn parse_address_specifier(context: &mut Context) -> Result> { - let start = context.tokens.start_loc(); - let (spec, end) = if match_token(context.tokens, Tok::LParen)? { - let spec = match context.tokens.peek() { - Tok::Star => { - context.tokens.advance()?; - AddressSpecifier_::Any - }, - Tok::NumValue => AddressSpecifier_::Literal(parse_address_bytes(context)?.value), - _ => { - let chain = parse_name_access_chain(context, false, || "an address specifier")?; - let type_args = parse_optional_type_args(context)?; - if match_token(context.tokens, Tok::LParen)? { - let name = parse_identifier(context)?; - let call = AddressSpecifier_::Call(chain, type_args, name); - consume_token(context.tokens, Tok::RParen)?; - call - } else { - if type_args.is_some() { - return Err(Box::new(diag!( - Syntax::InvalidAccessSpecifier, - (chain.loc, "type arguments not allowed") - ))); - } - if let NameAccessChain_::One(name) = chain.value { - AddressSpecifier_::Name(name) - } else { - return Err(Box::new(diag!( - Syntax::InvalidAccessSpecifier, - (chain.loc, "expected a simple name") - ))); - } - } - }, - }; - consume_token(context.tokens, Tok::RParen)?; - (spec, context.tokens.previous_end_loc()) - } else { - (AddressSpecifier_::Empty, context.tokens.start_loc()) - }; - Ok(sp(make_loc(context.tokens.file_hash(), start, end), spec)) + Ok(acquires) } //************************************************************************************************** @@ -4503,3 +4376,46 @@ pub fn parse_file_string( Ok(def) => Ok((def, tokens.check_and_get_doc_comments(env))), } } + +#[cfg(test)] +mod tests { + use super::*; + + fn parses(source: &str) -> bool { + let flags = Flags::empty().set_language_version(LanguageVersion::V2_5); + let mut env = CompilationEnv::new(flags, Default::default()); + parse_file_string(&mut env, FileHash::new(source), source).is_ok() + } + + #[test] + fn parses_legacy_acquires_syntax() { + assert!(parses( + "module 0x1::M { + struct R has key {} + struct S has key {} + fun f() acquires R, 0x1::M::S, {} + }", + )); + } + + #[test] + fn does_not_parse_resource_access_control_syntax() { + for access in [ + "reads R", + "writes R", + "pure", + "!reads R", + "acquires R(*)", + "acquires *", + ] { + let source = format!( + "module 0x1::M {{ + struct R has key {{}} + fun f() {} {{}} + }}", + access + ); + assert!(!parses(&source), "unexpectedly parsed `{}`", access); + } + } +} diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/acquires_checker.rs b/third_party/move/move-compiler-v2/src/env_pipeline/acquires_checker.rs index cf727ff1754..c72c20f055a 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/acquires_checker.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/acquires_checker.rs @@ -20,7 +20,7 @@ use crate::Options; use codespan_reporting::diagnostic::Severity; use move_model::{ - ast::{AccessSpecifierKind, ExpData, Operation, ResourceSpecifier, VisitorPosition}, + ast::{ExpData, Operation, VisitorPosition}, metadata::LanguageVersion, model::{FunId, FunctionEnv, GlobalEnv, Loc, ModuleEnv, StructId}, ty::Type, @@ -111,29 +111,19 @@ pub fn acquires_checker(env: &mut GlobalEnv) { /// Gets the acquired resources declared by `acquires R` fn get_acquired_resources(fun_env: &FunctionEnv) -> BTreeMap { - if let Some(access_specifiers) = fun_env.get_access_specifiers() { - access_specifiers - .iter() - .filter_map(|access_specifier| { - if access_specifier.kind != AccessSpecifierKind::LegacyAcquires { - return None; - } - if let ResourceSpecifier::Resource(inst_qid) = &access_specifier.resource.1 { - if inst_qid.module_id != fun_env.module_env.get_id() { - fun_env.module_env.env.error( - &access_specifier.resource.0, - "acquires a resource from another module", - ) - } - Some((inst_qid.id, access_specifier.resource.0.clone())) - } else { - None - } - }) - .collect() - } else { - BTreeMap::new() - } + fun_env + .get_declared_acquires() + .iter() + .map(|(loc, acquired)| { + if acquired.module_id != fun_env.module_env.get_id() { + fun_env + .module_env + .env + .error(loc, "acquires a resource from another module") + } + (acquired.id, loc.clone()) + }) + .collect() } #[derive(Debug)] diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/flow_insensitive_checkers.rs b/third_party/move/move-compiler-v2/src/env_pipeline/flow_insensitive_checkers.rs index 6f0e67d99e5..ae2580bfda3 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/flow_insensitive_checkers.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/flow_insensitive_checkers.rs @@ -127,16 +127,10 @@ impl<'env, 'params> SymbolVisitor<'env, 'params> { params: &'params [Parameter], inline: bool, ) -> SymbolVisitor<'env, 'params> { - let mut seen_uses = ScopedVisibleSet::new(); - for spec in func.get_access_specifiers().unwrap_or_default() { - for var in spec.used_vars() { - seen_uses.insert(var) - } - } SymbolVisitor { env: func.module_env.env, params, - seen_uses, + seen_uses: ScopedVisibleSet::new(), inline, } } diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/inliner.rs b/third_party/move/move-compiler-v2/src/env_pipeline/inliner.rs index 6d735b95d07..a2a0b670429 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/inliner.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/inliner.rs @@ -157,7 +157,7 @@ pub fn run_inlining( } /// Check that inline functions are (1) not native, (2) have a body, (3) are not in a script, -/// (4) do not have certain attributes, and (5) do not have access specifiers. +/// (4) do not have certain attributes, and (5) do not have `acquires` annotations. /// Filter out inline functions from the targets if `Experiment::SKIP_INLINING_INLINE_FUNS` is on. fn check_and_maybe_filter_targets(env: &GlobalEnv, targets: &mut RewriteTargets) { let keep_inline_functions = !env @@ -201,10 +201,10 @@ fn check_and_maybe_filter_targets(env: &GlobalEnv, targets: &mut RewriteTargets) ); } - if func.get_access_specifiers().is_some() { + if !func.get_declared_acquires().is_empty() { env.warning( &func.get_id_loc(), - "acquires and access specifiers are not applicable to inline functions and should be removed", + "acquires annotations are not applicable to inline functions and should be removed", ); } diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/inlining_optimization.rs b/third_party/move/move-compiler-v2/src/env_pipeline/inlining_optimization.rs index 1ea58681a25..c83730d0dcf 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/inlining_optimization.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/inlining_optimization.rs @@ -13,7 +13,7 @@ use crate::{ use codespan_reporting::diagnostic::Severity; use move_binary_format::file_format::Visibility; use move_model::{ - ast::{AccessSpecifierKind, Exp, ExpData, Operation, Pattern, TempIndex}, + ast::{Exp, ExpData, Operation, Pattern, TempIndex}, exp_rewriter::ExpRewriterFunctions, metadata::LanguageVersion, model::{ @@ -250,7 +250,6 @@ fn compute_call_sites_to_inline_and_new_function_size( || has_privileged_operations(caller_mid, &callee_env) || has_invisible_calls(caller_module, &callee_env, across_package) || has_module_lock_attribute(&callee_env) - || has_access_controls(&callee_env) { // won't inline if: // - callee is inline (should have been inlined already) @@ -262,7 +261,6 @@ fn compute_call_sites_to_inline_and_new_function_size( // perform directly // - callee has calls to functions that are not visible from the caller module // - callee has the `#[module_lock]` attribute - // - callee has runtime access control checks // - callee has an abort expression None } else { @@ -552,24 +550,6 @@ fn has_abort(function: &FunctionEnv, caller: &FunctionEnv) -> bool { found } -/// Does `function` have any runtime access control checks? -/// If so, by inlining, such checks would not be performed. -fn has_access_controls(function: &FunctionEnv) -> bool { - if let Some(access_specifiers) = function.get_access_specifiers() { - if access_specifiers.is_empty() { - // empty access specifiers means no access is allowed, the strictest form - // of access control - return true; - } - // any reads or writes specification is considered an access control - access_specifiers - .iter() - .any(|spec| spec.kind != AccessSpecifierKind::LegacyAcquires) - } else { - false - } -} - /// Does `function` have the `#[module_lock]` attribute? fn has_module_lock_attribute(function: &FunctionEnv) -> bool { let env = function.env(); diff --git a/third_party/move/move-compiler-v2/src/file_format_generator/mod.rs b/third_party/move/move-compiler-v2/src/file_format_generator/mod.rs index e8938ea361c..a543e9d9213 100644 --- a/third_party/move/move-compiler-v2/src/file_format_generator/mod.rs +++ b/third_party/move/move-compiler-v2/src/file_format_generator/mod.rs @@ -74,7 +74,6 @@ pub fn generate_file_format( code, type_parameters, parameters, - // TODO(#16278): support rac access_specifiers: None, }; if options.experiment_on(Experiment::ATTACH_COMPILED_MODULE) { diff --git a/third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs b/third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs index 84def3632b4..b7991563700 100644 --- a/third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs +++ b/third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs @@ -19,11 +19,8 @@ use move_core_types::{ }; use move_ir_types::ast as IR_AST; use move_model::{ - ast::{AccessSpecifier, AccessSpecifierKind, AddressSpecifier, Attribute, ResourceSpecifier}, - metadata::{ - lang_feature_versions::LANGUAGE_VERSION_FOR_RAC, CompilationMetadata, CompilerVersion, - LanguageVersion, COMPILATION_METADATA_KEY, - }, + ast::Attribute, + metadata::{CompilationMetadata, CompilerVersion, LanguageVersion, COMPILATION_METADATA_KEY}, model::{ FieldEnv, FunId, FunctionEnv, GlobalEnv, Loc, ModuleEnv, ModuleId, Parameter, QualifiedId, StructEnv, StructId, TypeParameter, TypeParameterKind, @@ -42,8 +39,6 @@ use std::collections::{BTreeMap, BTreeSet}; /// Internal state of the module code generator #[derive(Debug)] pub struct ModuleGenerator { - /// Whether to generate access specifiers - gen_access_specifiers: bool, /// Whether to generate function attributes. pub(crate) gen_function_attributes: bool, /// The module index for which we generate code. @@ -127,7 +122,6 @@ impl ModuleGenerator { let compiler_version = options .compiler_version .unwrap_or(CompilerVersion::latest_stable()); - let gen_access_specifiers = language_version.is_at_least(LANGUAGE_VERSION_FOR_RAC); let gen_function_attributes = language_version.is_at_least(LanguageVersion::V2_2); let compilation_metadata = CompilationMetadata::new(compiler_version, language_version); let metadata = Metadata { @@ -156,7 +150,6 @@ impl ModuleGenerator { SourceMap::new(ctx.env.to_ir_loc(&module_env.get_loc()), module_name_opt) }; let mut r#gen = Self { - gen_access_specifiers, gen_function_attributes, module_idx: FF::ModuleHandleIndex(0), module_to_idx: Default::default(), @@ -525,18 +518,6 @@ impl ModuleGenerator { loc, fun_env.get_result_type().flatten().into_iter().collect(), ); - let access_specifiers = fun_env - .get_access_specifiers() - .as_ref() - .map(|v| { - v.iter() - .filter_map(|s| self.access_specifier(ctx, fun_env, s)) - .collect_vec() - }) - .and_then(|specs| if specs.is_empty() { None } else { Some(specs) }); - if !self.gen_access_specifiers && access_specifiers.is_some() { - ctx.error(loc, "access specifiers not enabled"); - } let attributes = if self.gen_function_attributes { ctx.function_attributes(fun_env) } else { @@ -548,7 +529,7 @@ impl ModuleGenerator { type_parameters, parameters, return_, - access_specifiers, + access_specifiers: None, attributes, }; let idx = if fun_env.module_env.is_script_module() { @@ -568,85 +549,6 @@ impl ModuleGenerator { idx } - pub fn access_specifier( - &mut self, - ctx: &ModuleContext, - fun_env: &FunctionEnv, - access_specifier: &AccessSpecifier, - ) -> Option { - let kind = match access_specifier.kind { - AccessSpecifierKind::Reads => FF::AccessKind::Reads, - AccessSpecifierKind::Writes => FF::AccessKind::Writes, - AccessSpecifierKind::LegacyAcquires => { - // Legacy acquires not represented in file format - return None; - }, - }; - let resource = match &access_specifier.resource.1 { - ResourceSpecifier::Any => FF::ResourceSpecifier::Any, - ResourceSpecifier::DeclaredAtAddress(addr) => FF::ResourceSpecifier::DeclaredAtAddress( - self.address_index(ctx, &access_specifier.resource.0, addr.expect_numerical()), - ), - ResourceSpecifier::DeclaredInModule(module_id) => { - FF::ResourceSpecifier::DeclaredInModule(self.module_index( - ctx, - &access_specifier.resource.0, - &ctx.env.get_module(*module_id), - )) - }, - ResourceSpecifier::Resource(struct_id) => { - let struct_env = ctx.env.get_struct(struct_id.to_qualified_id()); - if struct_id.inst.is_empty() { - FF::ResourceSpecifier::Resource(self.struct_index( - ctx, - &access_specifier.loc, - &struct_env, - )) - } else { - FF::ResourceSpecifier::ResourceInstantiation( - self.struct_index(ctx, &access_specifier.loc, &struct_env), - self.signature(ctx, &access_specifier.loc, struct_id.inst.to_vec()), - ) - } - }, - }; - let address = - match &access_specifier.address.1 { - AddressSpecifier::Any => FF::AddressSpecifier::Any, - AddressSpecifier::Address(addr) => FF::AddressSpecifier::Literal( - self.address_index(ctx, &access_specifier.address.0, addr.expect_numerical()), - ), - AddressSpecifier::Parameter(name) => { - let param_index = fun_env - .get_parameters() - .iter() - .position(|Parameter(n, _ty, _)| n == name) - .expect("parameter defined") as u8; - FF::AddressSpecifier::Parameter(param_index, None) - }, - AddressSpecifier::Call(fun, name) => { - let param_index = fun_env - .get_parameters() - .iter() - .position(|Parameter(n, _ty, _)| n == name) - .expect("parameter defined") as u8; - let fun_index = self.function_instantiation_index( - ctx, - &access_specifier.address.0, - &ctx.env.get_function(fun.to_qualified_id()), - fun.inst.clone(), - ); - FF::AddressSpecifier::Parameter(param_index, Some(fun_index)) - }, - }; - Some(FF::AccessSpecifier { - kind, - negated: access_specifier.negated, - resource, - address, - }) - } - pub fn function_instantiation_index( &mut self, ctx: &ModuleContext, diff --git a/third_party/move/move-compiler-v2/src/pipeline/reference_safety/reference_safety_processor_v2.rs b/third_party/move/move-compiler-v2/src/pipeline/reference_safety/reference_safety_processor_v2.rs index 9145e4a03b5..cde9ef96c56 100644 --- a/third_party/move/move-compiler-v2/src/pipeline/reference_safety/reference_safety_processor_v2.rs +++ b/third_party/move/move-compiler-v2/src/pipeline/reference_safety/reference_safety_processor_v2.rs @@ -123,7 +123,7 @@ use itertools::Itertools; use log::{debug, log_enabled, Level}; use move_binary_format::file_format::CodeOffset; use move_model::{ - ast::{AccessSpecifierKind, TempIndex}, + ast::TempIndex, model::{FieldId, FunId, FunctionEnv, GlobalEnv, Loc, Parameter, QualifiedInstId, StructId}, symbol::Symbol, ty::{ReferenceKind, Type}, @@ -1699,40 +1699,40 @@ impl LifetimeAnalysisStep<'_, '_> { /// currently borrowed. fn check_global_access(&mut self, fun_id: QualifiedInstId) { let fun = self.global_env().get_function(fun_id.to_qualified_id()); - let specifiers = fun.get_access_specifiers().unwrap_or(&[]); + let empty_acquires = BTreeSet::new(); + let acquires = fun.get_acquired_structs().unwrap_or(&empty_acquires); for (global, label) in &self.state.global_to_label_map { let is_mut = self.state.children(label).any(|e| e.kind.is_mut()); - // We are only checking positive specifiers, as negatives say nothing - // about what is accessed. - for spec in specifiers.iter().filter(|s| !s.negated) { - if spec - .resource - .1 - .matches(self.global_env(), &fun_id.inst, global) - // For mut global borrows, no access is allowed at all. For - // non-mut, write access is not allowed. - // TODO: needs to be updated to use acquired resources instead - // access specifiers (see v3 code). - && (is_mut || spec.kind.subsumes(&AccessSpecifierKind::Writes)) - { - self.error_with_hints( - self.cur_loc(), - format!( - "function {} global `{}` which is currently {}borrowed", - spec.kind, - self.global_env().display(global), - if is_mut { "mutably " } else { "" } - ), - "function called here", - self.borrow_info(label, |_| true) - .into_iter() - .chain(iter::once(( - spec.loc.clone(), - "access declared here".to_owned(), - ))), - ) - } + if global.module_id == fun.module_env.get_id() && acquires.contains(&global.id) { + let access_origin_hint = fun + .get_declared_acquires() + .iter() + .find_map(|(loc, acquired)| { + if *acquired == global.to_qualified_id() { + Some((loc.clone(), "`acquires` declared here".to_owned())) + } else { + None + } + }) + .unwrap_or_else(|| { + ( + fun.get_id_loc(), + "`acquires` of this function was inferred".to_owned(), + ) + }); + self.error_with_hints( + self.cur_loc(), + format!( + "function acquires global `{}` which is currently {}borrowed", + self.global_env().display(global), + if is_mut { "mutably " } else { "" } + ), + "function called here", + self.borrow_info(label, |_| true) + .into_iter() + .chain(iter::once(access_origin_hint)), + ) } } } diff --git a/third_party/move/move-compiler-v2/src/pipeline/reference_safety/reference_safety_processor_v3.rs b/third_party/move/move-compiler-v2/src/pipeline/reference_safety/reference_safety_processor_v3.rs index 4cca02e891a..5ddf38b1790 100644 --- a/third_party/move/move-compiler-v2/src/pipeline/reference_safety/reference_safety_processor_v3.rs +++ b/third_party/move/move-compiler-v2/src/pipeline/reference_safety/reference_safety_processor_v3.rs @@ -28,7 +28,7 @@ use itertools::Itertools; use move_binary_format::file_format::CodeOffset; use move_borrow_graph::{graph::BorrowGraph, references::RefID}; use move_model::{ - ast::{AccessSpecifierKind, ResourceSpecifier, TempIndex}, + ast::TempIndex, model::{FunId, FunctionEnv, GlobalEnv, Loc, QualifiedId, QualifiedInstId, StructId}, ty::{ReferenceKind, Type}, }; @@ -708,18 +708,13 @@ impl LifetimeAnalysisStep<'_, '_> { for (_code_id, struct_id, target) in self.state.global_borrow_edges() { let is_mut = self.state.borrow_graph.is_mutable(target); if struct_id.module_id == fun.module_env.get_id() && acquires.contains(&struct_id.id) { - // Try to find the location of the access declaration via the access specifier - // list. + // Try to find the location of the explicit `acquires` declaration. let access_origin_hint = fun - .get_access_specifiers() - .unwrap_or_default() + .get_declared_acquires() .iter() - .find_map(|s| { - if s.kind == AccessSpecifierKind::LegacyAcquires - && matches!(&s.resource.1, - ResourceSpecifier::Resource(s) if s.to_qualified_id() == struct_id) - { - Some(vec![(s.loc.clone(), "`acquires` declared here".to_owned())]) + .find_map(|(loc, acquired)| { + if *acquired == struct_id { + Some(vec![(loc.clone(), "`acquires` declared here".to_owned())]) } else { None } diff --git a/third_party/move/move-compiler-v2/tests/acquires-checker/copy_ability_tuple.exp b/third_party/move/move-compiler-v2/tests/acquires-checker/copy_ability_tuple.exp index cee7c724d5a..c77741a1aa8 100644 --- a/third_party/move/move-compiler-v2/tests/acquires-checker/copy_ability_tuple.exp +++ b/third_party/move/move-compiler-v2/tests/acquires-checker/copy_ability_tuple.exp @@ -4,4 +4,4 @@ error: unnecessary acquires annotation ┌─ tests/acquires-checker/copy_ability_tuple.move:8:39 │ 8 │ public fun g(s: &signer) acquires R { - │ ^^ + │ ^ diff --git a/third_party/move/move-compiler-v2/tests/acquires-checker/v1-borrow-tests/borrow_global_acquires_extraneous_annotation.exp b/third_party/move/move-compiler-v2/tests/acquires-checker/v1-borrow-tests/borrow_global_acquires_extraneous_annotation.exp index dbb441a1020..f7f030245ee 100644 --- a/third_party/move/move-compiler-v2/tests/acquires-checker/v1-borrow-tests/borrow_global_acquires_extraneous_annotation.exp +++ b/third_party/move/move-compiler-v2/tests/acquires-checker/v1-borrow-tests/borrow_global_acquires_extraneous_annotation.exp @@ -4,4 +4,4 @@ error: unnecessary acquires annotation ┌─ tests/acquires-checker/v1-borrow-tests/borrow_global_acquires_extraneous_annotation.move:4:32 │ 4 │ public fun test() acquires T1 { - │ ^^^ + │ ^^ diff --git a/third_party/move/move-compiler-v2/tests/acquires-checker/v1-borrow-tests/borrow_global_acquires_invalid_annotation.exp b/third_party/move/move-compiler-v2/tests/acquires-checker/v1-borrow-tests/borrow_global_acquires_invalid_annotation.exp index b99f6c653f9..291479edeca 100644 --- a/third_party/move/move-compiler-v2/tests/acquires-checker/v1-borrow-tests/borrow_global_acquires_invalid_annotation.exp +++ b/third_party/move/move-compiler-v2/tests/acquires-checker/v1-borrow-tests/borrow_global_acquires_invalid_annotation.exp @@ -4,4 +4,4 @@ error: unnecessary acquires annotation ┌─ tests/acquires-checker/v1-borrow-tests/borrow_global_acquires_invalid_annotation.move:4:32 │ 4 │ public fun test() acquires T1 { - │ ^^^ + │ ^^ diff --git a/third_party/move/move-compiler-v2/tests/acquires-checker/v1-tests/extraneous_acquire.exp b/third_party/move/move-compiler-v2/tests/acquires-checker/v1-tests/extraneous_acquire.exp index b636c11fed4..c1bb67e2490 100644 --- a/third_party/move/move-compiler-v2/tests/acquires-checker/v1-tests/extraneous_acquire.exp +++ b/third_party/move/move-compiler-v2/tests/acquires-checker/v1-tests/extraneous_acquire.exp @@ -4,10 +4,10 @@ error: unnecessary acquires annotation ┌─ tests/acquires-checker/v1-tests/extraneous_acquire.move:5:23 │ 5 │ fun t0() acquires R1 { - │ ^^^ + │ ^^ error: unnecessary acquires annotation ┌─ tests/acquires-checker/v1-tests/extraneous_acquire.move:9:37 │ 9 │ fun t1(a: address) acquires R1, R2 { - │ ^^^ + │ ^^ diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/borrow_deref_optimize.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/borrow_deref_optimize.exp index 7def2646ea7..1ac2479d780 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/borrow_deref_optimize.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/borrow_deref_optimize.exp @@ -4,7 +4,7 @@ module 0x42::test { value: bool, } private fun no_optimize_resource(): bool - acquires X(*) + acquires X { { let x: &mut X = Borrow(Mutable)(Deref(BorrowGlobal(Immutable)(0x1))); @@ -21,7 +21,7 @@ module 0x42::test { } } private fun optimize_resource(): bool - acquires X(*) + acquires X { { let x: &X = Borrow(Immutable)(Deref(BorrowGlobal(Immutable)(0x1))); @@ -161,7 +161,7 @@ module 0x42::test { value: bool, } private fun no_optimize_resource(): bool - acquires X(*) + acquires X { { let x: &mut X = Borrow(Mutable)(Deref(BorrowGlobal(Immutable)(0x1))); @@ -175,7 +175,7 @@ module 0x42::test { } } private fun optimize_resource(): bool - acquires X(*) + acquires X { { let x: &X = Borrow(Immutable)(Deref(BorrowGlobal(Immutable)(0x1))); diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_14471_receiver_inference.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_14471_receiver_inference.exp index 31b21752ab8..5a4dc4f8148 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_14471_receiver_inference.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_14471_receiver_inference.exp @@ -17,7 +17,7 @@ module 0x815::m { Tuple() } public fun add_when_missing(key: address,val: u64) - acquires MyMap(*) + acquires MyMap { { let my_map: &mut MyMap = BorrowGlobal(Mutable)(0x815); @@ -124,7 +124,7 @@ module 0x815::m { Tuple() } public fun add_when_missing(key: address,val: u64) - acquires MyMap(*) + acquires MyMap { { let my_map: &mut MyMap = BorrowGlobal(Mutable)(0x815); diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/escape_autoref.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/escape_autoref.exp index dbbed914235..9b155139f12 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/escape_autoref.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/escape_autoref.exp @@ -10,7 +10,7 @@ module 0x42::m { Abort(0) } private fun owner_correct(o: Object): address - acquires ObjectCore(*) + acquires ObjectCore { { let addr: address = select m::Object.inner(o); @@ -18,7 +18,7 @@ module 0x42::m { } } private fun owner_read_ref_missing(o: Object): address - acquires ObjectCore(*) + acquires ObjectCore { select m::ObjectCore.owner<&ObjectCore>(BorrowGlobal(Immutable)(select m::Object.inner(o))) } @@ -127,7 +127,7 @@ module 0x42::m { Abort(0) } private fun owner_correct(o: Object): address - acquires ObjectCore(*) + acquires ObjectCore { { let addr: address = select m::Object.inner(o); @@ -135,7 +135,7 @@ module 0x42::m { } } private fun owner_read_ref_missing(o: Object): address - acquires ObjectCore(*) + acquires ObjectCore { select m::ObjectCore.owner<&ObjectCore>(BorrowGlobal(Immutable)(select m::Object.inner(o))) } diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/globals.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/globals.exp index efc903b960d..cf9efdcfc97 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/globals.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/globals.exp @@ -11,7 +11,7 @@ module 0x42::globals { Tuple() } private fun read(a: address): u64 - acquires R(*) + acquires R { { let r: &R = BorrowGlobal(Immutable)(a); @@ -19,7 +19,7 @@ module 0x42::globals { } } private fun write(a: address,x: u64): u64 - acquires R(*) + acquires R { { let r: &mut R = BorrowGlobal(Mutable)(a); @@ -125,7 +125,7 @@ module 0x42::globals { Tuple() } private fun read(a: address): u64 - acquires R(*) + acquires R { { let r: &R = BorrowGlobal(Immutable)(a); @@ -133,7 +133,7 @@ module 0x42::globals { } } private fun write(a: address,x: u64): u64 - acquires R(*) + acquires R { { let r: &mut R = BorrowGlobal(Mutable)(a); diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v1/access_ok.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v1/access_ok.exp deleted file mode 100644 index c8a86116c11..00000000000 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v1/access_ok.exp +++ /dev/null @@ -1,49 +0,0 @@ - -Diagnostics: -error: unsupported language construct - ┌─ tests/checking-lang-v1/access_ok.move:11:14 - │ -11 │ fun f2() reads S { - │ ^^^^^ Move 2 language construct is not enabled: access specifiers - -error: unsupported language construct - ┌─ tests/checking-lang-v1/access_ok.move:14:14 - │ -14 │ fun f3() writes S { - │ ^^^^^^ Move 2 language construct is not enabled: access specifiers - -error: unsupported language construct - ┌─ tests/checking-lang-v1/access_ok.move:20:33 - │ -20 │ fun f_multiple() acquires R reads R writes T, S reads G { - │ ^^^^^ Move 2 language construct is not enabled: access specifiers - -error: unsupported language construct - ┌─ tests/checking-lang-v1/access_ok.move:20:41 - │ -20 │ fun f_multiple() acquires R reads R writes T, S reads G { - │ ^^^^^^ Move 2 language construct is not enabled: access specifiers - -error: unsupported language construct - ┌─ tests/checking-lang-v1/access_ok.move:20:53 - │ -20 │ fun f_multiple() acquires R reads R writes T, S reads G { - │ ^^^^^ Move 2 language construct is not enabled: access specifiers - -error: unsupported language construct - ┌─ tests/checking-lang-v1/access_ok.move:45:15 - │ -45 │ fun f11() !reads *(0x42), *(0x43) { - │ ^ Move 2 language construct is not enabled: access specifiers - -error: unsupported language construct - ┌─ tests/checking-lang-v1/access_ok.move:45:16 - │ -45 │ fun f11() !reads *(0x42), *(0x43) { - │ ^^^^^ Move 2 language construct is not enabled: access specifiers - -error: unsupported language construct - ┌─ tests/checking-lang-v1/access_ok.move:48:15 - │ -48 │ fun f12() pure { - │ ^^^^ Move 2 language construct is not enabled: access specifiers diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v1/access_ok.move b/third_party/move/move-compiler-v2/tests/checking-lang-v1/access_ok.move deleted file mode 100644 index e6267ce5278..00000000000 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v1/access_ok.move +++ /dev/null @@ -1,50 +0,0 @@ -module 0x42::m { - - struct S has store {} - struct R has store {} - struct T has store {} - struct G has store {} - - fun f1() acquires S { - } - - fun f2() reads S { - } - - fun f3() writes S { - } - - fun f4() acquires S(*) { - } - - fun f_multiple() acquires R reads R writes T, S reads G { - } - - fun f5() acquires 0x42::*::* { - } - - fun f6() acquires 0x42::m::* { - } - - fun f7() acquires *(*) { - } - - fun f8() acquires *(0x42) { - } - - fun f9(a: address) acquires *(a) { - } - - fun f10(x: u64) acquires *(make_up_address(x)) { - } - - fun make_up_address(x: u64): address { - @0x42 - } - - fun f11() !reads *(0x42), *(0x43) { - } - - fun f12() pure { - } -} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v1/acquires_list_generic.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v1/acquires_list_generic.exp index 3afa9395082..e4038545a3f 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v1/acquires_list_generic.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v1/acquires_list_generic.exp @@ -1,7 +1,10 @@ Diagnostics: -error: only simple resource names can be used with `acquires` - ┌─ tests/checking-lang-v1/acquires_list_generic.move:6:24 +error: unexpected token + ┌─ tests/checking-lang-v1/acquires_list_generic.move:6:25 │ 6 │ fun foo() acquires B> { - │ ^^^^^^^^^^^ + │ ^ + │ │ + │ Unexpected '<' + │ Expected '{' diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v1/expansion/access_specifier_not_supported.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v1/expansion/access_specifier_not_supported.exp deleted file mode 100644 index 666c992ab14..00000000000 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v1/expansion/access_specifier_not_supported.exp +++ /dev/null @@ -1,13 +0,0 @@ - -Diagnostics: -error: unsupported language construct - ┌─ tests/checking-lang-v1/expansion/access_specifier_not_supported.move:8:14 - │ -8 │ fun f2() reads S { - │ ^^^^^ Move 2 language construct is not enabled: access specifiers - -error: unsupported language construct - ┌─ tests/checking-lang-v1/expansion/access_specifier_not_supported.move:11:14 - │ -11 │ fun f3() writes S { - │ ^^^^^^ Move 2 language construct is not enabled: access specifiers diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v1/expansion/access_specifier_not_supported.move b/third_party/move/move-compiler-v2/tests/checking-lang-v1/expansion/access_specifier_not_supported.move deleted file mode 100644 index 0b76ed198e0..00000000000 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v1/expansion/access_specifier_not_supported.move +++ /dev/null @@ -1,31 +0,0 @@ -module 0x42::m { - - struct S has key {} - struct R has key {} - struct T has key {} - struct G has key {} - - fun f2() reads S { - } - - fun f3() writes S { - } - - fun f4() acquires S(*) { - } - - fun f5() acquires 0x42::*::* { - } - - fun f6() acquires 0x42::m::R { - } - - fun f7() acquires *(*) { - } - - fun f8() acquires *(0x42) { - } - - fun f9(_a: address) acquires *(_a) { - } -} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v1/v1-typing/invalid_type_acquire.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v1/v1-typing/invalid_type_acquire.exp index bf5a2c1e779..25f417c7233 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v1/v1-typing/invalid_type_acquire.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v1/v1-typing/invalid_type_acquire.exp @@ -1,24 +1,12 @@ Diagnostics: -error: invalid access specifier +error: undeclared `0x2::M::T` ┌─ tests/checking-lang-v1/v1-typing/invalid_type_acquire.move:18:9 │ 18 │ T, │ ^ -error: not supported before language version `2.0`: address and wildcard access specifiers. Only resource type names can be provided. - ┌─ tests/checking-lang-v1/v1-typing/invalid_type_acquire.move:18:9 - │ -18 │ T, - │ ^ - -error: invalid access specifier - ┌─ tests/checking-lang-v1/v1-typing/invalid_type_acquire.move:19:9 - │ -19 │ u64, - │ ^^^ - -error: not supported before language version `2.0`: address and wildcard access specifiers. Only resource type names can be provided. +error: undeclared `0x2::M::u64` ┌─ tests/checking-lang-v1/v1-typing/invalid_type_acquire.move:19:9 │ 19 │ u64, diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/access_specifiers/access_not_supported.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/access_specifiers/access_not_supported.exp deleted file mode 100644 index 8455d48151c..00000000000 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/access_specifiers/access_not_supported.exp +++ /dev/null @@ -1,79 +0,0 @@ - -Diagnostics: -error: not supported before language version `2.5-unstable`: read/write access specifiers. - ┌─ tests/checking-lang-v2.2/access_specifiers/access_not_supported.move:11:20 - │ -11 │ fun f2() reads S { - │ ^^ - -error: not supported before language version `2.5-unstable`: read/write access specifiers. - ┌─ tests/checking-lang-v2.2/access_specifiers/access_not_supported.move:14:21 - │ -14 │ fun f3() writes S { - │ ^^ - -error: only simple resource names can be used with `acquires` - ┌─ tests/checking-lang-v2.2/access_specifiers/access_not_supported.move:17:23 - │ -17 │ fun f4() acquires S(*) { - │ ^^^^ - -error: not supported before language version `2.5-unstable`: read/write access specifiers. - ┌─ tests/checking-lang-v2.2/access_specifiers/access_not_supported.move:20:39 - │ -20 │ fun f_multiple() acquires R reads R writes T, S reads G { - │ ^^ - -error: not supported before language version `2.5-unstable`: read/write access specifiers. - ┌─ tests/checking-lang-v2.2/access_specifiers/access_not_supported.move:20:48 - │ -20 │ fun f_multiple() acquires R reads R writes T, S reads G { - │ ^ - -error: not supported before language version `2.5-unstable`: read/write access specifiers. - ┌─ tests/checking-lang-v2.2/access_specifiers/access_not_supported.move:20:51 - │ -20 │ fun f_multiple() acquires R reads R writes T, S reads G { - │ ^^ - -error: not supported before language version `2.5-unstable`: read/write access specifiers. - ┌─ tests/checking-lang-v2.2/access_specifiers/access_not_supported.move:20:59 - │ -20 │ fun f_multiple() acquires R reads R writes T, S reads G { - │ ^^^^^^^ - -error: only simple resource names can be used with `acquires` - ┌─ tests/checking-lang-v2.2/access_specifiers/access_not_supported.move:29:23 - │ -29 │ fun f7() acquires *(*) { - │ ^^^^ - -error: only simple resource names can be used with `acquires` - ┌─ tests/checking-lang-v2.2/access_specifiers/access_not_supported.move:32:23 - │ -32 │ fun f8() acquires *(0x42) { - │ ^^^^^^^ - -error: only simple resource names can be used with `acquires` - ┌─ tests/checking-lang-v2.2/access_specifiers/access_not_supported.move:35:33 - │ -35 │ fun f9(a: address) acquires *(a) { - │ ^^^^ - -error: only simple resource names can be used with `acquires` - ┌─ tests/checking-lang-v2.2/access_specifiers/access_not_supported.move:38:30 - │ -38 │ fun f10(x: u64) acquires *(make_up_address(x)) { - │ ^^^^^^^^^^^^^^^^^^^^^ - -error: not supported before language version `2.5-unstable`: read/write access specifiers. - ┌─ tests/checking-lang-v2.2/access_specifiers/access_not_supported.move:45:22 - │ -45 │ fun f11() !reads *(0x42), *(0x43) { - │ ^^^^^^^ - -error: not supported before language version `2.5-unstable`: read/write access specifiers. - ┌─ tests/checking-lang-v2.2/access_specifiers/access_not_supported.move:45:31 - │ -45 │ fun f11() !reads *(0x42), *(0x43) { - │ ^^^^^^^ diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/access_specifiers/access_not_supported.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/access_specifiers/access_not_supported.move deleted file mode 100644 index 23d6cbb305f..00000000000 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/access_specifiers/access_not_supported.move +++ /dev/null @@ -1,50 +0,0 @@ -module 0x42::m { - - struct S has store {} - struct R has store {} - struct T has store {} - struct G has store {} - - fun f1() acquires S { - } - - fun f2() reads S { - } - - fun f3() writes S { - } - - fun f4() acquires S(*) { - } - - fun f_multiple() acquires R reads R writes T, S reads G { - } - - fun f5() acquires 0x42::*::* { - } - - fun f6() acquires 0x42::m::* { - } - - fun f7() acquires *(*) { - } - - fun f8() acquires *(0x42) { - } - - fun f9(a: address) acquires *(a) { - } - - fun f10(x: u64) acquires *(make_up_address(x)) { - } - - fun make_up_address(x: u64): address { - @0x42 - } - - fun f11() !reads *(0x42), *(0x43) { - } - - fun f12() pure { - } -} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/acquires/acquires_error.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/acquires/acquires_error.exp index 72d92fa930a..52850b482eb 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/acquires/acquires_error.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/acquires/acquires_error.exp @@ -14,4 +14,4 @@ error: unnecessary acquires annotation ┌─ tests/checking-lang-v2.2/acquires/acquires_error.move:14:40 │ 14 │ fun read(a: address): u64 acquires S { - │ ^^ + │ ^ diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/acquires/acquires_inferred.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/acquires/acquires_inferred.exp index 91bf3296a16..6342f4fcff7 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/acquires/acquires_inferred.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/acquires/acquires_inferred.exp @@ -36,11 +36,15 @@ module 0x42::acquires_inferred { fun publish(s: &signer) { move_to(R{f: 1}, s); } - fun read(a: address): u64 { + fun read(a: address): u64 + acquires R + { let r = borrow_global(a); r.f } - fun write(a: address, x: u64): u64 { + fun write(a: address, x: u64): u64 + acquires R + { let r = borrow_global_mut(a); r.f = x; 9 diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/storable/generic_func.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/storable/generic_func.exp index a36a8411f9a..29da029062e 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/storable/generic_func.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/storable/generic_func.exp @@ -4,7 +4,7 @@ module 0x42::mod2 { func: F, } public fun get_item(addr: address): F - acquires Registry(*) + acquires Registry { select mod2::Registry.func<&Registry>(BorrowGlobal(Immutable)>(addr)) } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_err.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_err.exp deleted file mode 100644 index cd49f667dd2..00000000000 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_err.exp +++ /dev/null @@ -1,43 +0,0 @@ - -Diagnostics: -error: invalid access specifier - ┌─ tests/checking-lang-v2.5/access_specifiers/access_err.move:6:20 - │ -6 │ fun f1() reads undef { - │ ^^^^^^ - -error: undeclared module `undef` - ┌─ tests/checking-lang-v2.5/access_specifiers/access_err.move:9:20 - │ -9 │ fun f2() reads 0x42::undef::* { - │ ^^^^^^^^^^^^^^^ - -error: invalid access specifier: a wildcard cannot be followed by a non-wildcard name component - ┌─ tests/checking-lang-v2.5/access_specifiers/access_err.move:12:20 - │ -12 │ fun f3() reads 0x42::*::S { - │ ^^^^^^^^^^^ - -error: undeclared `y` - ┌─ tests/checking-lang-v2.5/access_specifiers/access_err.move:18:32 - │ -18 │ fun f5(x: address) reads *(y) { - │ ^ - -error: undeclared `y` - ┌─ tests/checking-lang-v2.5/access_specifiers/access_err.move:21:48 - │ -21 │ fun f6(x: address) reads *(make_up_address(y)) { - │ ^ - -error: cannot pass `u64` to a function which expects argument of type `address` - ┌─ tests/checking-lang-v2.5/access_specifiers/access_err.move:24:27 - │ -24 │ fun f7(x: u64) reads *(make_up_address_wrong(x)) { - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: no function named `undefined` found - ┌─ tests/checking-lang-v2.5/access_specifiers/access_err.move:27:27 - │ -27 │ fun f8(x: u64) reads *(undefined(x)) { - │ ^^^^^^^^^^^^^^ diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_err.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_err.move deleted file mode 100644 index bff00f18533..00000000000 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_err.move +++ /dev/null @@ -1,37 +0,0 @@ -module 0x42::m { - - struct S has store {} - struct G has store {} - - fun f1() reads undef { - } - - fun f2() reads 0x42::undef::* { - } - - fun f3() reads 0x42::*::S { - } - - fun f4() reads G { - } - - fun f5(x: address) reads *(y) { - } - - fun f6(x: address) reads *(make_up_address(y)) { - } - - fun f7(x: u64) reads *(make_up_address_wrong(x)) { - } - - fun f8(x: u64) reads *(undefined(x)) { - } - - fun make_up_address(foo: u64): address { - @0x42 - } - - fun make_up_address_wrong(foo: u64): u64 { - 0x42 - } -} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_ok.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_ok.exp deleted file mode 100644 index f4d87f0228d..00000000000 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_ok.exp +++ /dev/null @@ -1,144 +0,0 @@ -// -- Model dump before first bytecode pipeline -module 0x42::m { - struct T { - dummy_field: bool, - } - struct G { - dummy_field: bool, - } - struct R { - dummy_field: bool, - } - struct S { - dummy_field: bool, - } - private fun f10(x: u64) - reads *(m::make_up_address(x)) - { - Tuple() - } - private fun f11() - !reads *(0x42) - !reads *(0x43) - { - Tuple() - } - private fun f12() - { - Tuple() - } - private fun f2() - reads S(*) - { - Tuple() - } - private fun f3() - writes S(*) - { - Tuple() - } - private fun f4() - reads S(*) - { - Tuple() - } - private fun f5() - reads 0x42::*(*) - { - Tuple() - } - private fun f6() - reads 0x42::m::*(*) - { - Tuple() - } - private fun f7() - reads *(*) - { - Tuple() - } - private fun f8() - reads *(0x42) - { - Tuple() - } - private fun f9(a: address) - reads *(a) - { - Tuple() - } - private fun f_multiple() - reads R(*) - writes T(*) - writes S(*) - reads G(*) - { - Tuple() - } - private fun make_up_address(_x: u64): address { - 0x42 - } -} // end 0x42::m - -// -- Sourcified model before first bytecode pipeline -module 0x42::m { - struct T has store { - } - struct G has store { - } - struct R has store { - } - struct S has store { - } - fun f10(x: u64) - reads *(make_up_address(x)) - { - } - fun f11() - !reads *(0x42), *(0x43) - { - } - fun f12() - { - } - fun f2() - reads S - { - } - fun f3() - writes S - { - } - fun f4() - reads S - { - } - fun f5() - reads 0x42::*::* - { - } - fun f6() - reads 0x42::m::* - { - } - fun f7() - reads * - { - } - fun f8() - reads *(0x42) - { - } - fun f9(a: address) - reads *(a) - { - } - fun f_multiple() - reads G, R - writes S, T - { - } - fun make_up_address(_x: u64): address { - @0x42 - } -} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_ok.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_ok.move deleted file mode 100644 index e822dc0cee4..00000000000 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_ok.move +++ /dev/null @@ -1,47 +0,0 @@ -module 0x42::m { - - struct S has store {} - struct R has store {} - struct T has store {} - struct G has store {} - - fun f2() reads S { - } - - fun f3() writes S { - } - - fun f4() reads S(*) { - } - - fun f_multiple() reads R writes T, S reads G { - } - - fun f5() reads 0x42::*::* { - } - - fun f6() reads 0x42::m::* { - } - - fun f7() reads *(*) { - } - - fun f8() reads *(0x42) { - } - - fun f9(a: address) reads *(a) { - } - - fun f10(x: u64) reads *(make_up_address(x)) { - } - - fun make_up_address(_x: u64): address { - @0x42 - } - - fun f11() !reads *(0x42), *(0x43) { - } - - fun f12() pure { - } -} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/acquires_list_generic.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/acquires_list_generic.exp deleted file mode 100644 index 6bb1b49ca46..00000000000 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/acquires_list_generic.exp +++ /dev/null @@ -1,32 +0,0 @@ -// -- Model dump before first bytecode pipeline -module 0x42::M { - struct B { - dummy_field: bool, - } - struct CupC { - dummy_field: bool, - } - struct R { - dummy_field: bool, - } - private fun foo() - reads B>(*) - { - Abort(0) - } -} // end 0x42::M - -// -- Sourcified model before first bytecode pipeline -module 0x42::M { - struct B { - } - struct CupC { - } - struct R { - } - fun foo() - reads B> - { - abort 0 - } -} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/acquires_list_generic.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/acquires_list_generic.move deleted file mode 100644 index eac55c16764..00000000000 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/acquires_list_generic.move +++ /dev/null @@ -1,9 +0,0 @@ -module 0x42::M { - struct CupC {} - struct R {} - struct B {} - - fun foo() reads B> { - abort 0 - } -} diff --git a/third_party/move/move-compiler-v2/tests/checking/abilities/v1/phantom_param_op_abilities.exp b/third_party/move/move-compiler-v2/tests/checking/abilities/v1/phantom_param_op_abilities.exp index ccbb4b13d8c..6f167bbd6f8 100644 --- a/third_party/move/move-compiler-v2/tests/checking/abilities/v1/phantom_param_op_abilities.exp +++ b/third_party/move/move-compiler-v2/tests/checking/abilities/v1/phantom_param_op_abilities.exp @@ -37,7 +37,7 @@ module 0x42::M { Tuple() } private fun f6(): HasKey - acquires HasKey(*) + acquires HasKey { MoveFrom>(0x0) } diff --git a/third_party/move/move-compiler-v2/tests/checking/indexing/examples_book.exp b/third_party/move/move-compiler-v2/tests/checking/indexing/examples_book.exp index e6a3c38f74b..92dec071764 100644 --- a/third_party/move/move-compiler-v2/tests/checking/indexing/examples_book.exp +++ b/third_party/move/move-compiler-v2/tests/checking/indexing/examples_book.exp @@ -4,7 +4,7 @@ module 0x1::m { value: bool, } private fun f1() - acquires R(*) + acquires R { { let x: &mut R = BorrowGlobal(Mutable)(0x1); diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/inline_disallowed_acquires.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/inline_disallowed_acquires.exp index 27fa2364743..346e6e1948a 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/inline_disallowed_acquires.exp +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/inline_disallowed_acquires.exp @@ -1,6 +1,6 @@ Diagnostics: -warning: acquires and access specifiers are not applicable to inline functions and should be removed +warning: acquires annotations are not applicable to inline functions and should be removed ┌─ tests/checking/inlining/inline_disallowed_acquires.move:6:16 │ 6 │ inline fun test() acquires R {} @@ -12,7 +12,7 @@ module 0xc0ffee::m { x: u64, } private inline fun test() - acquires R(*) + acquires R { Tuple() } @@ -35,7 +35,7 @@ module 0xc0ffee::m { x: u64, } private inline fun test() - acquires R(*) + acquires R { Tuple() } diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/resources_valid.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/resources_valid.exp index a22a89546d0..7ab24b131b2 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/resources_valid.exp +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/resources_valid.exp @@ -16,7 +16,7 @@ module 0x42::token { val: u64, } public fun get_value(ref: &obj::ReaderRef): u64 - acquires Token(*) + acquires Token { select token::Token.val<&Token>({ let (ref: &obj::ReaderRef): (&obj::ReaderRef) = Tuple(ref); @@ -70,7 +70,7 @@ module 0x42::token { val: u64, } public fun get_value(ref: &obj::ReaderRef): u64 - acquires Token(*) + acquires Token { select token::Token.val<&Token>({ let (ref: &obj::ReaderRef): (&obj::ReaderRef) = Tuple(ref); diff --git a/third_party/move/move-compiler-v2/tests/checking/naming/duplicate_acquires_list_item.exp b/third_party/move/move-compiler-v2/tests/checking/naming/duplicate_acquires_list_item.exp index 83e735f8f41..c2f4ccf5e16 100644 --- a/third_party/move/move-compiler-v2/tests/checking/naming/duplicate_acquires_list_item.exp +++ b/third_party/move/move-compiler-v2/tests/checking/naming/duplicate_acquires_list_item.exp @@ -7,20 +7,20 @@ module 0x8675309::M { dummy_field: bool, } private fun t0() - acquires R(*) - acquires X(*) - acquires R(*) + acquires R + acquires X + acquires R { BorrowGlobal(Mutable)(0x1); BorrowGlobal(Mutable)(0x1); Tuple() } private fun t1() - acquires R(*) - acquires X(*) - acquires R(*) - acquires R(*) - acquires R(*) + acquires R + acquires X + acquires R + acquires R + acquires R { BorrowGlobal(Mutable)(0x1); BorrowGlobal(Mutable)(0x1); diff --git a/third_party/move/move-compiler-v2/tests/checking/naming/global_builtin_one_type_argument.exp b/third_party/move/move-compiler-v2/tests/checking/naming/global_builtin_one_type_argument.exp index dd0a3056ef5..9b77f4e1e4a 100644 --- a/third_party/move/move-compiler-v2/tests/checking/naming/global_builtin_one_type_argument.exp +++ b/third_party/move/move-compiler-v2/tests/checking/naming/global_builtin_one_type_argument.exp @@ -4,7 +4,7 @@ module 0x8675309::M { dummy_field: bool, } private fun t(account: &signer) - acquires R(*) + acquires R { { let _: bool = exists(0x0); diff --git a/third_party/move/move-compiler-v2/tests/checking/receiver/calls_index.exp b/third_party/move/move-compiler-v2/tests/checking/receiver/calls_index.exp index c267a8c7584..d651e7fae8a 100644 --- a/third_party/move/move-compiler-v2/tests/checking/receiver/calls_index.exp +++ b/third_party/move/move-compiler-v2/tests/checking/receiver/calls_index.exp @@ -31,42 +31,42 @@ module 0x42::m { m::greater(vector::borrow(Borrow(Immutable)(v), 0), w) } private fun dispatch(account: address): T - acquires Wrapper(*) + acquires Wrapper { m::unwrap(BorrowGlobal(Immutable)>(account)) } private fun foo(account: address,w: W) - acquires S(*) + acquires S { m::merge(Borrow(Mutable)(select m::T.w(select m::S.t(BorrowGlobal(Mutable)(account)))), w) } private fun foo_(account: address,w: W) - acquires S(*) + acquires S { m::merge(Borrow(Mutable)(select m::T.w(select m::S.t(BorrowGlobal(Mutable)(account)))), w) } private fun foo_2(account: address,w: W) - acquires W(*) + acquires W { m::merge(BorrowGlobal(Mutable)(account), w) } private fun foo_3(account: address,w: W) - acquires W(*) + acquires W { m::merge(BorrowGlobal(Mutable)(account), w) } private fun foo_greater(account: address,w: W): bool - acquires S(*) + acquires S { m::greater(Borrow(Immutable)(select m::T.w(select m::S.t(BorrowGlobal(Immutable)(account)))), w) } private fun foo_greater_(account: address,w: W): bool - acquires S(*) + acquires S { m::greater(Freeze(false)(Borrow(Mutable)(select m::T.w(select m::S.t(BorrowGlobal(Mutable)(account))))), w) } private fun foo_greater_2(account: address,w: W): bool - acquires W(*) + acquires W { m::greater(BorrowGlobal(Immutable)(account), w) } diff --git a/third_party/move/move-compiler-v2/tests/checking/specs/move_function_in_spec_ok.exp b/third_party/move/move-compiler-v2/tests/checking/specs/move_function_in_spec_ok.exp index 92a9e178b14..6b495013520 100644 --- a/third_party/move/move-compiler-v2/tests/checking/specs/move_function_in_spec_ok.exp +++ b/third_party/move/move-compiler-v2/tests/checking/specs/move_function_in_spec_ok.exp @@ -18,7 +18,7 @@ module 0x42::move_function_in_spec { } } public fun no_change(target: address,new_addr: address): bool - acquires TypeInfo(*) + acquires TypeInfo { { let ty: &TypeInfo = BorrowGlobal(Immutable)(target); diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/dummy_field.exp b/third_party/move/move-compiler-v2/tests/checking/typing/dummy_field.exp index 4dfa0b7196b..4003114961f 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/dummy_field.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/dummy_field.exp @@ -7,7 +7,7 @@ module 0x42::test { dummy_field: bool, } public entry fun test(addr: address) - acquires R(*) + acquires R { { let test::R{ dummy_field: _dummy_field } = MoveFrom(addr); @@ -21,7 +21,7 @@ module 0x42::test { } } public entry fun test3(addr: address) - acquires T(*) + acquires T { { let test::T{ dummy_field: _ } = MoveFrom(addr); diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/global_builtins.exp b/third_party/move/move-compiler-v2/tests/checking/typing/global_builtins.exp index 1d2171c4b11..11930e909f6 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/global_builtins.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/global_builtins.exp @@ -4,7 +4,7 @@ module 0x8675309::M { dummy_field: bool, } private fun t0(a: &signer) - acquires R(*) + acquires R { { let _: bool = exists(0x0); @@ -24,7 +24,7 @@ module 0x8675309::M { } } private fun t1(a: &signer) - acquires R(*) + acquires R { { let _: bool = exists(0x0); diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/global_builtins_inferred.exp b/third_party/move/move-compiler-v2/tests/checking/typing/global_builtins_inferred.exp index 2109d1efe8f..7d42ff1d131 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/global_builtins_inferred.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/global_builtins_inferred.exp @@ -4,7 +4,7 @@ module 0x42::m { addr: address, } public fun foo(input: address): address - acquires A(*) + acquires A { { let a: A = MoveFrom(input); diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/move_from_type_argument.exp b/third_party/move/move-compiler-v2/tests/checking/typing/move_from_type_argument.exp index 2109d1efe8f..7d42ff1d131 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/move_from_type_argument.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/move_from_type_argument.exp @@ -4,7 +4,7 @@ module 0x42::m { addr: address, } public fun foo(input: address): address - acquires A(*) + acquires A { { let a: A = MoveFrom(input); diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/v1-examples/multi_pool_money_market_token.exp b/third_party/move/move-compiler-v2/tests/checking/typing/v1-examples/multi_pool_money_market_token.exp index fd7953016dc..02877443746 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/v1-examples/multi_pool_money_market_token.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/v1-examples/multi_pool_money_market_token.exp @@ -79,10 +79,10 @@ module 0x3::OneToOneMarket { price: u64, } public fun borrow(account: &signer,pool_owner: address,amount: u64): Token::Coin - acquires Price(*) - acquires Pool(*) - acquires DepositRecord(*) - acquires BorrowRecord(*) + acquires Price + acquires Pool + acquires DepositRecord + acquires BorrowRecord { if Le(amount, OneToOneMarket::max_borrow_amount(account, pool_owner)) { Tuple() @@ -96,8 +96,8 @@ module 0x3::OneToOneMarket { } } public fun deposit(account: &signer,pool_owner: address,coin: Token::Coin) - acquires Pool(*) - acquires DepositRecord(*) + acquires Pool + acquires DepositRecord { { let amount: u64 = Token::value(Borrow(Immutable)(coin)); @@ -120,7 +120,7 @@ module 0x3::OneToOneMarket { } } private fun borrowed_amount(account: &signer,pool_owner: address): u64 - acquires BorrowRecord(*) + acquires BorrowRecord { { let sender: address = signer::address_of(account); @@ -140,7 +140,7 @@ module 0x3::OneToOneMarket { } } private fun deposited_amount(account: &signer,pool_owner: address): u64 - acquires DepositRecord(*) + acquires DepositRecord { { let sender: address = signer::address_of(account); @@ -160,10 +160,10 @@ module 0x3::OneToOneMarket { } } private fun max_borrow_amount(account: &signer,pool_owner: address): u64 - acquires Price(*) - acquires Pool(*) - acquires DepositRecord(*) - acquires BorrowRecord(*) + acquires Price + acquires Pool + acquires DepositRecord + acquires BorrowRecord { { let input_deposited: u64 = OneToOneMarket::deposited_amount(account, pool_owner); @@ -199,7 +199,7 @@ module 0x3::OneToOneMarket { MoveTo>(account, pack OneToOneMarket::Price(price)) } private fun update_borrow_record(account: &signer,pool_owner: address,amount: u64) - acquires BorrowRecord(*) + acquires BorrowRecord { { let sender: address = signer::address_of(account); @@ -224,7 +224,7 @@ module 0x3::OneToOneMarket { } } private fun update_deposit_record(account: &signer,pool_owner: address,amount: u64) - acquires DepositRecord(*) + acquires DepositRecord { { let sender: address = signer::address_of(account); @@ -267,7 +267,7 @@ module 0x70dd::ToddNickels { MoveTo(account, pack ToddNickels::Wallet(Token::create(pack ToddNickels::T(false), 0))) } public fun destroy(c: Token::Coin) - acquires Wallet(*) + acquires Wallet { Token::deposit(Borrow(Mutable)(select ToddNickels::Wallet.nickels<&mut Wallet>(BorrowGlobal(Mutable)(0x70dd))), c) } diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/v1-examples/simple_money_market_token.exp b/third_party/move/move-compiler-v2/tests/checking/typing/v1-examples/simple_money_market_token.exp index b8d3ce40a5e..cbe77c9ed8b 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/v1-examples/simple_money_market_token.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/v1-examples/simple_money_market_token.exp @@ -70,7 +70,7 @@ module 0x70dd::ToddNickels { MoveTo(account, pack ToddNickels::Wallet(Token::create(pack ToddNickels::T(false), 0))) } public fun destroy(c: Token::Coin) - acquires Wallet(*) + acquires Wallet { Token::deposit(Borrow(Mutable)(select ToddNickels::Wallet.nickels<&mut Wallet>(BorrowGlobal(Mutable)(0x70dd))), c) } @@ -99,10 +99,10 @@ module 0xb055::OneToOneMarket { price: u64, } public fun borrow(account: &signer,amount: u64): Token::Coin - acquires Price(*) - acquires Pool(*) - acquires DepositRecord(*) - acquires BorrowRecord(*) + acquires Price + acquires Pool + acquires DepositRecord + acquires BorrowRecord { if Le(amount, OneToOneMarket::max_borrow_amount(account)) { Tuple() @@ -116,8 +116,8 @@ module 0xb055::OneToOneMarket { } } public fun deposit(account: &signer,coin: Token::Coin) - acquires Pool(*) - acquires DepositRecord(*) + acquires Pool + acquires DepositRecord { { let amount: u64 = Token::value(Borrow(Immutable)(coin)); @@ -140,7 +140,7 @@ module 0xb055::OneToOneMarket { } } private fun borrowed_amount(account: &signer): u64 - acquires BorrowRecord(*) + acquires BorrowRecord { { let sender: address = signer::address_of(account); @@ -153,7 +153,7 @@ module 0xb055::OneToOneMarket { } } private fun deposited_amount(account: &signer): u64 - acquires DepositRecord(*) + acquires DepositRecord { { let sender: address = signer::address_of(account); @@ -166,10 +166,10 @@ module 0xb055::OneToOneMarket { } } private fun max_borrow_amount(account: &signer): u64 - acquires Price(*) - acquires Pool(*) - acquires DepositRecord(*) - acquires BorrowRecord(*) + acquires Price + acquires Pool + acquires DepositRecord + acquires BorrowRecord { { let input_deposited: u64 = OneToOneMarket::deposited_amount(account); @@ -213,7 +213,7 @@ module 0xb055::OneToOneMarket { } } private fun update_borrow_record(account: &signer,amount: u64) - acquires BorrowRecord(*) + acquires BorrowRecord { { let sender: address = signer::address_of(account); @@ -229,7 +229,7 @@ module 0xb055::OneToOneMarket { } } private fun update_deposit_record(account: &signer,amount: u64) - acquires DepositRecord(*) + acquires DepositRecord { { let sender: address = signer::address_of(account); diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/valid_ref_source.exp b/third_party/move/move-compiler-v2/tests/integers/signed/valid_ref_source.exp index 5314452a25e..5c0d45e42bd 100644 --- a/third_party/move/move-compiler-v2/tests/integers/signed/valid_ref_source.exp +++ b/third_party/move/move-compiler-v2/tests/integers/signed/valid_ref_source.exp @@ -80,19 +80,25 @@ module 0x42::valid_ref_resource { fun test_deref2(a: &i128): i128 { *a } - fun test_exist1(addr: address): i64 { + fun test_exist1(addr: address): i64 + acquires S1 + { if (exists(addr)) { let s = borrow_global(addr); s.y } else 1i64 } - fun test_exist2(addr: address): i128 { + fun test_exist2(addr: address): i128 + acquires S1 + { if (exists(addr)) { let s = borrow_global(addr); s.z } else 1i128 } - fun test_move_from(account: &signer, addr: address): i64 { + fun test_move_from(account: &signer, addr: address): i64 + acquires S1 + { let s1 = S1{x: 1, y: -1i64, z: -2i128}; if (exists(addr)) move_from(0x1::signer::address_of(account)).y else s1.y } diff --git a/third_party/move/move-compiler-v2/tests/more-v1/translated_ir_tests/move/borrow_tests/imm_borrow_global_lossy_acquire_invalid.exp b/third_party/move/move-compiler-v2/tests/more-v1/translated_ir_tests/move/borrow_tests/imm_borrow_global_lossy_acquire_invalid.exp index 5242e87363c..7445def7b56 100644 --- a/third_party/move/move-compiler-v2/tests/more-v1/translated_ir_tests/move/borrow_tests/imm_borrow_global_lossy_acquire_invalid.exp +++ b/third_party/move/move-compiler-v2/tests/more-v1/translated_ir_tests/move/borrow_tests/imm_borrow_global_lossy_acquire_invalid.exp @@ -10,4 +10,4 @@ error: function acquires global `Tester::Pair` which is currently borrowed │ ^^^^^^^^^^^^^^^^^^^^ function called here · 35 │ fun eq_helper(p1: &Pair, addr2: address): bool acquires Pair { - │ ----- `acquires` declared here + │ ---- `acquires` declared here diff --git a/third_party/move/move-compiler-v2/tests/more-v1/typing/invalid_type_acquire.exp b/third_party/move/move-compiler-v2/tests/more-v1/typing/invalid_type_acquire.exp index 697fe50a403..5dd261bdbae 100644 --- a/third_party/move/move-compiler-v2/tests/more-v1/typing/invalid_type_acquire.exp +++ b/third_party/move/move-compiler-v2/tests/more-v1/typing/invalid_type_acquire.exp @@ -1,12 +1,12 @@ Diagnostics: -error: invalid access specifier +error: undeclared `0x2::M::T` ┌─ tests/more-v1/typing/invalid_type_acquire.move:18:9 │ 18 │ T, │ ^ -error: invalid access specifier +error: undeclared `0x2::M::u64` ┌─ tests/more-v1/typing/invalid_type_acquire.move:19:9 │ 19 │ u64, diff --git a/third_party/move/move-compiler-v2/tests/op-equal/valid0.exp b/third_party/move/move-compiler-v2/tests/op-equal/valid0.exp index 91846d30653..6275bfb075c 100644 --- a/third_party/move/move-compiler-v2/tests/op-equal/valid0.exp +++ b/third_party/move/move-compiler-v2/tests/op-equal/valid0.exp @@ -46,7 +46,7 @@ module 0x42::test { } } private fun inc_coin_at(addr: address) - acquires Coin(*) + acquires Coin { { let coin: &mut Coin = BorrowGlobal(Mutable)(addr); @@ -1743,7 +1743,7 @@ module 0x42::test { } } private fun inc_coin_at(addr: address) - acquires Coin(*) + acquires Coin { { let coin: &mut Coin = BorrowGlobal(Mutable)(addr); diff --git a/third_party/move/move-compiler-v2/tests/op-equal/valid1.exp b/third_party/move/move-compiler-v2/tests/op-equal/valid1.exp index 14cf005f34c..464734ce139 100644 --- a/third_party/move/move-compiler-v2/tests/op-equal/valid1.exp +++ b/third_party/move/move-compiler-v2/tests/op-equal/valid1.exp @@ -67,7 +67,7 @@ module 0x42::test { Tuple() } private fun shr_coin_at(addr: address) - acquires Coin(*) + acquires Coin { { let coin: &mut Coin = BorrowGlobal(Mutable)(addr); @@ -1002,7 +1002,7 @@ module 0x42::test { Tuple() } private fun shr_coin_at(addr: address) - acquires Coin(*) + acquires Coin { { let coin: &mut Coin = BorrowGlobal(Mutable)(addr); diff --git a/third_party/move/move-compiler-v2/tests/reference-safety-v2/call_acquires_immutable_borrow.exp b/third_party/move/move-compiler-v2/tests/reference-safety-v2/call_acquires_immutable_borrow.exp new file mode 100644 index 00000000000..976b502c894 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/reference-safety-v2/call_acquires_immutable_borrow.exp @@ -0,0 +1,12 @@ + +Diagnostics: +error: function acquires global `m::R` which is currently borrowed + ┌─ tests/reference-safety-v2/call_acquires_immutable_borrow.move:14:27 + │ + 8 │ fun take(addr: address): R acquires R { + │ - `acquires` declared here + · +13 │ let reference = borrow_global(addr); + │ ---------------------- previous global borrow +14 │ let R { value } = take(addr); + │ ^^^^^^^^^^ function called here diff --git a/third_party/move/move-compiler-v2/tests/reference-safety-v2/call_acquires_immutable_borrow.move b/third_party/move/move-compiler-v2/tests/reference-safety-v2/call_acquires_immutable_borrow.move new file mode 100644 index 00000000000..5bcb77e548e --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/reference-safety-v2/call_acquires_immutable_borrow.move @@ -0,0 +1,17 @@ +// Calling an acquiring function while the resource is immutably borrowed must +// be rejected at the source level: `take` may `move_from` the value under +// `reference`. The v2 processor historically only rejected mutable borrows, +// which let this program through to a bytecode verification failure. +module 0x42::m { + struct R has key { value: u64 } + + fun take(addr: address): R acquires R { + move_from(addr) + } + + fun immutable_conflict(addr: address): u64 acquires R { + let reference = borrow_global(addr); + let R { value } = take(addr); + reference.value + value + } +} diff --git a/third_party/move/move-compiler-v2/tests/reference-safety-v2/call_acquires_mutability.exp b/third_party/move/move-compiler-v2/tests/reference-safety-v2/call_acquires_mutability.exp new file mode 100644 index 00000000000..ff99e74b27d --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/reference-safety-v2/call_acquires_mutability.exp @@ -0,0 +1,23 @@ + +Diagnostics: +error: function acquires global `m::R` which is currently mutably borrowed + ┌─ tests/reference-safety-v2/call_acquires_mutability.move:10:27 + │ + 4 │ fun take(addr: address): R acquires R { + │ - `acquires` declared here + · + 9 │ let reference = borrow_global_mut(addr); + │ -------------------------- previous mutable global borrow +10 │ let R { value } = take(addr); + │ ^^^^^^^^^^ function called here + +error: function acquires global `m::R` which is currently borrowed + ┌─ tests/reference-safety-v2/call_acquires_mutability.move:16:27 + │ + 4 │ fun take(addr: address): R acquires R { + │ - `acquires` declared here + · +15 │ let reference = borrow_global(addr); + │ ---------------------- previous global borrow +16 │ let R { value } = take(addr); + │ ^^^^^^^^^^ function called here diff --git a/third_party/move/move-compiler-v2/tests/reference-safety-v2/call_acquires_mutability.move b/third_party/move/move-compiler-v2/tests/reference-safety-v2/call_acquires_mutability.move new file mode 100644 index 00000000000..b6d93198b6b --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/reference-safety-v2/call_acquires_mutability.move @@ -0,0 +1,19 @@ +module 0x42::m { + struct R has key { value: u64 } + + fun take(addr: address): R acquires R { + move_from(addr) + } + + fun mutable_conflict(addr: address) acquires R { + let reference = borrow_global_mut(addr); + let R { value } = take(addr); + reference.value = value + } + + fun immutable_conflict(addr: address): u64 acquires R { + let reference = borrow_global(addr); + let R { value } = take(addr); + reference.value + value + } +} diff --git a/third_party/move/move-compiler-v2/tests/reference-safety/call_access_invalid.exp b/third_party/move/move-compiler-v2/tests/reference-safety/call_access_invalid.exp deleted file mode 100644 index e29c8a294a2..00000000000 --- a/third_party/move/move-compiler-v2/tests/reference-safety/call_access_invalid.exp +++ /dev/null @@ -1,143 +0,0 @@ - -Diagnostics: -error: function acquires global `m::R` which is currently mutably borrowed - ┌─ tests/reference-safety/call_access_invalid.move:27:9 - │ - 5 │ fun reads_any_R(addr: address) reads R { - │ ----------- `acquires` of this function was inferred - · -26 │ let _r1 = borrow_global_mut>(addr); - │ ------------------------------- struct `m::R` previously mutably borrowed here -27 │ reads_any_R(addr); - │ ^^^^^^^^^^^^^^^^^ function called here - · -31 │ *_r1; - │ ---- conflicting reference `_r1` used here - -error: function acquires global `m::R` which is currently mutably borrowed - ┌─ tests/reference-safety/call_access_invalid.move:28:9 - │ - 9 │ fun reads_any_cafe(addr: address) reads 0xcafe::*::* { - │ -------------- `acquires` of this function was inferred - · -26 │ let _r1 = borrow_global_mut>(addr); - │ ------------------------------- struct `m::R` previously mutably borrowed here -27 │ reads_any_R(addr); -28 │ reads_any_cafe(addr); - │ ^^^^^^^^^^^^^^^^^^^^ function called here - · -31 │ *_r1; - │ ---- conflicting reference `_r1` used here - -error: function acquires global `m::R` which is currently mutably borrowed - ┌─ tests/reference-safety/call_access_invalid.move:29:9 - │ -13 │ fun reads_any_m(addr: address) reads 0xcafe::m::* { - │ ----------- `acquires` of this function was inferred - · -26 │ let _r1 = borrow_global_mut>(addr); - │ ------------------------------- struct `m::R` previously mutably borrowed here - · -29 │ reads_any_m(addr); - │ ^^^^^^^^^^^^^^^^^ function called here -30 │ reads_not_any_m(addr); // no error -31 │ *_r1; - │ ---- conflicting reference `_r1` used here - -error: function acquires global `m::R` which is currently mutably borrowed - ┌─ tests/reference-safety/call_access_invalid.move:30:9 - │ -17 │ fun reads_not_any_m(addr: address) !reads 0xcafe::m::* { - │ --------------- `acquires` of this function was inferred - · -26 │ let _r1 = borrow_global_mut>(addr); - │ ------------------------------- struct `m::R` previously mutably borrowed here - · -30 │ reads_not_any_m(addr); // no error - │ ^^^^^^^^^^^^^^^^^^^^^ function called here -31 │ *_r1; - │ ---- conflicting reference `_r1` used here - -error: function acquires global `m::R` which is currently borrowed - ┌─ tests/reference-safety/call_access_invalid.move:36:9 - │ - 5 │ fun reads_any_R(addr: address) reads R { - │ ----------- `acquires` of this function was inferred - · -35 │ let _r1 = borrow_global>(addr); - │ --------------------------- struct `m::R` previously borrowed here -36 │ reads_any_R(addr); - │ ^^^^^^^^^^^^^^^^^ function called here - · -40 │ *_r1; - │ ---- conflicting reference `_r1` used here - -error: function acquires global `m::R` which is currently borrowed - ┌─ tests/reference-safety/call_access_invalid.move:37:9 - │ - 9 │ fun reads_any_cafe(addr: address) reads 0xcafe::*::* { - │ -------------- `acquires` of this function was inferred - · -35 │ let _r1 = borrow_global>(addr); - │ --------------------------- struct `m::R` previously borrowed here -36 │ reads_any_R(addr); -37 │ reads_any_cafe(addr); - │ ^^^^^^^^^^^^^^^^^^^^ function called here - · -40 │ *_r1; - │ ---- conflicting reference `_r1` used here - -error: function acquires global `m::R` which is currently borrowed - ┌─ tests/reference-safety/call_access_invalid.move:38:9 - │ -13 │ fun reads_any_m(addr: address) reads 0xcafe::m::* { - │ ----------- `acquires` of this function was inferred - · -35 │ let _r1 = borrow_global>(addr); - │ --------------------------- struct `m::R` previously borrowed here - · -38 │ reads_any_m(addr); - │ ^^^^^^^^^^^^^^^^^ function called here -39 │ reads_not_any_m(addr); -40 │ *_r1; - │ ---- conflicting reference `_r1` used here - -error: function acquires global `m::R` which is currently borrowed - ┌─ tests/reference-safety/call_access_invalid.move:39:9 - │ -17 │ fun reads_not_any_m(addr: address) !reads 0xcafe::m::* { - │ --------------- `acquires` of this function was inferred - · -35 │ let _r1 = borrow_global>(addr); - │ --------------------------- struct `m::R` previously borrowed here - · -39 │ reads_not_any_m(addr); - │ ^^^^^^^^^^^^^^^^^^^^^ function called here -40 │ *_r1; - │ ---- conflicting reference `_r1` used here - -error: function acquires global `m::R` which is currently borrowed - ┌─ tests/reference-safety/call_access_invalid.move:45:9 - │ -21 │ fun writes_any_R_u64(addr: address) writes R(addr) { - │ ---------------- `acquires` of this function was inferred - · -44 │ let _r1 = borrow_global>(addr); - │ --------------------------- struct `m::R` previously borrowed here -45 │ writes_any_R_u64(addr); - │ ^^^^^^^^^^^^^^^^^^^^^^ function called here -46 │ *_r1; - │ ---- conflicting reference `_r1` used here - -error: function acquires global `m::R` which is currently borrowed - ┌─ tests/reference-safety/call_access_invalid.move:51:9 - │ -21 │ fun writes_any_R_u64(addr: address) writes R(addr) { - │ ---------------- `acquires` of this function was inferred - · -50 │ let _r1 = borrow_global>(addr); - │ ---------------------------- struct `m::R` previously borrowed here -51 │ writes_any_R_u64(addr); - │ ^^^^^^^^^^^^^^^^^^^^^^ function called here -52 │ *_r1; - │ ---- conflicting reference `_r1` used here diff --git a/third_party/move/move-compiler-v2/tests/reference-safety/call_access_invalid.move b/third_party/move/move-compiler-v2/tests/reference-safety/call_access_invalid.move deleted file mode 100644 index 08ecd902972..00000000000 --- a/third_party/move/move-compiler-v2/tests/reference-safety/call_access_invalid.move +++ /dev/null @@ -1,55 +0,0 @@ -module 0xcafe::m { - - struct R has key, copy, drop { } - - fun reads_any_R(addr: address) reads R { - let _x = borrow_global>(addr); - } - - fun reads_any_cafe(addr: address) reads 0xcafe::*::* { - let _x = borrow_global>(addr); - } - - fun reads_any_m(addr: address) reads 0xcafe::m::* { - let _x = borrow_global>(addr); - } - - fun reads_not_any_m(addr: address) !reads 0xcafe::m::* { - let _x = borrow_global>(addr); - } - - fun writes_any_R_u64(addr: address) writes R(addr) { - let _x = borrow_global_mut>(addr); - } - - fun t0_invalid(addr: address) acquires R { - let _r1 = borrow_global_mut>(addr); - reads_any_R(addr); - reads_any_cafe(addr); - reads_any_m(addr); - reads_not_any_m(addr); // no error - *_r1; - } - - fun t1_valid(addr: address) acquires R { - let _r1 = borrow_global>(addr); - reads_any_R(addr); - reads_any_cafe(addr); - reads_any_m(addr); - reads_not_any_m(addr); - *_r1; - } - - fun t2_invalid(addr: address) acquires R { - let _r1 = borrow_global>(addr); - writes_any_R_u64(addr); - *_r1; - } - - fun t3_valid(addr: address) acquires R { - let _r1 = borrow_global>(addr); - writes_any_R_u64(addr); - *_r1; - } - -} diff --git a/third_party/move/move-compiler-v2/tests/reference-safety/call_access_invalid.no-opt.exp b/third_party/move/move-compiler-v2/tests/reference-safety/call_access_invalid.no-opt.exp deleted file mode 100644 index e29c8a294a2..00000000000 --- a/third_party/move/move-compiler-v2/tests/reference-safety/call_access_invalid.no-opt.exp +++ /dev/null @@ -1,143 +0,0 @@ - -Diagnostics: -error: function acquires global `m::R` which is currently mutably borrowed - ┌─ tests/reference-safety/call_access_invalid.move:27:9 - │ - 5 │ fun reads_any_R(addr: address) reads R { - │ ----------- `acquires` of this function was inferred - · -26 │ let _r1 = borrow_global_mut>(addr); - │ ------------------------------- struct `m::R` previously mutably borrowed here -27 │ reads_any_R(addr); - │ ^^^^^^^^^^^^^^^^^ function called here - · -31 │ *_r1; - │ ---- conflicting reference `_r1` used here - -error: function acquires global `m::R` which is currently mutably borrowed - ┌─ tests/reference-safety/call_access_invalid.move:28:9 - │ - 9 │ fun reads_any_cafe(addr: address) reads 0xcafe::*::* { - │ -------------- `acquires` of this function was inferred - · -26 │ let _r1 = borrow_global_mut>(addr); - │ ------------------------------- struct `m::R` previously mutably borrowed here -27 │ reads_any_R(addr); -28 │ reads_any_cafe(addr); - │ ^^^^^^^^^^^^^^^^^^^^ function called here - · -31 │ *_r1; - │ ---- conflicting reference `_r1` used here - -error: function acquires global `m::R` which is currently mutably borrowed - ┌─ tests/reference-safety/call_access_invalid.move:29:9 - │ -13 │ fun reads_any_m(addr: address) reads 0xcafe::m::* { - │ ----------- `acquires` of this function was inferred - · -26 │ let _r1 = borrow_global_mut>(addr); - │ ------------------------------- struct `m::R` previously mutably borrowed here - · -29 │ reads_any_m(addr); - │ ^^^^^^^^^^^^^^^^^ function called here -30 │ reads_not_any_m(addr); // no error -31 │ *_r1; - │ ---- conflicting reference `_r1` used here - -error: function acquires global `m::R` which is currently mutably borrowed - ┌─ tests/reference-safety/call_access_invalid.move:30:9 - │ -17 │ fun reads_not_any_m(addr: address) !reads 0xcafe::m::* { - │ --------------- `acquires` of this function was inferred - · -26 │ let _r1 = borrow_global_mut>(addr); - │ ------------------------------- struct `m::R` previously mutably borrowed here - · -30 │ reads_not_any_m(addr); // no error - │ ^^^^^^^^^^^^^^^^^^^^^ function called here -31 │ *_r1; - │ ---- conflicting reference `_r1` used here - -error: function acquires global `m::R` which is currently borrowed - ┌─ tests/reference-safety/call_access_invalid.move:36:9 - │ - 5 │ fun reads_any_R(addr: address) reads R { - │ ----------- `acquires` of this function was inferred - · -35 │ let _r1 = borrow_global>(addr); - │ --------------------------- struct `m::R` previously borrowed here -36 │ reads_any_R(addr); - │ ^^^^^^^^^^^^^^^^^ function called here - · -40 │ *_r1; - │ ---- conflicting reference `_r1` used here - -error: function acquires global `m::R` which is currently borrowed - ┌─ tests/reference-safety/call_access_invalid.move:37:9 - │ - 9 │ fun reads_any_cafe(addr: address) reads 0xcafe::*::* { - │ -------------- `acquires` of this function was inferred - · -35 │ let _r1 = borrow_global>(addr); - │ --------------------------- struct `m::R` previously borrowed here -36 │ reads_any_R(addr); -37 │ reads_any_cafe(addr); - │ ^^^^^^^^^^^^^^^^^^^^ function called here - · -40 │ *_r1; - │ ---- conflicting reference `_r1` used here - -error: function acquires global `m::R` which is currently borrowed - ┌─ tests/reference-safety/call_access_invalid.move:38:9 - │ -13 │ fun reads_any_m(addr: address) reads 0xcafe::m::* { - │ ----------- `acquires` of this function was inferred - · -35 │ let _r1 = borrow_global>(addr); - │ --------------------------- struct `m::R` previously borrowed here - · -38 │ reads_any_m(addr); - │ ^^^^^^^^^^^^^^^^^ function called here -39 │ reads_not_any_m(addr); -40 │ *_r1; - │ ---- conflicting reference `_r1` used here - -error: function acquires global `m::R` which is currently borrowed - ┌─ tests/reference-safety/call_access_invalid.move:39:9 - │ -17 │ fun reads_not_any_m(addr: address) !reads 0xcafe::m::* { - │ --------------- `acquires` of this function was inferred - · -35 │ let _r1 = borrow_global>(addr); - │ --------------------------- struct `m::R` previously borrowed here - · -39 │ reads_not_any_m(addr); - │ ^^^^^^^^^^^^^^^^^^^^^ function called here -40 │ *_r1; - │ ---- conflicting reference `_r1` used here - -error: function acquires global `m::R` which is currently borrowed - ┌─ tests/reference-safety/call_access_invalid.move:45:9 - │ -21 │ fun writes_any_R_u64(addr: address) writes R(addr) { - │ ---------------- `acquires` of this function was inferred - · -44 │ let _r1 = borrow_global>(addr); - │ --------------------------- struct `m::R` previously borrowed here -45 │ writes_any_R_u64(addr); - │ ^^^^^^^^^^^^^^^^^^^^^^ function called here -46 │ *_r1; - │ ---- conflicting reference `_r1` used here - -error: function acquires global `m::R` which is currently borrowed - ┌─ tests/reference-safety/call_access_invalid.move:51:9 - │ -21 │ fun writes_any_R_u64(addr: address) writes R(addr) { - │ ---------------- `acquires` of this function was inferred - · -50 │ let _r1 = borrow_global>(addr); - │ ---------------------------- struct `m::R` previously borrowed here -51 │ writes_any_R_u64(addr); - │ ^^^^^^^^^^^^^^^^^^^^^^ function called here -52 │ *_r1; - │ ---- conflicting reference `_r1` used here diff --git a/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_1.exp b/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_1.exp index 81b58cfcbd0..1c2c0c211cd 100644 --- a/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_1.exp +++ b/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_1.exp @@ -11,4 +11,4 @@ error: function acquires global `A::T1` which is currently mutably borrowed │ ------ conflicting reference `x` used here · 11 │ fun acquires_t1(account: &signer) acquires T1 { - │ --- `acquires` declared here + │ -- `acquires` declared here diff --git a/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_1.no-opt.exp b/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_1.no-opt.exp index 81b58cfcbd0..1c2c0c211cd 100644 --- a/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_1.no-opt.exp +++ b/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_1.no-opt.exp @@ -11,4 +11,4 @@ error: function acquires global `A::T1` which is currently mutably borrowed │ ------ conflicting reference `x` used here · 11 │ fun acquires_t1(account: &signer) acquires T1 { - │ --- `acquires` declared here + │ -- `acquires` declared here diff --git a/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_2.exp b/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_2.exp index 7e54c97816d..6f13dee261b 100644 --- a/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_2.exp +++ b/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_2.exp @@ -12,7 +12,7 @@ error: function acquires global `A::T1` which is currently mutably borrowed │ ------ conflicting reference `x` used here · 27 │ fun acquires_t1(account: &signer) acquires T1 { - │ --- `acquires` declared here + │ -- `acquires` declared here error: function acquires global `A::T1` which is currently mutably borrowed ┌─ tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_2.move:16:9 @@ -26,7 +26,7 @@ error: function acquires global `A::T1` which is currently mutably borrowed │ ------ conflicting reference `x` used here · 27 │ fun acquires_t1(account: &signer) acquires T1 { - │ --- `acquires` declared here + │ -- `acquires` declared here error: function acquires global `A::T1` which is currently mutably borrowed ┌─ tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_2.move:22:9 @@ -39,4 +39,4 @@ error: function acquires global `A::T1` which is currently mutably borrowed │ ------ conflicting reference `x` used here · 27 │ fun acquires_t1(account: &signer) acquires T1 { - │ --- `acquires` declared here + │ -- `acquires` declared here diff --git a/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_2.no-opt.exp b/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_2.no-opt.exp index 7e54c97816d..6f13dee261b 100644 --- a/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_2.no-opt.exp +++ b/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_2.no-opt.exp @@ -12,7 +12,7 @@ error: function acquires global `A::T1` which is currently mutably borrowed │ ------ conflicting reference `x` used here · 27 │ fun acquires_t1(account: &signer) acquires T1 { - │ --- `acquires` declared here + │ -- `acquires` declared here error: function acquires global `A::T1` which is currently mutably borrowed ┌─ tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_2.move:16:9 @@ -26,7 +26,7 @@ error: function acquires global `A::T1` which is currently mutably borrowed │ ------ conflicting reference `x` used here · 27 │ fun acquires_t1(account: &signer) acquires T1 { - │ --- `acquires` declared here + │ -- `acquires` declared here error: function acquires global `A::T1` which is currently mutably borrowed ┌─ tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_2.move:22:9 @@ -39,4 +39,4 @@ error: function acquires global `A::T1` which is currently mutably borrowed │ ------ conflicting reference `x` used here · 27 │ fun acquires_t1(account: &signer) acquires T1 { - │ --- `acquires` declared here + │ -- `acquires` declared here diff --git a/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_3.exp b/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_3.exp index fe74a7cbc26..d678613efdb 100644 --- a/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_3.exp +++ b/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_3.exp @@ -12,7 +12,7 @@ error: function acquires global `A::T1` which is currently mutably borrowed │ ------ conflicting reference `y` used here · 34 │ fun acquires_t1(account: &signer) acquires T1 { - │ --- `acquires` declared here + │ -- `acquires` declared here error: function acquires global `A::T1` which is currently mutably borrowed ┌─ tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_3.move:18:9 @@ -26,7 +26,7 @@ error: function acquires global `A::T1` which is currently mutably borrowed │ ------ conflicting reference `y` used here · 34 │ fun acquires_t1(account: &signer) acquires T1 { - │ --- `acquires` declared here + │ -- `acquires` declared here error: function acquires global `A::T1` which is currently mutably borrowed ┌─ tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_3.move:25:9 @@ -39,4 +39,4 @@ error: function acquires global `A::T1` which is currently mutably borrowed │ ------ conflicting reference `y` used here · 34 │ fun acquires_t1(account: &signer) acquires T1 { - │ --- `acquires` declared here + │ -- `acquires` declared here diff --git a/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_3.no-opt.exp b/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_3.no-opt.exp index fe74a7cbc26..d678613efdb 100644 --- a/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_3.no-opt.exp +++ b/third_party/move/move-compiler-v2/tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_3.no-opt.exp @@ -12,7 +12,7 @@ error: function acquires global `A::T1` which is currently mutably borrowed │ ------ conflicting reference `y` used here · 34 │ fun acquires_t1(account: &signer) acquires T1 { - │ --- `acquires` declared here + │ -- `acquires` declared here error: function acquires global `A::T1` which is currently mutably borrowed ┌─ tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_3.move:18:9 @@ -26,7 +26,7 @@ error: function acquires global `A::T1` which is currently mutably borrowed │ ------ conflicting reference `y` used here · 34 │ fun acquires_t1(account: &signer) acquires T1 { - │ --- `acquires` declared here + │ -- `acquires` declared here error: function acquires global `A::T1` which is currently mutably borrowed ┌─ tests/reference-safety/v1-borrow-tests/borrow_global_acquires_invalid_3.move:25:9 @@ -39,4 +39,4 @@ error: function acquires global `A::T1` which is currently mutably borrowed │ ------ conflicting reference `y` used here · 34 │ fun acquires_t1(account: &signer) acquires T1 { - │ --- `acquires` declared here + │ -- `acquires` declared here diff --git a/third_party/move/move-compiler-v2/tests/reference-safety/v1-tests/call_acquires_invalid.exp b/third_party/move/move-compiler-v2/tests/reference-safety/v1-tests/call_acquires_invalid.exp index 768e3cf10f6..80f3a97d423 100644 --- a/third_party/move/move-compiler-v2/tests/reference-safety/v1-tests/call_acquires_invalid.exp +++ b/third_party/move/move-compiler-v2/tests/reference-safety/v1-tests/call_acquires_invalid.exp @@ -4,7 +4,7 @@ error: function acquires global `M::R` which is currently mutably borrowed ┌─ tests/reference-safety/v1-tests/call_acquires_invalid.move:16:23 │ 10 │ fun acq(addr: address): R acquires R { - │ -- `acquires` declared here + │ - `acquires` declared here · 15 │ let r1 = borrow_global_mut(addr); │ -------------------------- struct `M::R` previously mutably borrowed here @@ -17,7 +17,7 @@ error: function acquires global `M::R` which is currently mutably borrowed ┌─ tests/reference-safety/v1-tests/call_acquires_invalid.move:22:23 │ 10 │ fun acq(addr: address): R acquires R { - │ -- `acquires` declared here + │ - `acquires` declared here · 21 │ let f_ref = &mut borrow_global_mut(addr).f; │ --------------------------------- struct `M::R` previously mutably borrowed here @@ -30,7 +30,7 @@ error: function acquires global `M::R` which is currently mutably borrowed ┌─ tests/reference-safety/v1-tests/call_acquires_invalid.move:28:23 │ 10 │ fun acq(addr: address): R acquires R { - │ -- `acquires` declared here + │ - `acquires` declared here · 27 │ let r1 = id_mut(borrow_global_mut(addr)); │ ---------------------------------- struct `M::R` previously mutably borrowed here @@ -43,7 +43,7 @@ error: function acquires global `M::R` which is currently mutably borrowed ┌─ tests/reference-safety/v1-tests/call_acquires_invalid.move:34:23 │ 10 │ fun acq(addr: address): R acquires R { - │ -- `acquires` declared here + │ - `acquires` declared here · 33 │ let f_ref = id_mut(&mut borrow_global_mut(addr).f); │ ----------------------------------------- struct `M::R` previously mutably borrowed here @@ -56,7 +56,7 @@ error: function acquires global `M::R` which is currently borrowed ┌─ tests/reference-safety/v1-tests/call_acquires_invalid.move:40:23 │ 10 │ fun acq(addr: address): R acquires R { - │ -- `acquires` declared here + │ - `acquires` declared here · 39 │ let r1 = borrow_global(addr); │ ---------------------- struct `M::R` previously borrowed here @@ -69,7 +69,7 @@ error: function acquires global `M::R` which is currently borrowed ┌─ tests/reference-safety/v1-tests/call_acquires_invalid.move:46:23 │ 10 │ fun acq(addr: address): R acquires R { - │ -- `acquires` declared here + │ - `acquires` declared here · 45 │ let f_ref = &borrow_global(addr).f; │ ------------------------- struct `M::R` previously borrowed here @@ -82,7 +82,7 @@ error: function acquires global `M::R` which is currently borrowed ┌─ tests/reference-safety/v1-tests/call_acquires_invalid.move:52:23 │ 10 │ fun acq(addr: address): R acquires R { - │ -- `acquires` declared here + │ - `acquires` declared here · 51 │ let r1 = id(borrow_global(addr)); │ -------------------------- struct `M::R` previously borrowed here @@ -95,7 +95,7 @@ error: function acquires global `M::R` which is currently borrowed ┌─ tests/reference-safety/v1-tests/call_acquires_invalid.move:58:23 │ 10 │ fun acq(addr: address): R acquires R { - │ -- `acquires` declared here + │ - `acquires` declared here · 57 │ let f_ref = id(&borrow_global(addr).f); │ ----------------------------- struct `M::R` previously borrowed here @@ -108,7 +108,7 @@ error: function acquires global `M::R` which is currently mutably borrowed ┌─ tests/reference-safety/v1-tests/call_acquires_invalid.move:66:23 │ 10 │ fun acq(addr: address): R acquires R { - │ -- `acquires` declared here + │ - `acquires` declared here · 65 │ let r1; if (cond) r1 = borrow_global_mut(addr) else r1 = &mut r; │ -------------------------- struct `M::R` previously mutably borrowed here diff --git a/third_party/move/move-compiler-v2/tests/reference-safety/v1-tests/call_acquires_invalid.no-opt.exp b/third_party/move/move-compiler-v2/tests/reference-safety/v1-tests/call_acquires_invalid.no-opt.exp index 768e3cf10f6..80f3a97d423 100644 --- a/third_party/move/move-compiler-v2/tests/reference-safety/v1-tests/call_acquires_invalid.no-opt.exp +++ b/third_party/move/move-compiler-v2/tests/reference-safety/v1-tests/call_acquires_invalid.no-opt.exp @@ -4,7 +4,7 @@ error: function acquires global `M::R` which is currently mutably borrowed ┌─ tests/reference-safety/v1-tests/call_acquires_invalid.move:16:23 │ 10 │ fun acq(addr: address): R acquires R { - │ -- `acquires` declared here + │ - `acquires` declared here · 15 │ let r1 = borrow_global_mut(addr); │ -------------------------- struct `M::R` previously mutably borrowed here @@ -17,7 +17,7 @@ error: function acquires global `M::R` which is currently mutably borrowed ┌─ tests/reference-safety/v1-tests/call_acquires_invalid.move:22:23 │ 10 │ fun acq(addr: address): R acquires R { - │ -- `acquires` declared here + │ - `acquires` declared here · 21 │ let f_ref = &mut borrow_global_mut(addr).f; │ --------------------------------- struct `M::R` previously mutably borrowed here @@ -30,7 +30,7 @@ error: function acquires global `M::R` which is currently mutably borrowed ┌─ tests/reference-safety/v1-tests/call_acquires_invalid.move:28:23 │ 10 │ fun acq(addr: address): R acquires R { - │ -- `acquires` declared here + │ - `acquires` declared here · 27 │ let r1 = id_mut(borrow_global_mut(addr)); │ ---------------------------------- struct `M::R` previously mutably borrowed here @@ -43,7 +43,7 @@ error: function acquires global `M::R` which is currently mutably borrowed ┌─ tests/reference-safety/v1-tests/call_acquires_invalid.move:34:23 │ 10 │ fun acq(addr: address): R acquires R { - │ -- `acquires` declared here + │ - `acquires` declared here · 33 │ let f_ref = id_mut(&mut borrow_global_mut(addr).f); │ ----------------------------------------- struct `M::R` previously mutably borrowed here @@ -56,7 +56,7 @@ error: function acquires global `M::R` which is currently borrowed ┌─ tests/reference-safety/v1-tests/call_acquires_invalid.move:40:23 │ 10 │ fun acq(addr: address): R acquires R { - │ -- `acquires` declared here + │ - `acquires` declared here · 39 │ let r1 = borrow_global(addr); │ ---------------------- struct `M::R` previously borrowed here @@ -69,7 +69,7 @@ error: function acquires global `M::R` which is currently borrowed ┌─ tests/reference-safety/v1-tests/call_acquires_invalid.move:46:23 │ 10 │ fun acq(addr: address): R acquires R { - │ -- `acquires` declared here + │ - `acquires` declared here · 45 │ let f_ref = &borrow_global(addr).f; │ ------------------------- struct `M::R` previously borrowed here @@ -82,7 +82,7 @@ error: function acquires global `M::R` which is currently borrowed ┌─ tests/reference-safety/v1-tests/call_acquires_invalid.move:52:23 │ 10 │ fun acq(addr: address): R acquires R { - │ -- `acquires` declared here + │ - `acquires` declared here · 51 │ let r1 = id(borrow_global(addr)); │ -------------------------- struct `M::R` previously borrowed here @@ -95,7 +95,7 @@ error: function acquires global `M::R` which is currently borrowed ┌─ tests/reference-safety/v1-tests/call_acquires_invalid.move:58:23 │ 10 │ fun acq(addr: address): R acquires R { - │ -- `acquires` declared here + │ - `acquires` declared here · 57 │ let f_ref = id(&borrow_global(addr).f); │ ----------------------------- struct `M::R` previously borrowed here @@ -108,7 +108,7 @@ error: function acquires global `M::R` which is currently mutably borrowed ┌─ tests/reference-safety/v1-tests/call_acquires_invalid.move:66:23 │ 10 │ fun acq(addr: address): R acquires R { - │ -- `acquires` declared here + │ - `acquires` declared here · 65 │ let r1; if (cond) r1 = borrow_global_mut(addr) else r1 = &mut r; │ -------------------------- struct `M::R` previously mutably borrowed here diff --git a/third_party/move/move-compiler-v2/tests/simplifier-elimination/assert_false_with_resource.exp b/third_party/move/move-compiler-v2/tests/simplifier-elimination/assert_false_with_resource.exp index 5478c305eb1..6d4bd0e0914 100644 --- a/third_party/move/move-compiler-v2/tests/simplifier-elimination/assert_false_with_resource.exp +++ b/third_party/move/move-compiler-v2/tests/simplifier-elimination/assert_false_with_resource.exp @@ -48,11 +48,15 @@ module 0x8675309::M { struct R1 has key { x: M1::R, } - fun f(a: address): M1::R { + fun f(a: address): M1::R + acquires R1 + { let r = borrow_global_mut>(a); M1::extract(&mut r.x, 3) } - public fun t0(a: address): M1::R { + public fun t0(a: address): M1::R + acquires R1 + { if (false) () else abort 0; f(a) } diff --git a/third_party/move/move-compiler-v2/tests/testsuite.rs b/third_party/move/move-compiler-v2/tests/testsuite.rs index 6d178306c34..c5ec4056f4d 100644 --- a/third_party/move/move-compiler-v2/tests/testsuite.rs +++ b/third_party/move/move-compiler-v2/tests/testsuite.rs @@ -211,16 +211,8 @@ const TEST_CONFIGS: Lazy> = Lazy::new(|| { dump_ast: DumpLevel::EndStage, ..config().lang(LanguageVersion::V2_2) }, - // Tests for checking v2 language features only supported if 2.3 or later + // Tests for checking v2 language features only supported if 2.4 or later // is selected - TestConfig { - name: "checking-lang-v2.5", - runner: |p| run_test(p, get_config_by_name("checking-lang-v2.5")), - include: vec!["/checking-lang-v2.5/"], - stop_after: StopAfter::FirstAstPipeline, - dump_ast: DumpLevel::EndStage, - ..config().lang(LanguageVersion::V2_5) - }, TestConfig { name: "checking-lang-v2.4", runner: |p| run_test(p, get_config_by_name("checking-lang-v2.4")), @@ -368,6 +360,15 @@ const TEST_CONFIGS: Lazy> = Lazy::new(|| { .exp_off(Experiment::OPTIMIZE) .exp_off(Experiment::OPTIMIZE_WAITING_FOR_COMPARE_TESTS) }, + // Focused regression tests for the legacy v2 reference safety processor. + TestConfig { + name: "reference-safety-v2", + runner: |p| run_test(p, get_config_by_name("reference-safety-v2")), + include: vec!["/reference-safety-v2/"], + ..config() + .lang(LanguageVersion::V2_1) + .exp_off(Experiment::REFERENCE_SAFETY_V3) + }, // Abort analysis tests TestConfig { name: "abort-analysis", diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/dynamic.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/dynamic.exp deleted file mode 100644 index 25fbdf414c4..00000000000 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/dynamic.exp +++ /dev/null @@ -1,27 +0,0 @@ -processed 6 tasks -task 0 lines 1-26: publish [module 0x42::test {] -task 1 lines 28-28: run --verbose --signers 0x1 -- 0x42::test::init -task 2 lines 30-30: run --verbose --args @0x1 -- 0x42::test::ok1 -return values: true -task 3 lines 32-32: run --verbose --signers 0x1 -- 0x42::test::ok2 -return values: true -task 4 lines 34-34: run --verbose --args @0x1 -- 0x42::test::fail1 -Error: Function execution failed with VMError: { - message: not allowed to perform `reads 0x42::test::R(@0x2)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(1), 1)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} -task 5 lines 36-36: run --verbose --signers 0x1 -- 0x42::test::fail2 -Error: Function execution failed with VMError: { - message: not allowed to perform `reads 0x42::test::R(@0x2)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(2), 3)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/dynamic.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/dynamic.move deleted file mode 100644 index 92b32a28be6..00000000000 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/dynamic.move +++ /dev/null @@ -1,36 +0,0 @@ -//# publish -module 0x42::test { - use 0x1::signer; - - struct R has key, drop { value: bool } - - fun init(s: &signer) { - move_to(s, R{value: true}); - } - - fun ok1(a: address): bool reads R(a) { - borrow_global(a).value - } - - fun ok2(s: &signer): bool reads R(signer::address_of(s)) { - borrow_global(signer::address_of(s)).value - } - - fun fail1(_a: address): bool reads R(_a) { - borrow_global(@0x2).value - } - - fun fail2(_s: &signer): bool reads R(signer::address_of(_s)) { - borrow_global(@0x2).value - } -} - -//# run --verbose --signers 0x1 -- 0x42::test::init - -//# run --verbose --args @0x1 -- 0x42::test::ok1 - -//# run --verbose --signers 0x1 -- 0x42::test::ok2 - -//# run --verbose --args @0x1 -- 0x42::test::fail1 - -//# run --verbose --signers 0x1 -- 0x42::test::fail2 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/generic.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/generic.exp deleted file mode 100644 index 295f72e0337..00000000000 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/generic.exp +++ /dev/null @@ -1,17 +0,0 @@ -processed 5 tasks -task 0 lines 1-21: publish [module 0x42::test {] -task 1 lines 23-23: run --verbose --signers 0x1 -- 0x42::test::init -task 2 lines 25-25: run --verbose -- 0x42::test::ok1 -return values: true -task 3 lines 27-27: run --verbose -- 0x42::test::ok2 -return values: true -task 4 lines 29-29: run --verbose -- 0x42::test::fail1 -Error: Function execution failed with VMError: { - message: not allowed to perform `reads 0x42::test::R(@0x1)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(1), 1)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/generic.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/generic.move deleted file mode 100644 index d786c362365..00000000000 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/generic.move +++ /dev/null @@ -1,29 +0,0 @@ -//# publish -module 0x42::test { - - struct R has key, drop { value: T } - - fun init(s: &signer) { - move_to(s, R{value: true}); - } - - fun ok1(): bool reads R { - borrow_global>(@0x1).value - } - - fun ok2(): bool reads R { - borrow_global>(@0x1).value - } - - fun fail1(): bool reads R { - borrow_global>(@0x1).value - } -} - -//# run --verbose --signers 0x1 -- 0x42::test::init - -//# run --verbose -- 0x42::test::ok1 - -//# run --verbose -- 0x42::test::ok2 - -//# run --verbose -- 0x42::test::fail1 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/negation.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/negation.exp deleted file mode 100644 index 7344c9b77fc..00000000000 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/negation.exp +++ /dev/null @@ -1,29 +0,0 @@ -processed 7 tasks -task 0 lines 1-28: publish [module 0x42::test {] -task 1 lines 30-30: run --verbose --signers 0x1 -- 0x42::test::init -task 2 lines 32-32: run --verbose -- 0x42::test::ok1 -return values: true -task 3 lines 34-34: run --verbose -- 0x42::test::ok2 -return values: true -task 4 lines 36-36: run --verbose -- 0x42::test::fail1 -Error: Function execution failed with VMError: { - message: not allowed to perform `reads 0x42::test::R(@0x1)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(1), 1)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} -task 5 lines 38-38: run --verbose -- 0x42::test::fail2 -Error: Function execution failed with VMError: { - message: not allowed to perform `reads 0x42::test::R(@0x1)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(2), 1)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} -task 6 lines 40-40: run --verbose -- 0x42::test::ok3 -return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/negation.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/negation.move deleted file mode 100644 index 71b2605d23a..00000000000 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/negation.move +++ /dev/null @@ -1,40 +0,0 @@ -//# publish -module 0x42::test { - struct R has key, drop { value: bool } - - fun init(s: &signer) { - move_to(s, R{value: true}); - } - - fun ok1(): bool reads 0x42::*::*, !reads 0x43::*::* { - borrow_global(@0x1).value - } - - fun ok2(): bool writes *, !reads 0x43::*::* { - borrow_global(@0x1).value - } - - fun fail1(): bool !reads 0x42::*::* { - borrow_global(@0x1).value - } - - fun fail2(): bool !reads *(0x1) { - borrow_global(@0x1).value - } - - fun ok3(): bool !reads *(0x2) { - borrow_global(@0x1).value - } -} - -//# run --verbose --signers 0x1 -- 0x42::test::init - -//# run --verbose -- 0x42::test::ok1 - -//# run --verbose -- 0x42::test::ok2 - -//# run --verbose -- 0x42::test::fail1 - -//# run --verbose -- 0x42::test::fail2 - -//# run --verbose -- 0x42::test::ok3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/resource.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/resource.exp deleted file mode 100644 index 6c20ae9728c..00000000000 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/resource.exp +++ /dev/null @@ -1,61 +0,0 @@ -processed 11 tasks -task 0 lines 1-53: publish [module 0x42::test {] -task 1 lines 55-55: run --verbose --signers 0x1 -- 0x42::test::init -task 2 lines 57-57: run --verbose -- 0x42::test::ok1 -return values: true -task 3 lines 59-59: run --verbose -- 0x42::test::ok2 -return values: true -task 4 lines 61-61: run --verbose --signers 0x2 -- 0x42::test::ok3 -return values: true -task 5 lines 63-63: run --verbose -- 0x42::test::ok4 -return values: true -task 6 lines 65-65: run --verbose -- 0x42::test::fail1 -Error: Function execution failed with VMError: { - message: not allowed to perform `reads 0x42::test::R(@0x1)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(1), 1)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} -task 7 lines 67-67: run --verbose -- 0x42::test::fail2 -Error: Function execution failed with VMError: { - message: not allowed to perform `reads 0x42::test::R(@0x1)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(2), 1)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} -task 8 lines 69-69: run --verbose -- 0x42::test::fail3 -Error: Function execution failed with VMError: { - message: not allowed to perform `writes 0x42::test::R(@0x1)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(3), 1)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} -task 9 lines 71-71: run --verbose -- 0x42::test::fail4 -Error: Function execution failed with VMError: { - message: not allowed to perform `writes 0x42::test::R(@0x1)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(4), 2)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} -task 10 lines 73-73: run --verbose -- 0x42::test::fail5 -Error: Function execution failed with VMError: { - message: not allowed to perform `reads 0x42::test::R(@0x1)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(6), 1)], - exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 0000000000000000000000000000000000000000000000000000000000000042, name: Identifier("test") }), FunctionDefinitionIndex(5), 0)] }), -} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/resource.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/resource.move deleted file mode 100644 index ca2c738b5af..00000000000 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/resource.move +++ /dev/null @@ -1,73 +0,0 @@ -//# publish -module 0x42::test { - struct R has key, drop { value: bool } - struct Other has key, drop {} - - fun init(s: &signer) { - move_to(s, R{value: true}); - } - - fun ok1(): bool reads R { - borrow_global(@0x1).value - } - - fun ok2(): bool reads R { - exists(@0x1) - } - - fun ok3(s: &signer): bool writes R { - move_to(s, R{value: true}); - true - } - - fun ok4(): bool writes R { - borrow_global_mut(@0x1).value = false; - true - } - - fun fail1(): bool reads Other { - !borrow_global(@0x1).value - } - - fun fail2(): bool reads Other { - !exists(@0x1) - } - - fun fail3(): bool reads R writes Other { - let r = move_from(@0x1); - !r.value - } - - fun fail4(): bool reads R writes Other { - borrow_global_mut(@0x1).value = false; - false - } - - fun fail5(): bool reads Other { - fail_no_subsumes() - } - - fun fail_no_subsumes(): bool reads R { - borrow_global(@0x1).value - } -} - -//# run --verbose --signers 0x1 -- 0x42::test::init - -//# run --verbose -- 0x42::test::ok1 - -//# run --verbose -- 0x42::test::ok2 - -//# run --verbose --signers 0x2 -- 0x42::test::ok3 - -//# run --verbose -- 0x42::test::ok4 - -//# run --verbose -- 0x42::test::fail1 - -//# run --verbose -- 0x42::test::fail2 - -//# run --verbose -- 0x42::test::fail3 - -//# run --verbose -- 0x42::test::fail4 - -//# run --verbose -- 0x42::test::fail5 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/dynamic.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/dynamic.decompiled deleted file mode 100644 index ac48e90f04a..00000000000 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/dynamic.decompiled +++ /dev/null @@ -1,49 +0,0 @@ -//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/access_control/dynamic.move` - -//# publish -module 0x42::test { - use 0x1::signer; - struct R has drop, key { - value: bool, - } - fun init(p0: &signer) { - let _v0 = R{value: true}; - move_to(p0, _v0); - } - fun fail1(p0: address): bool - acquires R - reads R(p0) - { - *&borrow_global(@0x2).value - } - fun fail2(p0: &signer): bool - acquires R - reads R(signer::address_of(p0)) - { - *&borrow_global(@0x2).value - } - fun ok1(p0: address): bool - acquires R - reads R(p0) - { - *&borrow_global(p0).value - } - fun ok2(p0: &signer): bool - acquires R - reads R(signer::address_of(p0)) - { - let _v0 = signer::address_of(p0); - *&borrow_global(_v0).value - } -} - - -//# run --verbose --signers 0x1 -- 0x42::test::init - -//# run --verbose --args @0x1 -- 0x42::test::ok1 - -//# run --verbose --signers 0x1 -- 0x42::test::ok2 - -//# run --verbose --args @0x1 -- 0x42::test::fail1 - -//# run --verbose --signers 0x1 -- 0x42::test::fail2 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/dynamic.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/dynamic.decompiled.baseline.exp deleted file mode 100644 index 1a5f6e1e21d..00000000000 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/dynamic.decompiled.baseline.exp +++ /dev/null @@ -1,40 +0,0 @@ -processed 6 tasks -task 0 lines 3-38: publish [module 0x42::test {] -warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` - ┌─ TEMPFILE:13:15 - │ -13 │ fun fail1(p0: address): bool - │ ^^ - -warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` - ┌─ TEMPFILE:19:15 - │ -19 │ fun fail2(p0: &signer): bool - │ ^^ - - -task 1 lines 41-41: run --verbose --signers 0x1 -- 0x42::test::init -task 2 lines 43-43: run --verbose --args @0x1 -- 0x42::test::ok1 -return values: true -task 3 lines 45-45: run --verbose --signers 0x1 -- 0x42::test::ok2 -return values: true -task 4 lines 47-47: run --verbose --args @0x1 -- 0x42::test::fail1 -Error: Function execution failed with VMError: { - message: not allowed to perform `reads 0x42::test::R(@0x2)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(1), 1)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} -task 5 lines 49-49: run --verbose --signers 0x1 -- 0x42::test::fail2 -Error: Function execution failed with VMError: { - message: not allowed to perform `reads 0x42::test::R(@0x2)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(2), 3)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/generic.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/generic.decompiled deleted file mode 100644 index 002da2e21b1..00000000000 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/generic.decompiled +++ /dev/null @@ -1,39 +0,0 @@ -//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/access_control/generic.move` - -//# publish -module 0x42::test { - struct R has drop, key { - value: T0, - } - fun init(p0: &signer) { - let _v0 = R{value: true}; - move_to>(p0, _v0); - } - fun fail1(): bool - acquires R - reads R - { - *&borrow_global>(@0x1).value - } - fun ok1(): bool - acquires R - reads R - { - *&borrow_global>(@0x1).value - } - fun ok2(): bool - acquires R - reads R - { - *&borrow_global>(@0x1).value - } -} - - -//# run --verbose --signers 0x1 -- 0x42::test::init - -//# run --verbose -- 0x42::test::ok1 - -//# run --verbose -- 0x42::test::ok2 - -//# run --verbose -- 0x42::test::fail1 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/generic.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/generic.decompiled.baseline.exp deleted file mode 100644 index 3bcb3987396..00000000000 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/generic.decompiled.baseline.exp +++ /dev/null @@ -1,17 +0,0 @@ -processed 5 tasks -task 0 lines 3-30: publish [module 0x42::test {] -task 1 lines 33-33: run --verbose --signers 0x1 -- 0x42::test::init -task 2 lines 35-35: run --verbose -- 0x42::test::ok1 -return values: true -task 3 lines 37-37: run --verbose -- 0x42::test::ok2 -return values: true -task 4 lines 39-39: run --verbose -- 0x42::test::fail1 -Error: Function execution failed with VMError: { - message: not allowed to perform `reads 0x42::test::R(@0x1)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(1), 1)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/negation.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/negation.decompiled deleted file mode 100644 index 9f0ceebdd50..00000000000 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/negation.decompiled +++ /dev/null @@ -1,57 +0,0 @@ -//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/access_control/negation.move` - -//# publish -module 0x42::test { - struct R has drop, key { - value: bool, - } - fun init(p0: &signer) { - let _v0 = R{value: true}; - move_to(p0, _v0); - } - fun fail1(): bool - !reads 0x42::*::* - acquires R - { - *&borrow_global(@0x1).value - } - fun fail2(): bool - !reads *(0x1) - acquires R - { - *&borrow_global(@0x1).value - } - fun ok1(): bool - !reads 0x43::*::* - acquires R - reads 0x42::*::* - { - *&borrow_global(@0x1).value - } - fun ok2(): bool - !reads 0x43::*::* - acquires R - writes * - { - *&borrow_global(@0x1).value - } - fun ok3(): bool - !reads *(0x2) - acquires R - { - *&borrow_global(@0x1).value - } -} - - -//# run --verbose --signers 0x1 -- 0x42::test::init - -//# run --verbose -- 0x42::test::ok1 - -//# run --verbose -- 0x42::test::ok2 - -//# run --verbose -- 0x42::test::fail1 - -//# run --verbose -- 0x42::test::fail2 - -//# run --verbose -- 0x42::test::ok3 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/negation.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/negation.decompiled.baseline.exp deleted file mode 100644 index 599eb255a4c..00000000000 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/negation.decompiled.baseline.exp +++ /dev/null @@ -1,29 +0,0 @@ -processed 7 tasks -task 0 lines 3-44: publish [module 0x42::test {] -task 1 lines 47-47: run --verbose --signers 0x1 -- 0x42::test::init -task 2 lines 49-49: run --verbose -- 0x42::test::ok1 -return values: true -task 3 lines 51-51: run --verbose -- 0x42::test::ok2 -return values: true -task 4 lines 53-53: run --verbose -- 0x42::test::fail1 -Error: Function execution failed with VMError: { - message: not allowed to perform `reads 0x42::test::R(@0x1)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(1), 1)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} -task 5 lines 55-55: run --verbose -- 0x42::test::fail2 -Error: Function execution failed with VMError: { - message: not allowed to perform `reads 0x42::test::R(@0x1)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(2), 1)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} -task 6 lines 57-57: run --verbose -- 0x42::test::ok3 -return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/resource.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/resource.decompiled deleted file mode 100644 index 1ca66d85205..00000000000 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/resource.decompiled +++ /dev/null @@ -1,101 +0,0 @@ -//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/access_control/resource.move` - -//# publish -module 0x42::test { - struct Other has drop, key { - } - struct R has drop, key { - value: bool, - } - fun init(p0: &signer) { - let _v0 = R{value: true}; - move_to(p0, _v0); - } - fun fail1(): bool - acquires R - reads Other - { - !*&borrow_global(@0x1).value - } - fun fail2(): bool - reads Other - { - !exists(@0x1) - } - fun fail3(): bool - acquires R - reads R - writes Other - { - let _v0 = move_from(@0x1); - !*&(&_v0).value - } - fun fail4(): bool - acquires R - reads R - writes Other - { - let _v0 = &mut borrow_global_mut(@0x1).value; - *_v0 = false; - false - } - fun fail5(): bool - acquires R - reads Other - { - fail_no_subsumes() - } - fun fail_no_subsumes(): bool - acquires R - reads R - { - *&borrow_global(@0x1).value - } - fun ok1(): bool - acquires R - reads R - { - *&borrow_global(@0x1).value - } - fun ok2(): bool - reads R - { - exists(@0x1) - } - fun ok3(p0: &signer): bool - writes R - { - let _v0 = R{value: true}; - move_to(p0, _v0); - true - } - fun ok4(): bool - acquires R - writes R - { - let _v0 = &mut borrow_global_mut(@0x1).value; - *_v0 = false; - true - } -} - - -//# run --verbose --signers 0x1 -- 0x42::test::init - -//# run --verbose -- 0x42::test::ok1 - -//# run --verbose -- 0x42::test::ok2 - -//# run --verbose --signers 0x2 -- 0x42::test::ok3 - -//# run --verbose -- 0x42::test::ok4 - -//# run --verbose -- 0x42::test::fail1 - -//# run --verbose -- 0x42::test::fail2 - -//# run --verbose -- 0x42::test::fail3 - -//# run --verbose -- 0x42::test::fail4 - -//# run --verbose -- 0x42::test::fail5 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/resource.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/resource.decompiled.baseline.exp deleted file mode 100644 index 1ff88eb01bc..00000000000 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/resource.decompiled.baseline.exp +++ /dev/null @@ -1,61 +0,0 @@ -processed 11 tasks -task 0 lines 3-80: publish [module 0x42::test {] -task 1 lines 83-83: run --verbose --signers 0x1 -- 0x42::test::init -task 2 lines 85-85: run --verbose -- 0x42::test::ok1 -return values: true -task 3 lines 87-87: run --verbose -- 0x42::test::ok2 -return values: true -task 4 lines 89-89: run --verbose --signers 0x2 -- 0x42::test::ok3 -return values: true -task 5 lines 91-91: run --verbose -- 0x42::test::ok4 -return values: true -task 6 lines 93-93: run --verbose -- 0x42::test::fail1 -Error: Function execution failed with VMError: { - message: not allowed to perform `reads 0x42::test::R(@0x1)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(1), 1)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} -task 7 lines 95-95: run --verbose -- 0x42::test::fail2 -Error: Function execution failed with VMError: { - message: not allowed to perform `reads 0x42::test::R(@0x1)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(2), 1)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} -task 8 lines 97-97: run --verbose -- 0x42::test::fail3 -Error: Function execution failed with VMError: { - message: not allowed to perform `writes 0x42::test::R(@0x1)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(3), 1)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} -task 9 lines 99-99: run --verbose -- 0x42::test::fail4 -Error: Function execution failed with VMError: { - message: not allowed to perform `writes 0x42::test::R(@0x1)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(4), 1)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} -task 10 lines 101-101: run --verbose -- 0x42::test::fail5 -Error: Function execution failed with VMError: { - message: not allowed to perform `reads 0x42::test::R(@0x1)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(6), 1)], - exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 0000000000000000000000000000000000000000000000000000000000000042, name: Identifier("test") }), FunctionDefinitionIndex(5), 0)] }), -} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/wildcard.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/wildcard.decompiled deleted file mode 100644 index 4ec5876fc03..00000000000 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/wildcard.decompiled +++ /dev/null @@ -1,63 +0,0 @@ -//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/access_control/wildcard.move` - -//# publish -module 0x42::test { - struct R has drop, key { - value: bool, - } - fun init(p0: &signer) { - let _v0 = R{value: true}; - move_to(p0, _v0); - } - fun fail1(): bool - acquires R - reads 0x43::*::* - { - *&borrow_global(@0x1).value - } - fun fail2(): bool - acquires R - reads *(0x2) - { - *&borrow_global(@0x1).value - } - fun ok1(): bool - acquires R - reads 0x42::*::* - { - *&borrow_global(@0x1).value - } - fun ok2(): bool - acquires R - reads 0x42::test::* - { - *&borrow_global(@0x1).value - } - fun ok3(): bool - acquires R - reads 0x42::test::* - { - *&borrow_global(@0x1).value - } - fun ok4(): bool - acquires R - reads *(0x1) - { - *&borrow_global(@0x1).value - } -} - - -//# run --verbose --signers 0x1 -- 0x42::test::init - -//# run --verbose -- 0x42::test::ok1 - -//# run --verbose -- 0x42::test::ok2 - -//# run --verbose -- 0x42::test::ok3 - -//# run --verbose -- 0x42::test::ok4 - -//# run --verbose -- 0x42::test::fail1 - -//# run --verbose -- 0x42::test::fail2 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/wildcard.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/wildcard.decompiled.baseline.exp deleted file mode 100644 index 80ac63589a2..00000000000 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/wildcard.decompiled.baseline.exp +++ /dev/null @@ -1,31 +0,0 @@ -processed 8 tasks -task 0 lines 3-48: publish [module 0x42::test {] -task 1 lines 51-51: run --verbose --signers 0x1 -- 0x42::test::init -task 2 lines 53-53: run --verbose -- 0x42::test::ok1 -return values: true -task 3 lines 55-55: run --verbose -- 0x42::test::ok2 -return values: true -task 4 lines 57-57: run --verbose -- 0x42::test::ok3 -return values: true -task 5 lines 59-59: run --verbose -- 0x42::test::ok4 -return values: true -task 6 lines 61-61: run --verbose -- 0x42::test::fail1 -Error: Function execution failed with VMError: { - message: not allowed to perform `reads 0x42::test::R(@0x1)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(1), 1)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} -task 7 lines 63-63: run --verbose -- 0x42::test::fail2 -Error: Function execution failed with VMError: { - message: not allowed to perform `reads 0x42::test::R(@0x1)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(2), 1)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/wildcard.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/wildcard.exp deleted file mode 100644 index 0043e3bf3ab..00000000000 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/wildcard.exp +++ /dev/null @@ -1,31 +0,0 @@ -processed 8 tasks -task 0 lines 1-32: publish [module 0x42::test {] -task 1 lines 34-34: run --verbose --signers 0x1 -- 0x42::test::init -task 2 lines 36-36: run --verbose -- 0x42::test::ok1 -return values: true -task 3 lines 38-38: run --verbose -- 0x42::test::ok2 -return values: true -task 4 lines 40-40: run --verbose -- 0x42::test::ok3 -return values: true -task 5 lines 42-42: run --verbose -- 0x42::test::ok4 -return values: true -task 6 lines 44-44: run --verbose -- 0x42::test::fail1 -Error: Function execution failed with VMError: { - message: not allowed to perform `reads 0x42::test::R(@0x1)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(1), 1)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} -task 7 lines 46-46: run --verbose -- 0x42::test::fail2 -Error: Function execution failed with VMError: { - message: not allowed to perform `reads 0x42::test::R(@0x1)`, - major_status: ACCESS_DENIED, - sub_status: None, - location: 0x42::test, - indices: [], - offsets: [(FunctionDefinitionIndex(2), 1)], - exec_state: Some(ExecutionState { stack_trace: [] }), -} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/wildcard.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/wildcard.move deleted file mode 100644 index 7078634a6c4..00000000000 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/wildcard.move +++ /dev/null @@ -1,46 +0,0 @@ -//# publish -module 0x42::test { - struct R has key, drop { value: bool } - - fun init(s: &signer) { - move_to(s, R{value: true}); - } - - fun ok1(): bool reads 0x42::*::* { - borrow_global(@0x1).value - } - - fun ok2(): bool reads 0x42::test::* { - borrow_global(@0x1).value - } - - fun ok3(): bool reads 0x42::test::*(*) { - borrow_global(@0x1).value - } - - fun ok4(): bool reads *(0x1) { - borrow_global(@0x1).value - } - - fun fail1(): bool reads 0x43::*::* { - borrow_global(@0x1).value - } - - fun fail2(): bool reads *(0x2) { - borrow_global(@0x1).value - } -} - -//# run --verbose --signers 0x1 -- 0x42::test::init - -//# run --verbose -- 0x42::test::ok1 - -//# run --verbose -- 0x42::test::ok2 - -//# run --verbose -- 0x42::test::ok3 - -//# run --verbose -- 0x42::test::ok4 - -//# run --verbose -- 0x42::test::fail1 - -//# run --verbose -- 0x42::test::fail2 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs b/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs index b3a0c226aa4..b06bba912c6 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs @@ -57,7 +57,7 @@ const TEST_CONFIGS: &[TestConfig] = &[ exclude: COMMON_EXCLUSIONS, cross_compile: true, }, - // Test optimize/no-optimize/etc., except for `/access_control/` + // Test optimize/no-optimize/etc. TestConfig { name: "optimize", runner: |p| run(p, get_config_by_name("optimize")), diff --git a/third_party/move/move-model/src/ast.rs b/third_party/move/move-model/src/ast.rs index 91c38baedf5..a743fd164da 100644 --- a/third_party/move/move-model/src/ast.rs +++ b/third_party/move/move-model/src/ast.rs @@ -513,60 +513,6 @@ pub struct FriendDecl { pub module_id: Option, } -// ================================================================================================= -/// # Access Specifiers - -/// Access specifier -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct AccessSpecifier { - pub loc: Loc, - pub kind: AccessSpecifierKind, - pub negated: bool, - pub resource: (Loc, ResourceSpecifier), - pub address: (Loc, AddressSpecifier), -} - -impl AccessSpecifier { - pub fn used_vars(&self) -> Vec { - match &self.address.1 { - AddressSpecifier::Call(_, var) | AddressSpecifier::Parameter(var) => { - vec![*var] - }, - _ => vec![], - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub enum AccessSpecifierKind { - Reads, - Writes, - LegacyAcquires, -} - -impl AccessSpecifierKind { - pub fn subsumes(&self, other: &Self) -> bool { - use AccessSpecifierKind::*; - matches!((self, other), (_, Reads) | (Writes, Writes)) - } -} - -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub enum ResourceSpecifier { - Any, - DeclaredAtAddress(Address), - DeclaredInModule(ModuleId), - Resource(QualifiedInstId), -} - -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub enum AddressSpecifier { - Any, - Address(Address), - Parameter(Symbol), - Call(QualifiedInstId, Symbol), -} - #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Copy, Hash, Default)] pub enum LambdaCaptureKind { /// No modifier (e.g., inlining) @@ -592,54 +538,6 @@ impl fmt::Display for LambdaCaptureKind { } } -impl ResourceSpecifier { - /// Checks whether this resource specifier matches the given struct. A function - /// instantiation is passed to instantiate the specifier in the calling context - /// of the function where it is declared for. - pub fn matches( - &self, - env: &GlobalEnv, - fun_inst: &[Type], - struct_id: &QualifiedInstId, - ) -> bool { - use ResourceSpecifier::*; - let struct_env = env.get_struct(struct_id.to_qualified_id()); - match self { - Any => true, - DeclaredAtAddress(addr) => struct_env.module_env.get_name().addr() == addr, - DeclaredInModule(mod_id) => struct_env.module_env.get_id() == *mod_id, - Resource(spec_struct_id) => { - // Since this resource specifier is declared for a specific function, - // need to instantiate it with the function instantiation. - let spec_struct_id = spec_struct_id.clone().instantiate(fun_inst); - struct_id.to_qualified_id() == spec_struct_id.to_qualified_id() - // If the specified instance has no parameters, every type instance is - // allowed, otherwise only the given one. - && (spec_struct_id.inst.is_empty() || spec_struct_id.inst == struct_id.inst) - }, - } - } - - /// Matches an unqualified struct name. This matches any resource pattern with that name, - /// regardless of type instantiation. - pub fn matches_modulo_type_instantiation( - &self, - env: &GlobalEnv, - struct_id: &QualifiedId, - ) -> bool { - use ResourceSpecifier::*; - let struct_id = struct_id.instantiate(vec![]); - match self { - Resource(spec_struct_id) => Resource( - // Downgrade to a pattern without instantiation - spec_struct_id.to_qualified_id().instantiate(vec![]), - ) - .matches(env, &[], &struct_id), - _ => self.matches(env, &[], &struct_id), - } - } -} - // ================================================================================================= /// # Expressions @@ -3891,16 +3789,6 @@ fn optional_variant_suffix(pool: &SymbolPool, variant: &Option) -> Strin } } -impl fmt::Display for AccessSpecifierKind { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - match self { - AccessSpecifierKind::Reads => f.write_str("reads"), - AccessSpecifierKind::Writes => f.write_str("writes"), - AccessSpecifierKind::LegacyAcquires => f.write_str("acquires"), - } - } -} - #[cfg(test)] mod tests { use crate::{ diff --git a/third_party/move/move-model/src/builder/binary_module_loader.rs b/third_party/move/move-model/src/builder/binary_module_loader.rs index 607f3319a8b..aea6b6772de 100644 --- a/third_party/move/move-model/src/builder/binary_module_loader.rs +++ b/third_party/move/move-model/src/builder/binary_module_loader.rs @@ -6,11 +6,7 @@ //! scripts (`CompiledScript`) to the global env. use crate::{ - ast::{ - AccessSpecifier as ASTAccessSpecifier, AccessSpecifierKind as ASTAccessSpecifierKind, - Address, AddressSpecifier as ASTAddressSpecifier, Attribute, ModuleName, - ResourceSpecifier as ASTResourceSpecifier, - }, + ast::{Address, Attribute, ModuleName}, model::{ FieldData, FieldId, FunId, FunctionData, FunctionKind, GlobalEnv, Loc, ModuleData, ModuleId, MoveIrLoc, Parameter, StructData, StructId, StructVariant, TypeParameter, @@ -24,10 +20,9 @@ use itertools::Itertools; use move_binary_format::{ access::ModuleAccess, file_format::{ - AccessKind as FFAccessKind, AddressSpecifier as FFAddressSpecifier, FunctionAttribute, - FunctionDefinitionIndex, FunctionHandleIndex, MemberCount, - ResourceSpecifier as FFResourceSpecifier, SignatureToken, StructDefinitionIndex, - StructHandleIndex, TableIndex, VariantIndex, Visibility, + FunctionAttribute, FunctionDefinitionIndex, FunctionHandleIndex, MemberCount, + SignatureToken, StructDefinitionIndex, StructHandleIndex, TableIndex, VariantIndex, + Visibility, }, internals::ModuleIndex, views::{ @@ -38,20 +33,7 @@ use move_binary_format::{ }; use move_bytecode_source_map::source_map::{SourceMap, SourceName}; use move_core_types::{ability::AbilitySet, account_address::AccountAddress, language_storage}; -use std::collections::BTreeMap; - -/// Macro to abort the execution if `with_dep_closure` is specified while dependencies are missing. -macro_rules! abort_if_missing { - ($with_dep_closure:expr) => { - if $with_dep_closure { - panic!("Malformed bytecode or module loader bug. Please report this."); - } else { - // This should not be reached since no existing code sets `with_dep_closure` to `false`. - // Adding an alert in case things change in the future. - unimplemented!("[TODO #17414]"); - } - }; -} +use std::collections::{BTreeMap, BTreeSet}; impl GlobalEnv { /// Loads the compiled module into the environment. If the module already exists, @@ -423,23 +405,9 @@ impl<'a> BinaryModuleLoader<'a> { let result_type = Type::tuple(handle_view.return_().0.iter().map(|s| self.ty(s)).collect()); - // Convert access specifiers from file format to AST format - let rw_specifiers = self.rw_specifiers(&handle_view, ¶ms); - let acquire_specifiers = if let Some((_, def_view)) = def_view.clone() { - self.acquire_specifiers(&def_view) - } else { - None - }; - // Combine read/write and acquire specifiers. - let access_specifiers = rw_specifiers - .clone() - .zip(acquire_specifiers.clone()) - .map(|(mut rw, acquire)| { - rw.extend(acquire); - rw - }) - .or(rw_specifiers) - .or(acquire_specifiers); + let acquired_structs = def_view + .as_ref() + .map(|(_, def_view)| self.acquired_structs(def_view)); let (visibility, is_native, kind) = if let Some((_, def_view)) = def_view { ( @@ -509,7 +477,7 @@ impl<'a> BinaryModuleLoader<'a> { // to definition, like locations. fun_data.type_params = type_params; fun_data.params = params; - fun_data.access_specifiers = access_specifiers; + fun_data.acquired_structs = acquired_structs; fun_data.result_type = result_type; } @@ -522,180 +490,21 @@ impl<'a> BinaryModuleLoader<'a> { } } - fn rw_specifiers( - &self, - handle_view: &FunctionHandleView, - params: &[Parameter], - ) -> Option> { - let ff_access_specifiers = handle_view.access_specifiers()?; - let mut access_specifiers = Vec::new(); - let ff_module = handle_view.module(); - - // Helper function mapping a file format `ModuleId` to a `ModuleEnv` in move model - let ff_mid_to_module_env = |ff_mid: language_storage::ModuleId| { - let mname = self.env.to_module_name(&ff_mid); - self.env - .find_module(&mname) - .unwrap_or_else(|| abort_if_missing!(self.with_dep_closure)) - }; - - for ff_acc_spec in ff_access_specifiers { - let spec_kind = match ff_acc_spec.kind { - FFAccessKind::Reads => ASTAccessSpecifierKind::Reads, - FFAccessKind::Writes => ASTAccessSpecifierKind::Writes, - }; - let spec_negated = ff_acc_spec.negated; - let resource_spec = match ff_acc_spec.resource { - FFResourceSpecifier::Any => ASTResourceSpecifier::Any, - FFResourceSpecifier::DeclaredAtAddress(addr_idx) => { - let acct_addr = ff_module.address_identifier_at(addr_idx); - ASTResourceSpecifier::DeclaredAtAddress(Address::Numerical(*acct_addr)) - }, - FFResourceSpecifier::DeclaredInModule(mhid) => { - // ModuleHandleIndex -> ModuleHandle -> File format ModuleId - let ff_mhandle = ff_module.module_handle_at(mhid); - let ff_mid = ff_module.module_id_for_handle(ff_mhandle); - // File format ModuleId -> ModuleEnv in move model - let module_env = ff_mid_to_module_env(ff_mid); - ASTResourceSpecifier::DeclaredInModule(module_env.get_id()) - }, - FFResourceSpecifier::Resource(shid) => { - // StructHandleIndex -> StructHandle -> ModuleHandle -> File format ModuleId - let ff_shandle = ff_module.struct_handle_at(shid); - let ff_mhandle = ff_module.module_handle_at(ff_shandle.module); - let ff_mid = ff_module.module_id_for_handle(ff_mhandle); - // StructHandle -> struct name -> StructId in move model - let sname = ff_module.identifier_at(ff_shandle.name); - let struct_id = StructId::new(self.sym(sname.as_str())); - // File format ModuleId -> ModuleEnv in move model -> StructEnv in move model - let module_env = ff_mid_to_module_env(ff_mid); - let struct_env = self - .env - .get_struct_opt(module_env.get_id().qualified(struct_id)) - .unwrap_or_else(|| abort_if_missing!(self.with_dep_closure)); - ASTResourceSpecifier::Resource( - module_env - .get_id() - .qualified_inst(struct_env.get_id(), vec![]), - ) - }, - FFResourceSpecifier::ResourceInstantiation(shid, sig_idx) => { - // Process similar to `FFResourceSpecifier::Resource` - let ff_shandle = ff_module.struct_handle_at(shid); - let ff_mhandle = ff_module.module_handle_at(ff_shandle.module); - let ff_mid = ff_module.module_id_for_handle(ff_mhandle); - let sname = ff_module.identifier_at(ff_shandle.name); - let sig = ff_module.signature_at(sig_idx); - let type_args: Vec<_> = sig.0.iter().map(|arg| self.ty(arg)).collect(); - let struct_id = StructId::new(self.sym(sname.as_str())); - let module_env = ff_mid_to_module_env(ff_mid); - let struct_env = self - .env - .get_struct_opt(module_env.get_id().qualified(struct_id)) - .unwrap_or_else(|| abort_if_missing!(self.with_dep_closure)); - ASTResourceSpecifier::Resource( - module_env - .get_id() - .qualified_inst(struct_env.get_id(), type_args), - ) - }, - }; - let addr_spec = match ff_acc_spec.address { - FFAddressSpecifier::Any => ASTAddressSpecifier::Any, - FFAddressSpecifier::Literal(addr_idx) => { - let addr = Address::Numerical(*ff_module.address_identifier_at(addr_idx)); - ASTAddressSpecifier::Address(addr) - }, - FFAddressSpecifier::Parameter(param_idx, func_inst_inx) => { - if let Some(func_inst_idx) = func_inst_inx { - // FunctionInstantiationIndex -> FunctionInstantiation -> FunctionHandle -> ModuleHandle -> File format ModuleId - let ff_func_inst = ff_module.function_instantiation_at(func_inst_idx); - let ff_func_handle = ff_module.function_handle_at(ff_func_inst.handle); - let ff_mhandle = ff_module.module_handle_at(ff_func_handle.module); - let ff_mid = ff_module.module_id_for_handle(ff_mhandle); - // FunctionHandle -> function name -> FunId in move model - let fname = ff_module.identifier_at(ff_func_handle.name); - let fun_id = FunId::new(self.sym(fname.as_str())); - // File format ModuleId -> ModuleEnv in move model -> FunctionEnv in move model - let module_env = ff_mid_to_module_env(ff_mid); - let fun_env = self - .env - .get_function_opt(module_env.get_id().qualified(fun_id)) - .unwrap_or_else(|| abort_if_missing!(self.with_dep_closure)); - ASTAddressSpecifier::Call( - module_env - .get_id() - .qualified_inst(fun_env.get_id(), fun_env.get_parameter_types()), - params[param_idx as usize].0, - ) - } else { - ASTAddressSpecifier::Parameter(params[param_idx as usize].0) - } - }, - }; - let loc = Loc::default(); - let ast_access_specifier: ASTAccessSpecifier = ASTAccessSpecifier { - kind: spec_kind, - negated: spec_negated, - resource: (loc.clone(), resource_spec), - address: (loc.clone(), addr_spec), - loc, - }; - access_specifiers.push(ast_access_specifier); - } - Some(access_specifiers) - } - - fn acquire_specifiers( + fn acquired_structs( &self, def_view: &FunctionDefinitionView, - ) -> Option> { - let mut access_specifiers = Vec::new(); - let ff_module = def_view.module(); - let ff_acquires = def_view.acquired_resources(); - if ff_acquires.is_empty() { - return None; - } - for sdef_idx in def_view.acquired_resources() { - let spec_kind = ASTAccessSpecifierKind::LegacyAcquires; - let spec_negated = false; - let resource_spec = { - // StructDefinitionIndex -> StructHandleIndex -> StructHandle -> ModuleHandle -> File format ModuleId - let struct_hidx = ff_module.struct_def_at(*sdef_idx).struct_handle; - let struct_handle = ff_module.struct_handle_at(struct_hidx); - let mhandle = ff_module.module_handle_at(struct_handle.module); - let ff_mid = ff_module.module_id_for_handle(mhandle); - // StructHandle -> struct name -> StructId in move model - let sname = ff_module.identifier_at(struct_handle.name); - let struct_id = StructId::new(self.sym(sname.as_str())); - // File format ModuleId -> ModuleEnv in move model -> StructEnv in move model - let mname = self.env.to_module_name(&ff_mid); - let module_env = self - .env - .find_module(&mname) - .unwrap_or_else(|| abort_if_missing!(self.with_dep_closure)); - let struct_env = self - .env - .get_struct_opt(module_env.get_id().qualified(struct_id)) - .unwrap_or_else(|| abort_if_missing!(self.with_dep_closure)); - ASTResourceSpecifier::Resource( - module_env - .get_id() - .qualified_inst(struct_env.get_id(), vec![]), - ) - }; - let addr_spec = ASTAddressSpecifier::Any; - let loc = Loc::default(); - let ast_acquire_specifier: ASTAccessSpecifier = ASTAccessSpecifier { - kind: spec_kind, - negated: spec_negated, - resource: (loc.clone(), resource_spec), - address: (loc.clone(), addr_spec), - loc, - }; - access_specifiers.push(ast_acquire_specifier); - } - Some(access_specifiers) + ) -> BTreeSet { + let module = def_view.module(); + def_view + .acquired_resources() + .iter() + .map(|struct_def_idx| { + let struct_handle_idx = module.struct_def_at(*struct_def_idx).struct_handle; + let struct_handle = module.struct_handle_at(struct_handle_idx); + let name = module.identifier_at(struct_handle.name); + StructId::new(self.sym(name.as_str())) + }) + .collect() } fn ty(&self, sign: &SignatureToken) -> Type { diff --git a/third_party/move/move-model/src/builder/exp_builder.rs b/third_party/move/move-model/src/builder/exp_builder.rs index cac030872b8..0e1da8cf04c 100644 --- a/third_party/move/move-model/src/builder/exp_builder.rs +++ b/third_party/move/move-model/src/builder/exp_builder.rs @@ -4,9 +4,8 @@ use crate::{ ast::{ - AccessSpecifier, AccessSpecifierKind, Address, AddressSpecifier, Exp, ExpData, - LambdaCaptureKind, MatchArm, ModuleName, Operation, Pattern, QualifiedSymbol, QuantKind, - ResourceSpecifier, RewriteResult, Spec, TempIndex, Value, + Address, Exp, ExpData, LambdaCaptureKind, MatchArm, ModuleName, Operation, Pattern, + QualifiedSymbol, QuantKind, RewriteResult, Spec, TempIndex, Value, }, builder::{ model_builder::{ @@ -14,10 +13,7 @@ use crate::{ }, module_builder::{ModuleBuilder, SpecBlockContext}, }, - metadata::{ - lang_feature_versions::{LANGUAGE_VERSION_FOR_RAC, SINT_LANGUAGE_VERSION_VALUE}, - LanguageVersion, - }, + metadata::{lang_feature_versions::SINT_LANGUAGE_VERSION_VALUE, LanguageVersion}, model::{ FieldData, FieldId, FunctionKind, GlobalEnv, Loc, ModuleId, NodeId, Parameter, QualifiedId, QualifiedInstId, SpecFunId, StructId, TypeParameter, TypeParameterKind, @@ -1198,253 +1194,25 @@ impl ExpTranslator<'_, '_, '_> { } } -/// # Access Specifier Translation +/// # Acquires Translation impl ExpTranslator<'_, '_, '_> { - pub(crate) fn translate_access_specifiers( - &mut self, - specifiers: &Option>, - ) -> Option> { - specifiers.as_ref().map(|v| { - v.iter() - .filter_map(|s| self.translate_access_specifier(s)) - .collect() - }) - } - - fn translate_access_specifier( - &mut self, - specifier: &EA::AccessSpecifier, - ) -> Option { - fn is_wildcard(name: &Name) -> bool { - name.value.as_str() == "*" - } - - let loc = self.to_loc(&specifier.loc); - let EA::AccessSpecifier_ { - kind, - negated, - module_address, - module_name, - resource_name, - type_args, - address, - } = &specifier.value; - match kind { - EA::AccessSpecifierKind::LegacyAcquires => { - if *negated || type_args.is_some() || address.value != EA::AddressSpecifier_::Empty - { - self.error( - &loc, - "only simple resource names can be used with `acquires`", - ) - } - }, - EA::AccessSpecifierKind::Reads | EA::AccessSpecifierKind::Writes => { - self.check_language_version( - &loc, - "read/write access specifiers.", - LANGUAGE_VERSION_FOR_RAC, - )?; - }, - } - let resource = match (module_address, module_name, resource_name) { - (None, None, None) => { - // This stems from a specifier of the form `acquires *(0x1)` - ResourceSpecifier::Any - }, - (Some(address), None, None) => { - ResourceSpecifier::DeclaredAtAddress(self.translate_address(&loc, address)) - }, - (Some(address), Some(module), None) if is_wildcard(&module.0) => { - ResourceSpecifier::DeclaredAtAddress(self.translate_address(&loc, address)) - }, - (Some(address), Some(module), Some(resource)) - if is_wildcard(&module.0) && is_wildcard(resource) => - { - ResourceSpecifier::DeclaredAtAddress(self.translate_address(&loc, address)) - }, - (Some(address), Some(module), Some(resource)) if !is_wildcard(&module.0) => { - let module_name = ModuleName::new( - self.translate_address(&loc, address), - self.symbol_pool().make(module.0.value.as_str()), - ); - let module_id = if self.parent.module_name == module_name { - self.parent.module_id - } else if let Some(module_env) = self.env().find_module(&module_name) { - module_env.get_id() - } else { - self.error(&loc, &format!("undeclared module `{}`", module)); - self.parent.module_id - }; - if is_wildcard(resource) { - ResourceSpecifier::DeclaredInModule(module_id) - } else { - let mident = sp(specifier.loc, EA::ModuleIdent_ { - address: *address, - module: *module, - }); - let maccess = sp( - specifier.loc, - EA::ModuleAccess_::ModuleAccess(mident, *resource, None), - ); - let sym = self.parent.module_access_to_qualified(&maccess); - if let Type::Struct(mid, sid, _) = self.parent.parent.lookup_type(&loc, &sym) { - if type_args.is_none() { - // If no type args are provided, we assume this is either a non-generic - // or a generic type without instantiation, which is a valid wild card. - ResourceSpecifier::Resource(mid.qualified_inst(sid, vec![])) - } else { - // Otherwise construct an expansion type so we can feed it through the standard translation - // process. - let ety = sp( - specifier.loc, - EA::Type_::Apply( - maccess, - type_args.as_ref().cloned().unwrap_or_default(), - ), - ); - let ty = self.translate_type(&ety); - if let Type::Struct(mid, sid, inst) = ty { - ResourceSpecifier::Resource(mid.qualified_inst(sid, inst)) - } else { - // errors reported - debug_assert!(self.env().has_errors()); - ResourceSpecifier::Any - } - } - } else { - // error reported - ResourceSpecifier::Any - } - } - }, - (Some(_), Some(module), Some(resource)) - if is_wildcard(&module.0) && !is_wildcard(resource) => - { - self.error( - &loc, - "invalid access specifier: a wildcard \ - cannot be followed by a non-wildcard name component", - ); - ResourceSpecifier::Any - }, - _ => { - self.error(&loc, "invalid access specifier"); - ResourceSpecifier::Any - }, - }; - if !matches!(resource, ResourceSpecifier::Resource(..)) { - self.check_language_version( - &loc, - "address and wildcard access specifiers. Only resource type names can be provided.", - LanguageVersion::V2_0, - )?; - }; - let address = self.translate_address_specifier(address)?; - let kind = match kind { - EA::AccessSpecifierKind::Reads => AccessSpecifierKind::Reads, - EA::AccessSpecifierKind::Writes => AccessSpecifierKind::Writes, - EA::AccessSpecifierKind::LegacyAcquires => AccessSpecifierKind::LegacyAcquires, - }; - Some(AccessSpecifier { - loc: loc.clone(), - kind, - negated: *negated, - resource: (loc, resource), - address, - }) - } - - fn translate_address_specifier( + pub(crate) fn translate_acquires( &mut self, - specifier: &EA::AddressSpecifier, - ) -> Option<(Loc, AddressSpecifier)> { - let loc = self.to_loc(&specifier.loc); - let res = match &specifier.value { - EA::AddressSpecifier_::Empty => (loc, AddressSpecifier::Any), - EA::AddressSpecifier_::Any => { - self.check_language_version( - &loc, - "wildcard address specifiers", - LanguageVersion::V2_0, - )?; - (loc, AddressSpecifier::Any) - }, - EA::AddressSpecifier_::Literal(addr) => { - self.check_language_version( - &loc, - "literal address specifiers", - LanguageVersion::V2_0, - )?; - ( - loc, - AddressSpecifier::Address(Address::Numerical(addr.into_inner())), - ) - }, - EA::AddressSpecifier_::Name(name) => { - self.check_language_version( - &loc, - "named address specifiers", - LanguageVersion::V2_0, - )?; - // Construct an expansion name exp for regular type check - let maccess = sp(name.loc, EA::ModuleAccess_::Name(*name)); - self.translate_name( - &self.to_loc(&maccess.loc), - &maccess, - &None, - &Type::new_prim(PrimitiveType::Address), - &ErrorMessageContext::General, - ); - ( - loc, - AddressSpecifier::Parameter(self.symbol_pool().make(name.value.as_str())), - ) - }, - EA::AddressSpecifier_::Call(maccess, type_args, name) => { - self.check_language_version( - &loc, - "derived address specifiers", - LanguageVersion::V2_0, - )?; - // Construct an expansion function call for regular type check - let name_exp = sp( - name.loc, - EA::Exp_::Name(sp(name.loc, EA::ModuleAccess_::Name(*name)), None), - ); - if let ExpData::Call(id, Operation::MoveFunction(mid, fid), _) = self - .translate_fun_call( - &Type::new_prim(PrimitiveType::Address), - &loc, - CallKind::Regular, - maccess, - type_args, - &[&name_exp], - &ErrorMessageContext::Argument, - ) - { - let inst = self.env().get_node_instantiation(id); - ( - loc, - AddressSpecifier::Call( - mid.qualified_inst(fid, inst), - self.symbol_pool().make(name.value.as_str()), - ), - ) + acquires: &[EA::ModuleAccess], + ) -> Vec<(Loc, QualifiedId)> { + acquires + .iter() + .filter_map(|acquire| { + let loc = self.to_loc(&acquire.loc); + let sym = self.parent.module_access_to_qualified(acquire); + if let Type::Struct(mid, sid, _) = self.parent.parent.lookup_type(&loc, &sym) { + Some((loc, mid.qualified(sid))) } else { - // Error reported - debug_assert!(self.env().has_errors()); - (loc, AddressSpecifier::Any) + None } - }, - }; - Some(res) - } - - fn translate_address(&mut self, loc: &Loc, addr: &EA::Address) -> Address { - let x = self.parent.parent.resolve_address(loc, addr); - Address::Numerical(x.into_inner()) + }) + .collect() } } diff --git a/third_party/move/move-model/src/builder/module_builder.rs b/third_party/move/move-model/src/builder/module_builder.rs index c18b865040a..62b3f549d1c 100644 --- a/third_party/move/move-model/src/builder/module_builder.rs +++ b/third_party/move/move-model/src/builder/module_builder.rs @@ -4,10 +4,9 @@ use crate::{ ast::{ - AccessSpecifier, Address, Attribute, AttributeValue, Condition, ConditionKind, Exp, - ExpData, FriendDecl, ModuleName, Operation, Pattern, PropertyBag, PropertyValue, - QualifiedSymbol, Spec, SpecBlockInfo, SpecBlockTarget, SpecFunDecl, SpecVarDecl, TempIndex, - UseDecl, Value, + Address, Attribute, AttributeValue, Condition, ConditionKind, Exp, ExpData, FriendDecl, + ModuleName, Operation, Pattern, PropertyBag, PropertyValue, QualifiedSymbol, Spec, + SpecBlockInfo, SpecBlockTarget, SpecFunDecl, SpecVarDecl, TempIndex, UseDecl, Value, }, builder::{ exp_builder::ExpTranslator, @@ -22,8 +21,9 @@ use crate::{ metadata::lang_feature_versions::LANGUAGE_VERSION_FOR_PUBLIC_STRUCT, model::{ self, EqIgnoringLoc, FieldData, FieldId, FunId, FunctionData, FunctionKind, FunctionLoc, - Loc, ModuleId, MoveIrLoc, NamedConstantData, NamedConstantId, NodeId, Parameter, SchemaId, - SpecFunId, SpecVarId, StructData, StructId, TypeParameter, TypeParameterKind, + Loc, ModuleId, MoveIrLoc, NamedConstantData, NamedConstantId, NodeId, Parameter, + QualifiedId, SchemaId, SpecFunId, SpecVarId, StructData, StructId, TypeParameter, + TypeParameterKind, }, options::ModelBuilderOptions, pragmas::{ @@ -89,8 +89,8 @@ pub(crate) struct ModuleBuilder<'env, 'translator> { pub inline_spec_builder: Spec, /// Translated function definitions, if we are compiling Move code pub fun_defs: BTreeMap, - /// Translated access specifiers, if we are compiling Move code - pub fun_access_specifiers: BTreeMap>, + /// Translated legacy `acquires` annotations, if we are compiling Move code. + pub fun_declared_acquires: BTreeMap)>>, /// Translated struct specifications. pub struct_specs: BTreeMap, /// Translated module spec @@ -170,7 +170,7 @@ impl<'env, 'translator> ModuleBuilder<'env, 'translator> { spec_vars: vec![], fun_specs: BTreeMap::new(), fun_defs: BTreeMap::new(), - fun_access_specifiers: BTreeMap::new(), + fun_declared_acquires: BTreeMap::new(), struct_specs: BTreeMap::new(), module_spec: Spec::default(), spec_block_infos: Default::default(), @@ -1479,7 +1479,7 @@ impl ModuleBuilder<'_, '_> { et.define_local(loc, *n, ty.clone(), None, Some(idx)); } } - let access_specifiers = et.translate_access_specifiers(&def.access_specifiers); + let declared_acquires = et.translate_acquires(&def.acquires); let result = et.translate_seq(&loc, seq, &result_type, &ErrorMessageContext::Return); // Run type inference finalization so post processing has all available type information, // but do not report errors yet because receiver functions can add more type bindings. @@ -1490,10 +1490,10 @@ impl ModuleBuilder<'_, '_> { et.check_mutable_borrow_field(&translated); et.check_lambda_types(&translated); assert!(self.fun_defs.insert(full_name.symbol, translated).is_none()); - if let Some(specifiers) = access_specifiers { + if !declared_acquires.is_empty() { assert!(self - .fun_access_specifiers - .insert(full_name.symbol, specifiers) + .fun_declared_acquires + .insert(full_name.symbol, declared_acquires) .is_none()); } } @@ -3651,7 +3651,10 @@ impl ModuleBuilder<'_, '_> { let def = self.fun_defs.remove(&name.symbol); let called_funs = Some(def.as_ref().map(|e| e.called_funs()).unwrap_or_default()); let used_funs = Some(def.as_ref().map(|e| e.used_funs()).unwrap_or_default()); - let access_specifiers = self.fun_access_specifiers.remove(&name.symbol); + let declared_acquires = self + .fun_declared_acquires + .remove(&name.symbol) + .unwrap_or_default(); let fun_id = FunId::new(name.symbol); let data = FunctionData { name: name.symbol, @@ -3670,7 +3673,7 @@ impl ModuleBuilder<'_, '_> { type_params: entry.type_params.clone(), params: entry.params.clone(), result_type: entry.result_type.clone(), - access_specifiers, + declared_acquires, acquired_structs: None, spec: spec.into(), def, diff --git a/third_party/move/move-model/src/metadata.rs b/third_party/move/move-model/src/metadata.rs index 29a846fc4b0..2b138c51266 100644 --- a/third_party/move/move-model/src/metadata.rs +++ b/third_party/move/move-model/src/metadata.rs @@ -30,7 +30,6 @@ pub mod lang_feature_versions { pub const COMPILE_FOR_TESTING_VALUE: LanguageVersion = LanguageVersion::V2_2; pub const SINT_LANGUAGE_VERSION_VALUE: LanguageVersion = LanguageVersion::V2_3; pub const LANGUAGE_VERSION_FOR_PUBLIC_STRUCT: LanguageVersion = LanguageVersion::V2_4; - pub const LANGUAGE_VERSION_FOR_RAC: LanguageVersion = LanguageVersion::V2_5; } // ================================================================================' diff --git a/third_party/move/move-model/src/model.rs b/third_party/move/move-model/src/model.rs index 28b889af37a..4a89bd3835d 100644 --- a/third_party/move/move-model/src/model.rs +++ b/third_party/move/move-model/src/model.rs @@ -17,10 +17,9 @@ use crate::{ ast::{ - AccessSpecifier, AccessSpecifierKind, Address, AddressSpecifier, Attribute, ConditionKind, - Exp, ExpData, FriendDecl, GlobalInvariant, ModuleName, PropertyBag, PropertyValue, - ResourceSpecifier, Spec, SpecBlockInfo, SpecBlockTarget, SpecFunDecl, SpecVarDecl, UseDecl, - Value, + Address, Attribute, ConditionKind, Exp, ExpData, FriendDecl, GlobalInvariant, ModuleName, + PropertyBag, PropertyValue, Spec, SpecBlockInfo, SpecBlockTarget, SpecFunDecl, SpecVarDecl, + UseDecl, Value, }, code_writer::CodeWriter, emit, emitln, @@ -2127,7 +2126,7 @@ impl GlobalEnv { type_params, params, result_type, - access_specifiers: None, + declared_acquires: vec![], acquired_structs: None, spec: RefCell::new(spec_opt.unwrap_or_default()), def: Some(def), @@ -2194,7 +2193,7 @@ impl GlobalEnv { type_params, params, result_type, - access_specifiers: None, + declared_acquires: vec![], acquired_structs: None, spec: RefCell::new(spec_opt.unwrap_or_default()), def: Some(def), @@ -2867,51 +2866,15 @@ impl GlobalEnv { fn dump_fun_internal(&self, writer: &CodeWriter, tctx: &TypeDisplayContext, fun: &FunctionEnv) { emit!(writer, "{}", fun.get_header_string()); - if let Some(specs) = fun.get_access_specifiers() { + if !fun.get_declared_acquires().is_empty() { emitln!(writer); writer.indent(); - for spec in specs { - if spec.negated { - emit!(writer, "!") - } - match &spec.kind { - AccessSpecifierKind::Reads => emit!(writer, "reads "), - AccessSpecifierKind::Writes => emit!(writer, "writes "), - AccessSpecifierKind::LegacyAcquires => emit!(writer, "acquires "), - } - match &spec.resource.1 { - ResourceSpecifier::Any => emit!(writer, "*"), - ResourceSpecifier::DeclaredAtAddress(addr) => { - emit!( - writer, - "0x{}::*", - addr.expect_numerical().short_str_lossless() - ) - }, - ResourceSpecifier::DeclaredInModule(mid) => { - emit!(writer, "{}::*", self.get_module(*mid).get_full_name_str()) - }, - ResourceSpecifier::Resource(sid) => { - emit!(writer, "{}", sid.to_type().display(tctx)) - }, - } - emit!(writer, "("); - match &spec.address.1 { - AddressSpecifier::Any => emit!(writer, "*"), - AddressSpecifier::Address(addr) => { - emit!(writer, "0x{}", addr.expect_numerical().short_str_lossless()) - }, - AddressSpecifier::Parameter(sym) => { - emit!(writer, "{}", sym.display(self.symbol_pool())) - }, - AddressSpecifier::Call(fun, sym) => emit!( - writer, - "{}({})", - self.get_function(fun.to_qualified_id()).get_full_name_str(), - sym.display(self.symbol_pool()) - ), - } - emitln!(writer, ")") + for (_, acquired) in fun.get_declared_acquires() { + emitln!( + writer, + "acquires {}", + acquired.instantiate(vec![]).to_type().display(tctx) + ) } writer.unindent() } @@ -4522,8 +4485,8 @@ pub struct FunctionData { /// Result type of the function, uses `Type::Tuple` for multiple values. pub(crate) result_type: Type, - /// Access specifiers. - pub(crate) access_specifiers: Option>, + /// Resources declared in legacy `acquires` annotations, paired with their locations. + pub(crate) declared_acquires: Vec<(Loc, QualifiedId)>, /// Acquires information, if available. This is either inferred or annotated by the /// user via a legacy acquires declaration. @@ -4575,7 +4538,7 @@ impl FunctionData { type_params: vec![], params: vec![], result_type: Type::unit(), - access_specifiers: None, + declared_acquires: vec![], acquired_structs: None, spec: RefCell::new(Default::default()), def: None, @@ -5046,18 +5009,13 @@ impl<'env> FunctionEnv<'env> { } } - /// Returns the access specifiers of this function. - /// If this is `None`, all accesses are allowed. If the list is empty, - /// no accesses are allowed. Otherwise the list is divided into _inclusions_ and _exclusions_, - /// the later being negated specifiers. Access is allowed if (a) any of the inclusion - /// specifiers allows it (union of inclusion specifiers) (b) none of the exclusions - /// specifiers disallows it (intersection of exclusion specifiers). - pub fn get_access_specifiers(&self) -> Option<&[AccessSpecifier]> { - self.data.access_specifiers.as_deref() + /// Returns resources declared in legacy `acquires` annotations and their locations. + pub fn get_declared_acquires(&self) -> &[(Loc, QualifiedId)] { + &self.data.declared_acquires } - /// Returns the inferred acquired structs of this function. This is checked - /// against declared acquires from `get_access_specifiers`. + /// Returns the inferred acquired structs of this function. This is checked against + /// the annotations returned by `get_declared_acquires`. pub fn get_acquired_structs(&self) -> Option<&BTreeSet> { self.data.acquired_structs.as_ref() } diff --git a/third_party/move/move-model/src/sourcifier.rs b/third_party/move/move-model/src/sourcifier.rs index f88750f2614..75b12fe63bd 100644 --- a/third_party/move/move-model/src/sourcifier.rs +++ b/third_party/move/move-model/src/sourcifier.rs @@ -3,10 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - ast::{ - AccessSpecifierKind, AddressSpecifier, Exp, ExpData, LambdaCaptureKind, Operation, Pattern, - ResourceSpecifier, TempIndex, Value, - }, + ast::{Exp, ExpData, LambdaCaptureKind, Operation, Pattern, TempIndex, Value}, code_writer::CodeWriter, emit, emitln, exp_builder::ExpBuilder, @@ -157,11 +154,12 @@ impl<'a> Sourcifier<'a> { fun_env.get_result_type().display(&tctx) ) } - if fun_env.get_access_specifiers().is_none() && !fun_env.is_native() { + let acquires = Self::acquires_for_display(&fun_env); + if acquires.is_empty() && !fun_env.is_native() { // Add a space so we open the code block with " {" on the same line. emit!(self.writer, " "); } else { - self.print_access_specifiers(&tctx, &fun_env); + self.print_acquires(&tctx, &acquires); } if let Some(def) = def { // Set up aliases for all temporary variables in the function body @@ -211,89 +209,37 @@ impl<'a> Sourcifier<'a> { } } - fn print_access_specifiers(&self, tctx: &TypeDisplayContext, fun: &FunctionEnv) { - let Some(specs) = fun.get_access_specifiers() else { - return; - }; - self.writer.indent(); - let mut acc_spec_map = BTreeMap::new(); - - // gather resources together under each spec kind - for spec_kind in [ - "!reads", - "!writes", - "!acquires", - "reads", - "writes", - "acquires", - ] { - acc_spec_map.insert(spec_kind.to_string(), BTreeSet::new()); - } - - for spec in specs { - let resource = match &spec.resource.1 { - ResourceSpecifier::Any => "*".to_string(), - ResourceSpecifier::DeclaredAtAddress(addr) => { - format!("0x{}::*::*", addr.expect_numerical().short_str_lossless()) - }, - ResourceSpecifier::DeclaredInModule(mid) => { - format!("{}::*", self.env().get_module(*mid).get_full_name_str()) - }, - ResourceSpecifier::Resource(sid) => { - format!("{}", sid.to_type().display(tctx)) - }, - }; - - let address = match &spec.address.1 { - AddressSpecifier::Any => "".to_string(), - AddressSpecifier::Address(addr) => { - format!("(0x{})", addr.expect_numerical().short_str_lossless()) - }, - AddressSpecifier::Parameter(sym) => { - format!("({})", self.sym(*sym)) - }, - AddressSpecifier::Call(fun, sym) => { - let func_env = self.env().get_function(fun.to_qualified_id()); - format!( - "({}{}({}))", - self.module_qualifier(tctx, func_env.module_env.get_id()), - func_env.get_name_str(), - self.sym(*sym) - ) - }, - }; - - let spec_kind = match spec.kind { - AccessSpecifierKind::Reads => "reads", - AccessSpecifierKind::Writes => "writes", - AccessSpecifierKind::LegacyAcquires => "acquires", - }; - - let spec_key = if spec.negated { - format!("!{}", spec_kind) - } else { - spec_kind.to_string() - }; - - acc_spec_map - .get_mut(&spec_key) - .expect("spec kind key expected") - .insert(format!("{}{}", resource, address)); + /// The acquires list to print for a function. The actually acquired structs are preferred + /// since they are exact and also available for functions loaded from bytecode; the declared + /// list is used for models where acquires analysis has not run (e.g. prover tools). + fn acquires_for_display(fun: &FunctionEnv) -> Vec> { + // Inline functions cannot carry `acquires` annotations, so never print + // inferred ones for them. + if !fun.is_inline() { + if let Some(acquired) = fun.get_acquired_structs() { + let mid = fun.module_env.get_id(); + return acquired.iter().map(|sid| mid.qualified(*sid)).collect(); + } } + fun.get_declared_acquires() + .iter() + .map(|(_, acquired)| *acquired) + .collect() + } - // print the spec kind and associated resources one by one - for (spec_kind, resources) in &acc_spec_map { - if !resources.is_empty() { - emitln!(self.writer); - self.print_list( - &format!("{} ", spec_kind), - ", ", - "", - resources.iter(), - |resource| emit!(self.writer, "{}", resource), - ); - } + fn print_acquires(&self, tctx: &TypeDisplayContext, acquires: &[QualifiedId]) { + if acquires.is_empty() { + return; } + self.writer.indent(); + emitln!(self.writer); + self.print_list("acquires ", ", ", "", acquires.iter(), |acquired| { + emit!( + self.writer, + "{}", + acquired.instantiate(vec![]).to_type().display(tctx) + ) + }); self.writer.unindent(); emitln!(self.writer) } diff --git a/third_party/move/move-vm/runtime/src/access_control.rs b/third_party/move/move-vm/runtime/src/access_control.rs deleted file mode 100644 index 4c8b330d763..00000000000 --- a/third_party/move/move-vm/runtime/src/access_control.rs +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -//! Represents the state machine managing resource access control in VM execution. - -use crate::{interpreter::ACCESS_STACK_SIZE_LIMIT, LoadedFunction}; -use move_binary_format::errors::{PartialVMError, PartialVMResult}; -use move_core_types::vm_status::StatusCode; -use move_vm_types::loaded_data::runtime_access_specifier::{ - AccessInstance, AccessSpecifier, AccessSpecifierEnv, -}; - -/// The state of access control. Maintains a stack of active access specifiers. -/// -/// Every access to a resource must satisfy every specifier on the stack. -#[derive(Clone, Debug, Default)] -pub struct AccessControlState { - specifier_stack: Vec, -} - -impl AccessControlState { - /// Enters a function, applying its access specifier to the state. - // note(inline): do not inline, they are called once per function, and increase `execute_main` - // quite a bit, we want to avoid those compile times - #[cfg_attr(feature = "force-inline", inline(always))] - pub(crate) fn enter_function( - &mut self, - env: &impl AccessSpecifierEnv, - fun: &LoadedFunction, - ) -> PartialVMResult<()> { - if matches!(fun.access_specifier(), AccessSpecifier::Any) { - // Shortcut case that no access is specified - return Ok(()); - } - if self.specifier_stack.len() >= ACCESS_STACK_SIZE_LIMIT { - Err( - PartialVMError::new(StatusCode::ACCESS_STACK_LIMIT_EXCEEDED).with_message(format!( - "access specifier stack overflow (limit = {})", - ACCESS_STACK_SIZE_LIMIT - )), - ) - } else { - // Specialize the functions access specifier and push it on the stack. - let mut fun_specifier = fun.access_specifier().clone(); - fun_specifier.specialize(env)?; - self.specifier_stack.push(fun_specifier); - Ok(()) - } - } - - /// Exit function, restoring access state before entering. - // note(inline): do not inline, they are called once per function, and increase `execute_main` - // quite a bit, we want to avoid those compile times - #[cfg_attr(feature = "force-inline", inline(always))] - pub(crate) fn exit_function(&mut self, fun: &LoadedFunction) -> PartialVMResult<()> { - if !matches!(fun.access_specifier(), AccessSpecifier::Any) { - if self.specifier_stack.is_empty() { - return Err( - PartialVMError::new(StatusCode::ACCESS_CONTROL_INVARIANT_VIOLATION) - .with_message("unbalanced access specifier stack".to_owned()), - ); - } - self.specifier_stack.pop(); - } - Ok(()) - } - - /// Check whether the given access is allowed in the current state. - pub(crate) fn check_access(&self, access: AccessInstance) -> PartialVMResult<()> { - for specifier in self.specifier_stack.iter().rev() { - if !specifier.enables(&access) { - return Err(PartialVMError::new(StatusCode::ACCESS_DENIED) - .with_message(format!("not allowed to perform `{}`", access))); - } - } - Ok(()) - } -} diff --git a/third_party/move/move-vm/runtime/src/frame.rs b/third_party/move/move-vm/runtime/src/frame.rs index 499f59badcf..96536193580 100644 --- a/third_party/move/move-vm/runtime/src/frame.rs +++ b/third_party/move/move-vm/runtime/src/frame.rs @@ -17,23 +17,20 @@ use move_binary_format::{ errors::{PartialVMError, PartialVMResult}, file_format::{ Constant, ConstantPoolIndex, FieldHandleIndex, FieldInstantiationIndex, - FunctionHandleIndex, FunctionInstantiationIndex, LocalIndex, SignatureIndex, + FunctionHandleIndex, FunctionInstantiationIndex, SignatureIndex, StructDefInstantiationIndex, StructDefinitionIndex, StructVariantHandleIndex, StructVariantInstantiationIndex, VariantFieldHandleIndex, VariantFieldInstantiationIndex, VariantIndex, }, }; use move_core_types::{ - ability::Ability, account_address::AccountAddress, gas_algebra::NumTypeNodes, + ability::Ability, gas_algebra::NumTypeNodes, identifier::IdentStr, language_storage::ModuleId, vm_status::StatusCode, }; use move_vm_profiler::FnGuard; use move_vm_types::{ gas::GasMeter, - loaded_data::{ - runtime_access_specifier::{AccessSpecifierEnv, AddressSpecifierFunction}, - runtime_types::{AbilityInfo, StructType, Type, TypeBuilder}, - }, + loaded_data::runtime_types::{AbilityInfo, StructType, Type, TypeBuilder}, ty_interner::{InternedTypePool, TypeVecId}, values::Locals, }; @@ -76,16 +73,6 @@ pub(crate) struct Frame { pub(crate) caller_type_stack_size: u32, } -impl AccessSpecifierEnv for Frame { - fn eval_address_specifier_function( - &self, - fun: AddressSpecifierFunction, - local: LocalIndex, - ) -> PartialVMResult { - fun.eval(self.locals.copy_loc(local as usize)?) - } -} - macro_rules! build_loaded_function { ($function_name:ident, $idx_ty:ty, $get_function_handle:ident) => { pub(crate) fn $function_name( diff --git a/third_party/move/move-vm/runtime/src/interpreter.rs b/third_party/move/move-vm/runtime/src/interpreter.rs index 1f8fc468c8a..d12d04d4e4d 100644 --- a/third_party/move/move-vm/runtime/src/interpreter.rs +++ b/third_party/move/move-vm/runtime/src/interpreter.rs @@ -3,7 +3,6 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - access_control::AccessControlState, config::VMConfig, data_cache::MoveVmDataCache, execution_tracing::TraceRecorder, @@ -31,7 +30,7 @@ use itertools::Itertools; use move_binary_format::{ errors, errors::*, - file_format::{AccessKind, FunctionHandleIndex, FunctionInstantiationIndex, SignatureIndex}, + file_format::{FunctionHandleIndex, FunctionInstantiationIndex, SignatureIndex}, }; use move_core_types::{ account_address::AccountAddress, @@ -47,7 +46,7 @@ use move_vm_types::{ debug_write, debug_writeln, gas::{GasMeter, SimpleInstruction}, instr::Instruction, - loaded_data::{runtime_access_specifier::AccessInstance, runtime_types::Type}, + loaded_data::runtime_types::Type, natives::function::NativeResult, ty_interner::InternedTypePool, values::{ @@ -145,8 +144,6 @@ pub(crate) struct InterpreterImpl<'ctx, LoaderImpl> { vm_config: &'ctx VMConfig, /// Pool of interned types. ty_pool: &'ctx InternedTypePool, - /// The access control state. - access_control: AccessControlState, /// Reentrancy checker. reentrancy_checker: ReentrancyChecker, /// Loader to resolve functions and modules from remote storage. Ensures all module accesses @@ -230,7 +227,6 @@ where call_stack: CallStack::new(), vm_config: loader.runtime_environment().vm_config(), ty_pool: loader.runtime_environment().ty_pool(), - access_control: AccessControlState::default(), reentrancy_checker: ReentrancyChecker::default(), loader, ty_depth_checker, @@ -378,11 +374,6 @@ where ) .map_err(|err| self.set_location(err))?; - // Access control for the new frame. - self.access_control - .enter_function(¤t_frame, ¤t_frame.function) - .map_err(|e| self.set_location(e))?; - trace_recorder.record_entrypoint(current_frame.function.as_ref()); loop { let exit_code = current_frame @@ -415,10 +406,6 @@ where self.call_stack .type_check_return::(&mut self.operand_stack, &mut current_frame) .map_err(|e| set_err_info!(current_frame, e))?; - self.access_control - .exit_function(¤t_frame.function) - .map_err(|e| set_err_info!(current_frame, e))?; - if let Some(frame) = self.call_stack.pop() { self.reentrancy_checker .exit_function( @@ -880,11 +867,6 @@ where self.attach_state_if_invariant_violation(self.set_location(err), current_frame) })?; - // Access control for the new frame. - self.access_control - .enter_function(&frame, &frame.function) - .map_err(|e| self.set_location(e))?; - std::mem::swap(current_frame, &mut frame); self.call_stack.push(frame).map_err(|frame| { let err = PartialVMError::new(StatusCode::CALL_STACK_OVERFLOW); @@ -1341,32 +1323,20 @@ where }, res.is_ok(), )?; - self.check_access( - runtime_environment, - if is_mut { - AccessKind::Writes - } else { - AccessKind::Reads - }, - ty, - addr, - )?; + self.check_resource_access(runtime_environment, ty)?; self.operand_stack.push(res.map_err(|err| { err.with_message(format!("Failed to borrow global resource from {:?}", addr)) })?)?; Ok(()) } - fn check_access( + fn check_resource_access( &self, runtime_environment: &RuntimeEnvironment, - kind: AccessKind, ty: &Type, - addr: AccountAddress, ) -> PartialVMResult<()> { - let (struct_idx, instance) = match ty { - Type::Struct { idx, .. } => (*idx, [].as_slice()), - Type::StructInstantiation { idx, ty_args, .. } => (*idx, ty_args.as_slice()), + let struct_idx = match ty { + Type::Struct { idx, .. } | Type::StructInstantiation { idx, .. } => *idx, _ => { return Err( PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR) @@ -1377,16 +1347,7 @@ where let struct_name = runtime_environment .struct_name_index_map() .idx_to_struct_name(struct_idx)?; - - // Perform resource reentrancy check - self.reentrancy_checker - .check_resource_access(&struct_name)?; - - // Perform resource access control - if let Some(access) = AccessInstance::new(kind, struct_name, instance, addr) { - self.access_control.check_access(access)? - } - Ok(()) + self.reentrancy_checker.check_resource_access(&struct_name) } /// Exists opcode. @@ -1410,7 +1371,7 @@ where }, exists, )?; - self.check_access(runtime_environment, AccessKind::Reads, ty, addr)?; + self.check_resource_access(runtime_environment, ty)?; self.operand_stack.push(Value::bool(exists))?; Ok(()) } @@ -1439,7 +1400,7 @@ where }, Some(&resource), )?; - self.check_access(runtime_environment, AccessKind::Writes, ty, addr)?; + self.check_resource_access(runtime_environment, ty)?; resource }, Err(err) => { @@ -1485,7 +1446,7 @@ where gv.view().unwrap(), true, )?; - self.check_access(runtime_environment, AccessKind::Writes, ty, addr)?; + self.check_resource_access(runtime_environment, ty)?; Ok(()) }, Err((err, resource)) => { @@ -1720,7 +1681,6 @@ where // TODO Determine stack size limits based on gas limit const OPERAND_STACK_SIZE_LIMIT: usize = 1024; const CALL_STACK_SIZE_LIMIT: usize = 1024; -pub(crate) const ACCESS_STACK_SIZE_LIMIT: usize = 256; /// The operand and runtime-type stacks. pub(crate) struct Stack { diff --git a/third_party/move/move-vm/runtime/src/lib.rs b/third_party/move/move-vm/runtime/src/lib.rs index 019fb9827cf..f7b9afb1cfa 100644 --- a/third_party/move/move-vm/runtime/src/lib.rs +++ b/third_party/move/move-vm/runtime/src/lib.rs @@ -25,7 +25,6 @@ pub mod module_traversal; #[cfg(any(debug_assertions, feature = "debugging"))] mod debug; -mod access_control; mod frame; mod frame_type_cache; mod reentrancy_checker; diff --git a/third_party/move/move-vm/runtime/src/loader/access_specifier_loader.rs b/third_party/move/move-vm/runtime/src/loader/access_specifier_loader.rs deleted file mode 100644 index bd200741c4d..00000000000 --- a/third_party/move/move-vm/runtime/src/loader/access_specifier_loader.rs +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) The Move Contributors -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::{ - binary_views::BinaryIndexedView, - errors::{PartialVMError, PartialVMResult}, - file_format as FF, - file_format::TableIndex, -}; -use move_core_types::vm_status::StatusCode; -use move_vm_types::loaded_data::{ - runtime_access_specifier::{ - AccessSpecifier, AccessSpecifierClause, AddressSpecifier, AddressSpecifierFunction, - ResourceSpecifier, - }, - runtime_types::{StructIdentifier, Type}, -}; - -/// Loads an access specifier from the file format into the runtime representation. -pub fn load_access_specifier( - module: BinaryIndexedView, - signature_table: &[Vec], - struct_names: &[StructIdentifier], - specifier: &Option>, -) -> PartialVMResult { - if let Some(specs) = specifier { - let mut incls = vec![]; - let mut excls = vec![]; - for spec in specs { - let resource = - load_resource_specifier(module, signature_table, struct_names, &spec.resource)?; - let address = load_address_specifier(module, &spec.address)?; - let clause = AccessSpecifierClause { - kind: spec.kind, - resource, - address, - }; - if spec.negated { - excls.push(clause) - } else { - incls.push(clause) - } - } - Ok(AccessSpecifier::Constraint(incls, excls)) - } else { - Ok(AccessSpecifier::Any) - } -} - -fn load_resource_specifier( - module: BinaryIndexedView, - signature_table: &[Vec], - struct_names: &[StructIdentifier], - spec: &FF::ResourceSpecifier, -) -> PartialVMResult { - use FF::ResourceSpecifier::*; - match spec { - Any => Ok(ResourceSpecifier::Any), - DeclaredAtAddress(addr_idx) => Ok(ResourceSpecifier::DeclaredAtAddress(*access_table( - module.address_identifiers(), - addr_idx.0, - )?)), - DeclaredInModule(mod_idx) => Ok(ResourceSpecifier::DeclaredInModule( - module - .safe_module_id_for_handle(access_table(module.module_handles(), mod_idx.0)?) - .ok_or_else(index_out_of_range)?, - )), - Resource(str_idx) => Ok(ResourceSpecifier::Resource( - access_table(struct_names, str_idx.0)?.clone(), - )), - ResourceInstantiation(str_idx, ty_idx) => Ok(ResourceSpecifier::ResourceInstantiation( - access_table(struct_names, str_idx.0)?.clone(), - access_table(signature_table, ty_idx.0)?.clone(), - )), - } -} - -fn load_address_specifier( - module: BinaryIndexedView, - spec: &FF::AddressSpecifier, -) -> PartialVMResult { - use FF::AddressSpecifier::*; - match spec { - Any => Ok(AddressSpecifier::Any), - Literal(idx) => Ok(AddressSpecifier::Literal(*access_table( - module.address_identifiers(), - idx.0, - )?)), - Parameter(param, fun) => { - let fun = if let Some(idx) = fun { - let fun_inst = access_table(module.function_instantiations(), idx.0)?; - let fun_handle = access_table(module.function_handles(), fun_inst.handle.0)?; - let mod_handle = access_table(module.module_handles(), fun_handle.module.0)?; - let mod_id = module - .safe_module_id_for_handle(mod_handle) - .ok_or_else(index_out_of_range)?; - let mod_name = mod_id.short_str_lossless(); - let fun_name = access_table(module.identifiers(), fun_handle.name.0)?; - AddressSpecifierFunction::parse(&mod_name, fun_name.as_str()).ok_or_else(|| { - PartialVMError::new(StatusCode::ACCESS_CONTROL_INVARIANT_VIOLATION) - .with_message(format!( - "function `{}::{}` not supported for address specifier", - mod_name, fun_name - )) - })? - } else { - AddressSpecifierFunction::Identity - }; - Ok(AddressSpecifier::Eval(fun, *param)) - }, - } -} - -fn access_table(table: &[T], idx: TableIndex) -> PartialVMResult<&T> { - if (idx as usize) < table.len() { - Ok(&table[idx as usize]) - } else { - Err(index_out_of_range()) - } -} - -fn index_out_of_range() -> PartialVMError { - PartialVMError::new(StatusCode::ACCESS_CONTROL_INVARIANT_VIOLATION) - .with_message("table index out of range".to_owned()) -} diff --git a/third_party/move/move-vm/runtime/src/loader/function.rs b/third_party/move/move-vm/runtime/src/loader/function.rs index 5d437df499c..60862ef64a9 100644 --- a/third_party/move/move-vm/runtime/src/loader/function.rs +++ b/third_party/move/move-vm/runtime/src/loader/function.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - loader::{access_specifier_loader::load_access_specifier, Module, Script}, + loader::{Module, Script}, module_traversal::TraversalContext, native_functions::{NativeFunction, NativeFunctions, UnboxedNativeFunction}, storage::{loader::traits::Loader, ty_layout_converter::LayoutConverter}, @@ -12,7 +12,6 @@ use better_any::{Tid, TidAble, TidExt}; use lazy_static::lazy_static; use move_binary_format::{ access::ModuleAccess, - binary_views::BinaryIndexedView, errors::{Location, PartialVMError, PartialVMResult, VMResult}, file_format::{CompiledModule, FunctionAttribute, FunctionDefinitionIndex, Visibility}, }; @@ -29,10 +28,7 @@ use move_vm_profiler::ProfilerFunction; use move_vm_types::{ gas::DependencyGasMeter, instr::Instruction, - loaded_data::{ - runtime_access_specifier::AccessSpecifier, - runtime_types::{StructIdentifier, Type}, - }, + loaded_data::runtime_types::Type, module_id_interner::InternedModuleId, ty_interner::TypeVecId, values::{AbstractFunction, SerializedFunctionData}, @@ -84,7 +80,6 @@ pub struct Function { // compatible). pub(crate) local_tys: Vec, pub(crate) param_tys: Vec, - pub(crate) access_specifier: AccessSpecifier, pub(crate) is_persistent: bool, pub(crate) has_module_reentrancy_lock: bool, pub(crate) is_trusted: bool, @@ -583,10 +578,6 @@ impl LoadedFunction { self.function.code.len() } - pub(crate) fn access_specifier(&self) -> &AccessSpecifier { - &self.function.access_specifier - } - pub(crate) fn name_as_pretty_string(&self) -> String { match &self.owner { LoadedFunctionOwner::Script(_) => "script::main".into(), @@ -614,7 +605,6 @@ impl Function { index: FunctionDefinitionIndex, module: &CompiledModule, signature_table: &[Vec], - struct_names: &[StructIdentifier], ) -> PartialVMResult { let def = module.function_def_at(index); let handle = module.function_handle_at(def.function); @@ -654,13 +644,6 @@ impl Function { }; let param_tys = signature_table[handle.parameters.0 as usize].clone(); - let access_specifier = load_access_specifier( - BinaryIndexedView::Module(module), - signature_table, - struct_names, - &handle.access_specifiers, - )?; - Ok(Self { file_format_version: module.version(), index, @@ -675,7 +658,6 @@ impl Function { local_tys, return_tys, param_tys, - access_specifier, is_persistent: handle.attributes.contains(&FunctionAttribute::Persistent), has_module_reentrancy_lock: handle.attributes.contains(&FunctionAttribute::ModuleLock), is_trusted, diff --git a/third_party/move/move-vm/runtime/src/loader/mod.rs b/third_party/move/move-vm/runtime/src/loader/mod.rs index bcbbdee4cfa..39e9cfd91bb 100644 --- a/third_party/move/move-vm/runtime/src/loader/mod.rs +++ b/third_party/move/move-vm/runtime/src/loader/mod.rs @@ -2,8 +2,6 @@ // Copyright (c) The Move Contributors // SPDX-License-Identifier: Apache-2.0 -mod access_specifier_loader; - mod function; pub use function::{Function, LoadedFunction, LoadedFunctionOwner}; pub(crate) use function::{ diff --git a/third_party/move/move-vm/runtime/src/loader/modules.rs b/third_party/move/move-vm/runtime/src/loader/modules.rs index 27cb76dc666..a2a6444c420 100644 --- a/third_party/move/move-vm/runtime/src/loader/modules.rs +++ b/third_party/move/move-vm/runtime/src/loader/modules.rs @@ -189,7 +189,6 @@ impl Module { let mut is_fully_instantiated_signature = vec![]; let mut struct_idxs = vec![]; - let mut struct_names = vec![]; // validate the correctness of struct handle references. for struct_handle in module.struct_handles() { @@ -199,7 +198,6 @@ impl Module { let struct_name = StructIdentifier::new(module_id_pool, module_id, struct_name.to_owned()); struct_idxs.push(struct_name_index_map.struct_name_to_idx(&struct_name)?); - struct_names.push(struct_name) } // Build signature table @@ -260,13 +258,7 @@ impl Module { for (idx, _) in module.function_defs().iter().enumerate() { let findex = FunctionDefinitionIndex(idx as TableIndex); - let function = Function::new( - natives, - findex, - &module, - signature_table.as_slice(), - &struct_names, - )?; + let function = Function::new(natives, findex, &module, signature_table.as_slice())?; function_map.insert(function.name.to_owned(), idx); function_defs.push(Arc::new(function)); diff --git a/third_party/move/move-vm/runtime/src/loader/script.rs b/third_party/move/move-vm/runtime/src/loader/script.rs index b8bc2e16213..49781174f4a 100644 --- a/third_party/move/move-vm/runtime/src/loader/script.rs +++ b/third_party/move/move-vm/runtime/src/loader/script.rs @@ -18,7 +18,6 @@ use move_core_types::{ }; use move_vm_types::{ loaded_data::{ - runtime_access_specifier::AccessSpecifier, runtime_types::{StructIdentifier, Type}, struct_name_indexing::StructNameIndexMap, }, @@ -135,7 +134,6 @@ impl Script { return_tys: vec![], local_tys, param_tys, - access_specifier: AccessSpecifier::Any, is_persistent: false, has_module_reentrancy_lock: false, is_trusted: false, diff --git a/third_party/move/move-vm/types/proptest-regressions/loaded_data/runtime_access_specifiers_prop_tests.txt b/third_party/move/move-vm/types/proptest-regressions/loaded_data/runtime_access_specifiers_prop_tests.txt deleted file mode 100644 index c4284eca12b..00000000000 --- a/third_party/move/move-vm/types/proptest-regressions/loaded_data/runtime_access_specifiers_prop_tests.txt +++ /dev/null @@ -1,9 +0,0 @@ -# Seeds for failure cases proptest has generated in the past. It is -# automatically read and these particular cases re-run before any -# novel cases are generated. -# -# It is recommended to check this file in to source control so that -# everyone who runs the test benefits from these saved cases. -cc 909d52933dc057f54814b28bd6ed88504cee077ece2e6d70252adeeab2ba9f58 # shrinks to access = AccessInstance { kind: Reads, resource: StructIdentifier { module: ModuleId { address: 0000000000000000000000000000000000000000000000000000000000000001, name: Identifier("ac") }, name: Identifier("ac") }, instance: [], address: 0000000000000000000000000000000000000000000000000000000000000001 }, s1 = Any, s2 = Any -cc dba42d5ed4d6a925756fb4ea8f829bed5a209f2be288885b453b352eec92ce5f # shrinks to access = AccessInstance { kind: Reads, resource: StructIdentifier { module: ModuleId { address: 0000000000000000000000000000000000000000000000000000000000000001, name: Identifier("ac") }, name: Identifier("ac") }, instance: [], address: 0000000000000000000000000000000000000000000000000000000000000001 }, s1 = Any, s2 = Any -cc b95bd44e13064041a78409ce4f11d729f189756de014c143b909e7eec2b8c81f # shrinks to access = AccessInstance { kind: Reads, resource: StructIdentifier { module: ModuleId { address: 0000000000000000000000000000000000000000000000000000000000000002, name: Identifier("ac") }, name: Identifier("ac") }, instance: [], address: 0000000000000000000000000000000000000000000000000000000000000002 }, s1 = Constraint([AccessSpecifierClause { kind: Acquires, resource: Any, address: Literal(0000000000000000000000000000000000000000000000000000000000000001) }], []), s2 = Constraint([AccessSpecifierClause { kind: Acquires, resource: Any, address: Any }], []) diff --git a/third_party/move/move-vm/types/src/loaded_data/mod.rs b/third_party/move/move-vm/types/src/loaded_data/mod.rs index d650a543423..814fc87db65 100644 --- a/third_party/move/move-vm/types/src/loaded_data/mod.rs +++ b/third_party/move/move-vm/types/src/loaded_data/mod.rs @@ -5,8 +5,5 @@ //! //! This module contains the loaded definition of code data used in runtime. -pub mod runtime_access_specifier; -#[cfg(test)] -mod runtime_access_specifiers_prop_tests; pub mod runtime_types; pub mod struct_name_indexing; diff --git a/third_party/move/move-vm/types/src/loaded_data/runtime_access_specifier.rs b/third_party/move/move-vm/types/src/loaded_data/runtime_access_specifier.rs deleted file mode 100644 index 67e265b33b4..00000000000 --- a/third_party/move/move-vm/types/src/loaded_data/runtime_access_specifier.rs +++ /dev/null @@ -1,326 +0,0 @@ -// Copyright (c) The Move Contributors -// SPDX-License-Identifier: Apache-2.0 - -//! Runtime representation of access control specifiers. -//! -//! Specifiers are represented as a list of inclusion and exclusion clauses. Each -//! of those clauses corresponds to an `acquires A`, `reads A`, or `writes A` -//! declaration in the language. Exclusions stem from negation, e.g. `!reads A`. -//! -//! Specifiers support access check via `AccessSpecifier::enables`. Moreover, -//! access specifiers can be joined via `AccessSpecifier::join`. The join of two access -//! specifiers behaves like intersection: for `a1 join a2`, access is allowed if it -//! is both allowed by `a1` and `a2`. Joining happens when a function is entered which -//! has access specifiers: then the current active access specifier is joined with the -//! function's specifier. The join operator is complete (no approximation). A further -//! operator `AccessSpecifier::subsumes` allows to test whether one specifier -//! allows all the access of the other. This used to abort execution if a function -//! is entered which declares accesses not allowed by the context. However, the -//!`subsumes` function is incomplete. This is semantically sound since -//! if subsume is undecided, abortion only happens later at the time of actual access -//! instead of when the function is entered. -//! -//! The `join` operation attempts to simplify the resulting access specifier, making -//! access checks faster and keeping memory use low. This is only implemented for -//! inclusions, which are fully simplified. Exclusions are accumulated. -//! There is potential for optimization by simplifying exclusions but since those are effectively -//! negations, such a simplification is not trivial and may require recursive specifiers, which -//! we like to avoid. - -use crate::{ - loaded_data::runtime_types::{StructIdentifier, Type}, - values::{Reference, SignerRef, Value}, -}; -use itertools::Itertools; -use move_binary_format::{ - errors::{PartialVMError, PartialVMResult}, - file_format::{AccessKind, LocalIndex}, -}; -use move_core_types::{ - account_address::AccountAddress, language_storage::ModuleId, vm_status::StatusCode, -}; -use std::{fmt, fmt::Debug}; - -/// Represents an access specifier. -#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Debug)] -pub enum AccessSpecifier { - /// Universal access granted - Any, - /// A constraint in normalized form `Constraint(inclusions, exclusions)`. - /// The inclusions are a _disjunction_ and the exclusions a _conjunction_ of - /// access clauses. An access is valid if it is enabled by any of the - /// inclusions, and not enabled for each of the exclusions. - Constraint(Vec, Vec), -} - -/// Represents an access specifier clause -#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Debug)] -pub struct AccessSpecifierClause { - pub kind: AccessKind, - pub resource: ResourceSpecifier, - pub address: AddressSpecifier, -} - -/// Represents a resource specifier. -#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Debug)] -pub enum ResourceSpecifier { - Any, - DeclaredAtAddress(AccountAddress), - DeclaredInModule(ModuleId), - Resource(StructIdentifier), - ResourceInstantiation(StructIdentifier, Vec), -} - -/// Represents an address specifier. -#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Debug)] -pub enum AddressSpecifier { - Any, - Literal(AccountAddress), - /// The `Eval` specifier represents a value dependent on a parameter of the - /// current function. Once address specifiers are instantiated in a given - /// caller context it is replaced by a literal. - Eval(AddressSpecifierFunction, LocalIndex), -} - -/// Represents a well-known function used in an address specifier. -#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug)] -pub enum AddressSpecifierFunction { - /// Identity function -- just returns the value of the parameter. - Identity, - /// signer::address_of - SignerAddress, - /// object::owner_of - ObjectAddress, -} - -/// A trait representing an environment for evaluating dynamic values in access specifiers. -pub trait AccessSpecifierEnv { - fn eval_address_specifier_function( - &self, - fun: AddressSpecifierFunction, - local: LocalIndex, - ) -> PartialVMResult; -} - -/// A struct to represent an access instance (request). -#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Debug)] -pub struct AccessInstance { - pub kind: AccessKind, - pub resource: StructIdentifier, - pub instance: Vec, - pub address: AccountAddress, -} - -impl AccessSpecifier { - /// Returns true if this access specifier is known to have no accesses. Note that this - /// may be under-approximated in the presence of exclusions. That is, if - /// `!s.is_empty()`, it is still possible that all concrete accesses fail. - pub fn is_empty(&self) -> bool { - if let AccessSpecifier::Constraint(incls, _) = self { - incls.is_empty() - } else { - false - } - } - - /// Specializes the access specifier for the given environment. This evaluates - /// `AddressSpecifier::Eval` terms. - pub fn specialize(&mut self, env: &impl AccessSpecifierEnv) -> PartialVMResult<()> { - match self { - AccessSpecifier::Any => Ok(()), - AccessSpecifier::Constraint(incls, excls) => { - for clause in incls { - clause.specialize(env)?; - } - for clause in excls { - clause.specialize(env)?; - } - Ok(()) - }, - } - } - - /// Returns true if the concrete access instance is enabled. - pub fn enables(&self, access: &AccessInstance) -> bool { - use AccessSpecifier::*; - match self { - Any => true, - Constraint(incls, excls) => { - (incls.is_empty() && !excls.is_empty() || incls.iter().any(|c| c.includes(access))) - && excls.iter().all(|c| !c.excludes(access)) - }, - } - } -} - -impl AccessSpecifierClause { - /// Checks whether this clause allows the access. - fn includes(&self, access: &AccessInstance) -> bool { - use AccessKind::*; - let AccessInstance { - kind, - resource, - instance, - address, - } = access; - let kind_allows = match (self.kind, kind) { - (Reads, Reads) => true, - (Reads, Writes) => false, - // `writes` enables both read and write access - (Writes, Reads) => true, - (Writes, Writes) => true, - }; - kind_allows && self.resource.matches(resource, instance) && self.address.matches(address) - } - - /// Checks whether this clause disallows the access. - /// There is a difference in the interpretation of Reads/Writes in negated mode. - /// With `!reads`, both reading and writing are excluded (since write access also allows - /// read). With `!writes`, only writing is excluded, while reading is still allowed. - fn excludes(&self, access: &AccessInstance) -> bool { - use AccessKind::*; - let AccessInstance { - kind, - resource, - instance, - address, - } = access; - let kind_excludes = match (self.kind, kind) { - (Reads, Reads) => true, - (Reads, Writes) => true, - (Writes, Reads) => false, - (Writes, Writes) => true, - }; - kind_excludes && self.resource.matches(resource, instance) && self.address.matches(address) - } - - /// Specializes this clause. - fn specialize(&mut self, env: &impl AccessSpecifierEnv) -> PartialVMResult<()> { - // Only addresses can be specialized right now. - self.address.specialize(env) - } -} - -impl ResourceSpecifier { - /// Checks whether the struct/type pair is enabled by this specifier. - fn matches(&self, struct_id: &StructIdentifier, type_inst: &[Type]) -> bool { - use ResourceSpecifier::*; - match self { - Any => true, - DeclaredAtAddress(addr) => struct_id.module().address() == addr, - DeclaredInModule(module_id) => struct_id.module() == module_id, - Resource(enabled_struct_id) => enabled_struct_id == struct_id, - ResourceInstantiation(enabled_struct_id, enabled_type_inst) => { - enabled_struct_id == struct_id && enabled_type_inst == type_inst - }, - } - } -} - -impl AddressSpecifier { - /// Checks whether the given address is enabled by this specifier. - fn matches(&self, addr: &AccountAddress) -> bool { - use AddressSpecifier::*; - match self { - Any => true, - Literal(a) => a == addr, - Eval(_, _) => false, - } - } - - /// Specializes this specifier, resolving `Eval` variants. - fn specialize(&mut self, env: &impl AccessSpecifierEnv) -> PartialVMResult<()> { - if let AddressSpecifier::Eval(fun, arg) = self { - *self = AddressSpecifier::Literal(env.eval_address_specifier_function(*fun, *arg)?) - } - Ok(()) - } -} - -impl AddressSpecifierFunction { - pub fn parse(module_str: &str, fun_str: &str) -> Option { - match (module_str, fun_str) { - ("0x1::signer", "address_of") => Some(AddressSpecifierFunction::SignerAddress), - ("0x1::object", "owner") => Some(AddressSpecifierFunction::ObjectAddress), - _ => None, - } - } - - pub fn eval(&self, arg: Value) -> PartialVMResult { - use AddressSpecifierFunction::*; - match self { - Identity => arg.value_as::(), - SignerAddress => { - // See also: implementation of `signer::native_borrow_address`. - let signer_ref = arg.value_as::()?; - signer_ref - .borrow_signer()? - .value_as::()? - .read_ref()? - .value_as::() - }, - ObjectAddress => Err(PartialVMError::new( - StatusCode::ACCESS_CONTROL_INVARIANT_VIOLATION, - ) - .with_message(format!( - "unimplemented address specifier function `{:?}`", - self - ))), - } - } -} - -impl AccessInstance { - pub fn new( - kind: AccessKind, - resource: StructIdentifier, - instance: &[Type], - address: AccountAddress, - ) -> Option { - Some(AccessInstance { - kind, - resource, - instance: instance.to_vec(), - address, - }) - } - - pub fn read( - resource: &StructIdentifier, - instance: &[Type], - address: AccountAddress, - ) -> Option { - Self::new(AccessKind::Reads, resource.clone(), instance, address) - } - - pub fn write( - resource: &StructIdentifier, - instance: &[Type], - address: AccountAddress, - ) -> Option { - Self::new(AccessKind::Writes, resource.clone(), instance, address) - } -} - -impl fmt::Display for AccessInstance { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { - kind, - resource, - instance, - address, - } = self; - write!( - f, - "{} {}{}(@0x{})", - kind, - resource, - if !instance.is_empty() { - format!("<{}>", instance.iter().map(|t| t.to_string()).join(",")) - } else { - "".to_owned() - }, - address.short_str_lossless() - ) - } -} diff --git a/third_party/move/move-vm/types/src/loaded_data/runtime_access_specifiers_prop_tests.rs b/third_party/move/move-vm/types/src/loaded_data/runtime_access_specifiers_prop_tests.rs deleted file mode 100644 index c64209d0f99..00000000000 --- a/third_party/move/move-vm/types/src/loaded_data/runtime_access_specifiers_prop_tests.rs +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright (c) The Move Contributors -// SPDX-License-Identifier: Apache-2.0 - -use crate::{ - loaded_data::{ - runtime_access_specifier::{ - AccessInstance, AccessSpecifier, AccessSpecifierClause, AddressSpecifier, - ResourceSpecifier, - }, - runtime_types::{StructIdentifier, Type, TypeBuilder}, - }, - module_id_interner::test_util::TEST_MODULE_ID_POOL, -}; -use move_binary_format::file_format::AccessKind; -use move_core_types::{ - account_address::AccountAddress, identifier::Identifier, language_storage::ModuleId, -}; -use proptest::{collection::vec, prelude::*}; - -proptest! { - #![proptest_config(ProptestConfig{cases: 5000, verbose: 1, ..ProptestConfig::default()})] - - /// Test membership, by constructing all combinations of specifiers derivable from a given - /// instance. - #[test] - fn access_specifier_enables( - (access1, clause1) in access_to_matching_specifier_clause(access_instance_strategy()), - (access2, clause2) in access_to_matching_specifier_clause(access_instance_strategy()), - ) { - let clauses = vec![clause1, clause2]; - let incl = AccessSpecifier::Constraint(clauses.clone(), vec![]); - let incl_excl = AccessSpecifier::Constraint(clauses.clone(), clauses.clone()); - let excl = AccessSpecifier::Constraint(vec![], clauses.clone()); - assert!(incl.enables(&access1)); - assert!(incl.enables(&access2)); - assert!(!incl_excl.enables(&access1)); - assert!(!incl_excl.enables(&access2)); - assert!(!excl.enables(&access1)); - assert!(!excl.enables(&access2)); - } -} - -fn access_instance_strategy() -> impl Strategy { - ( - any::(), - struct_id_strategy(), - type_args_strategy(), - address_strategy(), - ) - .prop_map(|(kind, resource, instance, address)| AccessInstance { - kind, - resource, - instance, - address, - }) -} - -#[allow(unused)] // currently unused, but maybe helpful for future tests -fn access_specifier_strategy( - incl_size: usize, - excl_size: usize, -) -> impl Strategy { - prop_oneof![ - Just(AccessSpecifier::Any), - ( - vec(access_specifier_clause_strategy(), 0..incl_size), - vec(access_specifier_clause_strategy(), 0..excl_size), - ) - .prop_map(|(incls, excls)| AccessSpecifier::Constraint(incls, excls)) - ] -} - -#[allow(unused)] // currently unused, but maybe helpful for future tests -fn access_specifier_clause_strategy() -> impl Strategy { - ( - any::(), - resource_specifier_strategy(), - address_specifier_strategy(), - ) - .prop_map(|(kind, resource, address)| AccessSpecifierClause { - kind, - resource, - address, - }) -} - -#[allow(unused)] // currently unused, but maybe helpful for future tests -fn resource_specifier_strategy() -> impl Strategy { - prop_oneof![ - Just(ResourceSpecifier::Any), - address_strategy().prop_map(ResourceSpecifier::DeclaredAtAddress), - module_id_strategy().prop_map(ResourceSpecifier::DeclaredInModule), - struct_id_strategy().prop_map(ResourceSpecifier::Resource), - (struct_id_strategy(), type_args_strategy()) - .prop_map(|(s, ts)| ResourceSpecifier::ResourceInstantiation(s, ts)), - ] -} - -#[allow(unused)] // currently unused, but maybe helpful for future tests -fn address_specifier_strategy() -> impl Strategy { - prop_oneof![ - Just(AddressSpecifier::Any), - address_strategy().prop_map(AddressSpecifier::Literal) // Skip Eval as it is not appearing subsumes and join - ] -} - -fn type_args_strategy() -> impl Strategy> { - // Actual type builder limits do not matter because creating primitive - // integer types is always possible. - let ty_builder = TypeBuilder::with_limits(10, 10); - prop_oneof![ - Just(vec![]), - Just(vec![ty_builder.create_u8_ty()]), - Just(vec![ty_builder.create_u16_ty(), ty_builder.create_u32_ty()]) - ] -} - -fn struct_id_strategy() -> impl Strategy { - (module_id_strategy(), identifier_strategy()) - .prop_map(|(module, name)| StructIdentifier::new(&TEST_MODULE_ID_POOL, module, name)) -} - -fn module_id_strategy() -> impl Strategy { - (address_strategy(), identifier_strategy()).prop_map(|(a, i)| ModuleId::new(a, i)) -} - -fn identifier_strategy() -> impl Strategy { - "[a-b]{1}[c-d]{1}".prop_map(|s| Identifier::new(s).unwrap()) -} - -fn address_strategy() -> impl Strategy { - prop_oneof![ - Just(AccountAddress::from_str_strict("0x1").unwrap()), - Just(AccountAddress::from_str_strict("0x2").unwrap()), - Just(AccountAddress::from_str_strict("0x3").unwrap()) - ] -} - -/// Map a strategy of instances to matching access specifier clauses. -fn access_to_matching_specifier_clause( - instances: impl Strategy, -) -> impl Strategy { - instances.prop_flat_map(|inst| { - ( - Just(inst.kind), - resource_to_matching_specifier(Just((inst.resource.clone(), inst.instance.clone()))), - address_to_matching_specifier(Just(inst.address)), - ) - .prop_map(move |(kind, resource, address)| { - (inst.clone(), AccessSpecifierClause { - kind, - resource, - address, - }) - }) - }) -} - -/// Map a strategy of resources to a strategy of specifiers which match them. -fn resource_to_matching_specifier( - resources: impl Strategy)>, -) -> impl Strategy { - resources.prop_flat_map(|(s, ts)| { - prop_oneof![ - Just(ResourceSpecifier::Any), - Just(ResourceSpecifier::DeclaredAtAddress(s.module().address)), - Just(ResourceSpecifier::DeclaredInModule(s.module().clone())), - Just(ResourceSpecifier::Resource(s.clone())), - Just(ResourceSpecifier::ResourceInstantiation(s, ts)) - ] - }) -} - -/// Map a strategy of addresses to a strategy of specifiers which match them. -fn address_to_matching_specifier( - addresses: impl Strategy, -) -> impl Strategy { - addresses.prop_flat_map(|a| { - prop_oneof![ - Just(AddressSpecifier::Any), - Just(AddressSpecifier::Literal(a)) - ] - }) -} diff --git a/third_party/move/tools/move-asm/src/module_builder.rs b/third_party/move/tools/move-asm/src/module_builder.rs index dbbc7797870..212d637d83b 100644 --- a/third_party/move/tools/move-asm/src/module_builder.rs +++ b/third_party/move/tools/move-asm/src/module_builder.rs @@ -962,7 +962,8 @@ impl<'a> ModuleBuilder<'a> { parameters, return_, type_parameters: fhandle.type_parameters.clone(), - access_specifiers: fhandle.access_specifiers.clone(), + // Resource access control has been removed; specifiers are never carried over. + access_specifiers: None, attributes: fhandle.attributes.clone(), }) } else { diff --git a/types/src/on_chain_config/aptos_features.rs b/types/src/on_chain_config/aptos_features.rs index 16bacbb58fe..442a4ad76df 100644 --- a/types/src/on_chain_config/aptos_features.rs +++ b/types/src/on_chain_config/aptos_features.rs @@ -97,7 +97,7 @@ pub enum FeatureFlag { /// Enabled on mainnet, cannot be disabled. _USE_COMPATIBILITY_CHECKER_V2 = 73, ENABLE_ENUM_TYPES = 74, - ENABLE_RESOURCE_ACCESS_CONTROL = 75, + _DEPRECATED_ENABLE_RESOURCE_ACCESS_CONTROL = 75, /// Enabled on mainnet, can never be disabled. _REJECT_UNSTABLE_BYTECODE_FOR_SCRIPT = 76, FEDERATED_KEYLESS = 77, @@ -237,7 +237,6 @@ impl FeatureFlag { FeatureFlag::ALLOW_SERIALIZED_SCRIPT_ARGS, FeatureFlag::_USE_COMPATIBILITY_CHECKER_V2, FeatureFlag::ENABLE_ENUM_TYPES, - FeatureFlag::ENABLE_RESOURCE_ACCESS_CONTROL, FeatureFlag::_REJECT_UNSTABLE_BYTECODE_FOR_SCRIPT, FeatureFlag::TRANSACTION_SIMULATION_ENHANCEMENT, FeatureFlag::NATIVE_MEMORY_OPERATIONS,