diff --git a/external-crates/move/crates/move-compiler/src/expansion/ast.rs b/external-crates/move/crates/move-compiler/src/expansion/ast.rs index 2d261314788b9..51f2e732af3b6 100644 --- a/external-crates/move/crates/move-compiler/src/expansion/ast.rs +++ b/external-crates/move/crates/move-compiler/src/expansion/ast.rs @@ -327,7 +327,7 @@ pub enum ExpDotted_ { Exp(Box), Dot(Box, Name), Index(Box, Spanned>), - DotUnresolved(Box), // dot where Name could not be parsed + DotUnresolved(Loc, Box), // dot where Name could not be parsed } pub type ExpDotted = Spanned; @@ -1735,7 +1735,7 @@ impl AstDebug for ExpDotted_ { w.comma(&rhs.value, |w, e| e.ast_debug(w)); w.write("]"); } - D::DotUnresolved(e) => { + D::DotUnresolved(_, e) => { e.ast_debug(w); w.write("") } diff --git a/external-crates/move/crates/move-compiler/src/expansion/translate.rs b/external-crates/move/crates/move-compiler/src/expansion/translate.rs index c50be73c7f9f2..3a89e427f8298 100644 --- a/external-crates/move/crates/move-compiler/src/expansion/translate.rs +++ b/external-crates/move/crates/move-compiler/src/expansion/translate.rs @@ -2632,7 +2632,7 @@ fn exp(context: &mut Context, pe: Box) -> Box { EE::UnresolvedError } }, - pdotted_ @ (PE::Dot(_, _) | PE::DotUnresolved(_)) => { + pdotted_ @ (PE::Dot(_, _) | PE::DotUnresolved(_, _)) => { match exp_dotted(context, Box::new(sp(loc, pdotted_))) { Some(edotted) => EE::ExpDotted(E::DottedUsage::Use, edotted), None => { @@ -2740,7 +2740,7 @@ fn exp_cast(context: &mut Context, in_parens: bool, plhs: Box, pty: P::T PE::DotCall(lhs, _, _, _, _) | PE::Dot(lhs, _) - | PE::DotUnresolved(lhs) + | PE::DotUnresolved(_, lhs) | PE::Index(lhs, _) | PE::Borrow(_, lhs) | PE::Dereference(lhs) => ambiguous_cast(lhs), @@ -2857,7 +2857,9 @@ fn move_or_copy_path_(context: &mut Context, case: PathCase, pe: Box) -> return None; } } - E::ExpDotted_::Dot(_, _) | E::ExpDotted_::DotUnresolved(_) | E::ExpDotted_::Index(_, _) => { + E::ExpDotted_::Dot(_, _) + | E::ExpDotted_::DotUnresolved(_, _) + | E::ExpDotted_::Index(_, _) => { let current_package = context.current_package(); context .env() @@ -2895,9 +2897,9 @@ fn exp_dotted(context: &mut Context, pdotted: Box) -> Option>(); EE::Index(lhs, sp(argloc, args)) } - PE::DotUnresolved(plhs) => { + PE::DotUnresolved(loc, plhs) => { let lhs = exp_dotted(context, plhs)?; - EE::DotUnresolved(lhs) + EE::DotUnresolved(loc, lhs) } pe_ => EE::Exp(exp(context, Box::new(sp(loc, pe_)))), }; diff --git a/external-crates/move/crates/move-compiler/src/hlir/detect_dead_code.rs b/external-crates/move/crates/move-compiler/src/hlir/detect_dead_code.rs index 4ccda256b67be..9323c4284e56f 100644 --- a/external-crates/move/crates/move-compiler/src/hlir/detect_dead_code.rs +++ b/external-crates/move/crates/move-compiler/src/hlir/detect_dead_code.rs @@ -532,7 +532,8 @@ fn value(context: &mut Context, e: &T::Exp) -> Option { | E::UnaryExp(_, base_exp) | E::Borrow(_, base_exp, _) | E::Cast(base_exp, _) - | E::TempBorrow(_, base_exp) => value_report!(base_exp), + | E::TempBorrow(_, base_exp) + | E::InvalidAccess(base_exp) => value_report!(base_exp), E::BorrowLocal(_, _) => None, @@ -746,6 +747,7 @@ fn statement(context: &mut Context, e: &T::Exp) -> Option { | E::ErrorConstant(_) | E::Move { .. } | E::Copy { .. } + | E::InvalidAccess(_) | E::UnresolvedError => value(context, e), E::Value(_) | E::Unit { .. } => None, diff --git a/external-crates/move/crates/move-compiler/src/hlir/translate.rs b/external-crates/move/crates/move-compiler/src/hlir/translate.rs index 126c4e02e5782..d99d5224cac59 100644 --- a/external-crates/move/crates/move-compiler/src/hlir/translate.rs +++ b/external-crates/move/crates/move-compiler/src/hlir/translate.rs @@ -1803,7 +1803,7 @@ fn value( context.env.add_diag(ice!((eloc, "ICE unexpanded use"))); error_exp(eloc) } - E::UnresolvedError => { + E::UnresolvedError | E::InvalidAccess(_) => { assert!(context.env.has_errors()); make_exp(HE::UnresolvedError) } @@ -2160,6 +2160,7 @@ fn statement(context: &mut Context, block: &mut Block, e: T::Exp) { | E::Move { .. } | E::Copy { .. } | E::UnresolvedError + | E::InvalidAccess(_) | E::NamedBlock(_, _)) => value_statement(context, block, make_exp(e_)), E::Value(_) | E::Unit { .. } => (), diff --git a/external-crates/move/crates/move-compiler/src/naming/ast.rs b/external-crates/move/crates/move-compiler/src/naming/ast.rs index 6e089684f6c0b..2b40244cc8839 100644 --- a/external-crates/move/crates/move-compiler/src/naming/ast.rs +++ b/external-crates/move/crates/move-compiler/src/naming/ast.rs @@ -356,7 +356,7 @@ pub enum ExpDotted_ { Exp(Box), Dot(Box, Field), Index(Box, Spanned>), - DotUnresolved(Box), // dot where Field could not be parsed + DotUnresolved(Loc, Box), // Dot (and its location) where Field could not be parsed } pub type ExpDotted = Spanned; @@ -1860,7 +1860,7 @@ impl AstDebug for ExpDotted_ { w.comma(args, |w, e| e.ast_debug(w)); w.write(")"); } - D::DotUnresolved(e) => { + D::DotUnresolved(_, e) => { e.ast_debug(w); w.write(".") } diff --git a/external-crates/move/crates/move-compiler/src/naming/resolve_use_funs.rs b/external-crates/move/crates/move-compiler/src/naming/resolve_use_funs.rs index ae7238e0b0717..4af8ff8a7b361 100644 --- a/external-crates/move/crates/move-compiler/src/naming/resolve_use_funs.rs +++ b/external-crates/move/crates/move-compiler/src/naming/resolve_use_funs.rs @@ -400,7 +400,7 @@ fn exp(context: &mut Context, sp!(_, e_): &mut N::Exp) { fn exp_dotted(context: &mut Context, sp!(_, ed_): &mut N::ExpDotted) { match ed_ { N::ExpDotted_::Exp(e) => exp(context, e), - N::ExpDotted_::Dot(ed, _) | N::ExpDotted_::DotUnresolved(ed) => exp_dotted(context, ed), + N::ExpDotted_::Dot(ed, _) | N::ExpDotted_::DotUnresolved(_, ed) => exp_dotted(context, ed), N::ExpDotted_::Index(ed, sp!(_, es)) => { exp_dotted(context, ed); for e in es { diff --git a/external-crates/move/crates/move-compiler/src/naming/translate.rs b/external-crates/move/crates/move-compiler/src/naming/translate.rs index 0a8fe48efdd91..3c6f1848f0333 100644 --- a/external-crates/move/crates/move-compiler/src/naming/translate.rs +++ b/external-crates/move/crates/move-compiler/src/naming/translate.rs @@ -2416,8 +2416,8 @@ fn dotted(context: &mut Context, edot: E::ExpDotted) -> Option { } } E::ExpDotted_::Dot(d, f) => N::ExpDotted_::Dot(Box::new(dotted(context, *d)?), Field(f)), - E::ExpDotted_::DotUnresolved(d) => { - N::ExpDotted_::DotUnresolved(Box::new(dotted(context, *d)?)) + E::ExpDotted_::DotUnresolved(loc, d) => { + N::ExpDotted_::DotUnresolved(loc, Box::new(dotted(context, *d)?)) } E::ExpDotted_::Index(inner, args) => { let args = call_args(context, args); @@ -3455,7 +3455,7 @@ fn remove_unused_bindings_exp_dotted( ) { match ed_ { N::ExpDotted_::Exp(e) => remove_unused_bindings_exp(context, used, e), - N::ExpDotted_::Dot(ed, _) | N::ExpDotted_::DotUnresolved(ed) => { + N::ExpDotted_::Dot(ed, _) | N::ExpDotted_::DotUnresolved(_, ed) => { remove_unused_bindings_exp_dotted(context, used, ed) } N::ExpDotted_::Index(ed, sp!(_, es)) => { diff --git a/external-crates/move/crates/move-compiler/src/parser/ast.rs b/external-crates/move/crates/move-compiler/src/parser/ast.rs index 2c5d25aaff830..3d474e5fa8664 100644 --- a/external-crates/move/crates/move-compiler/src/parser/ast.rs +++ b/external-crates/move/crates/move-compiler/src/parser/ast.rs @@ -624,8 +624,8 @@ pub enum Exp_ { // Internal node marking an error was added to the error list // This is here so the pass can continue even when an error is hit UnresolvedError, - // e.X (where X is not a valid tok after dot and cannot be parsed) - DotUnresolved(Box), + // e.X, where X is not a valid tok after dot and cannot be parsed (includes location of the dot) + DotUnresolved(Loc, Box), } pub type Exp = Spanned; @@ -2105,7 +2105,7 @@ impl AstDebug for Exp_ { w.write(&s.value); } E::UnresolvedError => w.write("_|_"), - E::DotUnresolved(e) => { + E::DotUnresolved(_, e) => { e.ast_debug(w); w.write("."); } diff --git a/external-crates/move/crates/move-compiler/src/parser/syntax.rs b/external-crates/move/crates/move-compiler/src/parser/syntax.rs index 485974c6feedb..b6b789632065a 100644 --- a/external-crates/move/crates/move-compiler/src/parser/syntax.rs +++ b/external-crates/move/crates/move-compiler/src/parser/syntax.rs @@ -2590,7 +2590,7 @@ fn parse_dot_or_index_chain(context: &mut Context) -> Result match parse_identifier(context) { Err(diag) => { context.add_diag(*diag); - Exp_::DotUnresolved(Box::new(lhs)) + Exp_::DotUnresolved(loc, Box::new(lhs)) } Ok(n) => { if is_start_of_call_after_function_name(context, &n) { diff --git a/external-crates/move/crates/move-compiler/src/typing/ast.rs b/external-crates/move/crates/move-compiler/src/typing/ast.rs index f1efdaf8c7b02..164e1746e1333 100644 --- a/external-crates/move/crates/move-compiler/src/typing/ast.rs +++ b/external-crates/move/crates/move-compiler/src/typing/ast.rs @@ -233,6 +233,9 @@ pub enum UnannotatedExp_ { Cast(Box, Box), Annotate(Box, Box), + // unfinished dot access (e.g. `some_field.`) + InvalidAccess(Box), + ErrorConstant(Option), UnresolvedError, } @@ -806,6 +809,10 @@ impl AstDebug for UnannotatedExp_ { ty.ast_debug(w); w.write(")"); } + E::InvalidAccess(e) => { + e.ast_debug(w); + w.write("."); + } E::UnresolvedError => w.write("_|_"), E::ErrorConstant(constant) => { w.write("ErrorConstant"); diff --git a/external-crates/move/crates/move-compiler/src/typing/dependency_ordering.rs b/external-crates/move/crates/move-compiler/src/typing/dependency_ordering.rs index 0209a20b84b37..36e5311bf497f 100644 --- a/external-crates/move/crates/move-compiler/src/typing/dependency_ordering.rs +++ b/external-crates/move/crates/move-compiler/src/typing/dependency_ordering.rs @@ -477,6 +477,7 @@ fn exp(context: &mut Context, e: &T::Exp) { exp(context, e); type_(context, ty) } + E::InvalidAccess(e) => exp(context, e), E::Unit { .. } | E::Value(_) | E::Move { .. } diff --git a/external-crates/move/crates/move-compiler/src/typing/expand.rs b/external-crates/move/crates/move-compiler/src/typing/expand.rs index ab274eb90b0d8..7aff4a0f67b03 100644 --- a/external-crates/move/crates/move-compiler/src/typing/expand.rs +++ b/external-crates/move/crates/move-compiler/src/typing/expand.rs @@ -270,7 +270,8 @@ pub fn exp(context: &mut Context, e: &mut T::Exp) { | E::Dereference(er) | E::UnaryExp(_, er) | E::Borrow(_, er, _) - | E::TempBorrow(_, er) => exp(context, er), + | E::TempBorrow(_, er) + | E::InvalidAccess(er) => exp(context, er), E::Mutate(el, er) => { exp(context, el); exp(context, er) diff --git a/external-crates/move/crates/move-compiler/src/typing/infinite_instantiations.rs b/external-crates/move/crates/move-compiler/src/typing/infinite_instantiations.rs index 6173613f215bc..e7a6deac5d5e9 100644 --- a/external-crates/move/crates/move-compiler/src/typing/infinite_instantiations.rs +++ b/external-crates/move/crates/move-compiler/src/typing/infinite_instantiations.rs @@ -276,7 +276,8 @@ fn exp(context: &mut Context, e: &T::Exp) { | E::Dereference(er) | E::UnaryExp(_, er) | E::Borrow(_, er, _) - | E::TempBorrow(_, er) => exp(context, er), + | E::TempBorrow(_, er) + | E::InvalidAccess(er) => exp(context, er), E::Mutate(el, er) | E::BinopExp(el, _, _, er) => { exp(context, el); exp(context, er) diff --git a/external-crates/move/crates/move-compiler/src/typing/macro_expand.rs b/external-crates/move/crates/move-compiler/src/typing/macro_expand.rs index 554d960222b96..3e2e71171babe 100644 --- a/external-crates/move/crates/move-compiler/src/typing/macro_expand.rs +++ b/external-crates/move/crates/move-compiler/src/typing/macro_expand.rs @@ -630,7 +630,9 @@ fn recolor_exp(ctx: &mut Recolor, sp!(_, e_): &mut N::Exp) { fn recolor_exp_dotted(ctx: &mut Recolor, sp!(_, ed_): &mut N::ExpDotted) { match ed_ { N::ExpDotted_::Exp(e) => recolor_exp(ctx, e), - N::ExpDotted_::Dot(ed, _) | N::ExpDotted_::DotUnresolved(ed) => recolor_exp_dotted(ctx, ed), + N::ExpDotted_::Dot(ed, _) | N::ExpDotted_::DotUnresolved(_, ed) => { + recolor_exp_dotted(ctx, ed) + } N::ExpDotted_::Index(ed, sp!(_, es)) => { recolor_exp_dotted(ctx, ed); for e in es { @@ -1088,7 +1090,7 @@ fn builtin_function(context: &mut Context, sp!(_, bf_): &mut N::BuiltinFunction) fn exp_dotted(context: &mut Context, sp!(_, ed_): &mut N::ExpDotted) { match ed_ { N::ExpDotted_::Exp(e) => exp(context, e), - N::ExpDotted_::Dot(ed, _) | N::ExpDotted_::DotUnresolved(ed) => exp_dotted(context, ed), + N::ExpDotted_::Dot(ed, _) | N::ExpDotted_::DotUnresolved(_, ed) => exp_dotted(context, ed), N::ExpDotted_::Index(ed, sp!(_, es)) => { exp_dotted(context, ed); for e in es { diff --git a/external-crates/move/crates/move-compiler/src/typing/translate.rs b/external-crates/move/crates/move-compiler/src/typing/translate.rs index 99316bf7fc70e..bbf8b76c56c75 100644 --- a/external-crates/move/crates/move-compiler/src/typing/translate.rs +++ b/external-crates/move/crates/move-compiler/src/typing/translate.rs @@ -477,7 +477,11 @@ mod check_valid_constant { //***************************************** // Error cases handled elsewhere //***************************************** - E::Use(_) | E::Continue(_) | E::Give(_, _) | E::UnresolvedError => return, + E::Use(_) + | E::Continue(_) + | E::Give(_, _) + | E::UnresolvedError + | E::InvalidAccess(_) => return, //***************************************** // Valid cases @@ -2933,7 +2937,7 @@ enum ExpDottedAccess { args: Spanned>, base_type: Type, /* base (non-ref) return type */ }, - UnresolvedError, + UnresolvedError(/* dot's location */ Loc), // whatever came after dot could not be parsed } #[derive(Debug)] @@ -2962,7 +2966,7 @@ impl ExpDotted { match accessor { ExpDottedAccess::Field(_, ty) => ty.clone(), ExpDottedAccess::Index { base_type, .. } => base_type.clone(), - ExpDottedAccess::UnresolvedError => sp(Loc::invalid(), Type_::UnresolvedError), + ExpDottedAccess::UnresolvedError(_) => sp(Loc::invalid(), Type_::UnresolvedError), } } else { self.base_type.clone() @@ -3014,9 +3018,9 @@ fn process_exp_dotted( .push(ExpDottedAccess::Field(field, field_type)); inner } - N::ExpDotted_::DotUnresolved(ndot) => { + N::ExpDotted_::DotUnresolved(loc, ndot) => { let mut inner = process_exp_dotted(context, Some("dot access"), *ndot); - inner.accessors.push(ExpDottedAccess::UnresolvedError); + inner.accessors.push(ExpDottedAccess::UnresolvedError(loc)); inner } N::ExpDotted_::Index(ndot, sp!(argloc, nargs_)) => { @@ -3058,7 +3062,7 @@ fn exp_dotted_usage( let constraint_verb = match &ndotted.value { N::ExpDotted_::Exp(_) => None, _ if matches!(usage, DottedUsage::Borrow(_)) => Some("borrow"), - N::ExpDotted_::Dot(_, _) | N::ExpDotted_::DotUnresolved(_) => Some("dot access"), + N::ExpDotted_::Dot(_, _) | N::ExpDotted_::DotUnresolved(_, _) => Some("dot access"), N::ExpDotted_::Index(_, _) => Some("index"), }; let edotted = process_exp_dotted(context, constraint_verb, ndotted); @@ -3296,8 +3300,7 @@ fn borrow_exp_dotted(context: &mut Context, mut_: bool, ed: ExpDotted) -> Box Box::new(base), }; - let num_accessors = accessors.len(); - for (idx, accessor) in accessors.into_iter().enumerate() { + for accessor in accessors { check_mut(context, loc, exp.ty.clone(), mut_); match accessor { ExpDottedAccess::Field(name, ty) => { @@ -3353,8 +3356,9 @@ fn borrow_exp_dotted(context: &mut Context, mut_: bool, ed: ExpDotted) -> Box { - assert!(idx == num_accessors - 1); + ExpDottedAccess::UnresolvedError(loc) => { + let t = sp(Loc::invalid(), Type_::UnresolvedError); + exp = Box::new(T::exp(t, sp(loc, T::UnannotatedExp_::InvalidAccess(exp)))); break; } } @@ -3385,7 +3389,7 @@ fn exp_dotted_to_owned(context: &mut Context, usage: DottedUsage, ed: ExpDotted) ExpDottedAccess::Index { base_type, .. } => { ("index result".to_string(), base_type.clone()) } - ExpDottedAccess::UnresolvedError => ( + ExpDottedAccess::UnresolvedError(_) => ( "unresolved field".to_string(), sp(Loc::invalid(), Type_::UnresolvedError), ), diff --git a/external-crates/move/crates/move-compiler/src/typing/visitor.rs b/external-crates/move/crates/move-compiler/src/typing/visitor.rs index ad81521d2eadd..1bf2adb98b124 100644 --- a/external-crates/move/crates/move-compiler/src/typing/visitor.rs +++ b/external-crates/move/crates/move-compiler/src/typing/visitor.rs @@ -222,6 +222,7 @@ pub trait TypingVisitorContext { E::TempBorrow(_, e) => self.visit_exp(e), E::Cast(e, _) => self.visit_exp(e), E::Annotate(e, _) => self.visit_exp(e), + E::InvalidAccess(e) => self.visit_exp(e), E::Unit { .. } | E::Value(_) | E::Move { .. }