diff --git a/third_party/move/move-compiler-v2/tests/more-v1/expansion/use_struct_overlap_with_module.exp b/third_party/move/move-compiler-v2/tests/more-v1/expansion/use_struct_overlap_with_module.exp index ea5bd62d87125d..c656af63451679 100644 --- a/third_party/move/move-compiler-v2/tests/more-v1/expansion/use_struct_overlap_with_module.exp +++ b/third_party/move/move-compiler-v2/tests/more-v1/expansion/use_struct_overlap_with_module.exp @@ -6,8 +6,5 @@ warning: unused alias 7 │ use 0x2::X::{Self, S as X}; │ ^ Unused 'use' of alias 'X'. Consider removing it -error: variants not allowed in this context - ┌─ tests/more-v1/expansion/use_struct_overlap_with_module.move:8:27 - │ -8 │ struct A { f1: X, f2: X::S } - │ ^^^^ + +============ bytecode verification succeeded ======== 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 871bfcda81727b..b6b08968ccb209 100644 --- a/third_party/move/move-model/src/builder/exp_builder.rs +++ b/third_party/move/move-model/src/builder/exp_builder.rs @@ -3054,10 +3054,11 @@ impl<'env, 'translator, 'module_translator> ExpTranslator<'env, 'translator, 'mo } // Treat this as a call to a global function. - if !self.parent.check_no_variant(maccess) { + let (no_variant, maccess) = self.parent.check_no_variant(maccess); + if !no_variant { return self.new_error_exp(); } - let (module_name, name, _) = self.parent.module_access_to_parts(maccess); + let (module_name, name, _) = self.parent.module_access_to_parts(&maccess); // Process `old(E)` scoping let is_old = 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 5b5cdaeae904cf..062684ad922234 100644 --- a/third_party/move/move-model/src/builder/module_builder.rs +++ b/third_party/move/move-model/src/builder/module_builder.rs @@ -48,7 +48,10 @@ use move_compiler::{ parser::ast as PA, shared::{unique_map::UniqueMap, Identifier, Name}, }; -use move_ir_types::{ast::ConstantName, location::Spanned}; +use move_ir_types::{ + ast::ConstantName, + location::{sp, Spanned}, +}; use regex::Regex; use std::{ cell::RefCell, @@ -250,8 +253,8 @@ impl<'env, 'translator> ModuleBuilder<'env, 'translator> { /// Converts a ModuleAccess into a qualified symbol which can be used for lookup of /// types or functions. If the access has a struct variant, an error is produced. pub fn module_access_to_qualified(&self, access: &EA::ModuleAccess) -> QualifiedSymbol { - self.check_no_variant(access); - let (qsym, _) = self.module_access_to_qualified_with_variant(access); + let (_, access) = self.check_no_variant(access); + let (qsym, _) = self.module_access_to_qualified_with_variant(&access); qsym } @@ -262,15 +265,41 @@ impl<'env, 'translator> ModuleBuilder<'env, 'translator> { ) } - pub fn check_no_variant(&self, maccess: &EA::ModuleAccess) -> bool { + pub fn check_no_variant(&self, maccess: &EA::ModuleAccess) -> (bool, EA::ModuleAccess) { if Self::is_variant(maccess) { - self.parent.env.error( - &self.parent.to_loc(&maccess.loc), - "variants not allowed in this context", - ); - false + if let EA::ModuleAccess_::ModuleAccess(mident, _, Some(var_name)) = &maccess.value { + let addr = self + .parent + .resolve_address(&self.parent.to_loc(&mident.loc), &mident.value.address); + let name = self + .symbol_pool() + .make(mident.value.module.0.value.as_str()); + let module_name = ModuleName::from_address_bytes_and_name(addr, name); + let var_name_sym = self.symbol_pool().make(var_name.value.as_str()); + let qualitifed_name = QualifiedSymbol { + module_name, + symbol: var_name_sym, + }; + if self.parent.struct_table.contains_key(&qualitifed_name) + || self.parent.spec_schema_table.contains_key(&qualitifed_name) + || self.parent.const_table.contains_key(&qualitifed_name) + { + let new_maccess = sp( + maccess.loc, + EA::ModuleAccess_::ModuleAccess(*mident, *var_name, None), + ); + return (true, new_maccess); + } else { + self.parent.env.error( + &self.parent.to_loc(&maccess.loc), + "variants not allowed in this context", + ); + return (false, maccess.clone()); + } + } + (true, maccess.clone()) } else { - true + (true, maccess.clone()) } } @@ -410,7 +439,7 @@ impl<'env, 'translator> ModuleBuilder<'env, 'translator> { self.symbol_pool().make(n.value.as_str()), ), EA::ModuleAccess_::ModuleAccess(mident, n, _) => { - self.check_no_variant(macc); + let (_, macc) = self.check_no_variant(macc); let addr_bytes = self.parent.resolve_address( &self.parent.to_loc(&macc.loc), &mident.value.address,