about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_resolve/late.rs16
-rw-r--r--src/test/ui/binding/ambiguity-item.rs1
2 files changed, 11 insertions, 6 deletions
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index f369e827a40..6214186a901 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -1522,11 +1522,20 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         ident: Ident,
         has_sub: bool,
     ) -> Option<Res> {
+        // An immutable (no `mut`) by-value (no `ref`) binding pattern without
+        // a sub pattern (no `@ $pat`) is syntactically ambiguous as it could
+        // also be interpreted as a path to e.g. a constant, variant, etc.
+        let is_syntactic_ambiguity = !has_sub && bm == BindingMode::ByValue(Mutability::Not);
+
         let ls_binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, None, pat.span)?;
         let (res, binding) = match ls_binding {
-            LexicalScopeBinding::Item(binding) if binding.is_ambiguity() => {
+            LexicalScopeBinding::Item(binding)
+                if is_syntactic_ambiguity && binding.is_ambiguity() =>
+            {
                 // For ambiguous bindings we don't know all their definitions and cannot check
                 // whether they can be shadowed by fresh bindings or not, so force an error.
+                // issues/33118#issuecomment-233962221 (see below) still applies here,
+                // but we have to ignore it for backward compatibility.
                 self.r.record_use(ident, ValueNS, binding, false);
                 return None;
             }
@@ -1534,11 +1543,6 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             LexicalScopeBinding::Res(res) => (res, None),
         };
 
-        // An immutable (no `mut`) by-value (no `ref`) binding pattern without
-        // a sub pattern (no `@ $pat`) is syntactically ambiguous as it could
-        // also be interpreted as a path to e.g. a constant, variant, etc.
-        let is_syntactic_ambiguity = !has_sub && bm == BindingMode::ByValue(Mutability::Not);
-
         match res {
             Res::SelfCtor(_) // See #70549.
             | Res::Def(
diff --git a/src/test/ui/binding/ambiguity-item.rs b/src/test/ui/binding/ambiguity-item.rs
index 10613cc6164..0f48340c2cd 100644
--- a/src/test/ui/binding/ambiguity-item.rs
+++ b/src/test/ui/binding/ambiguity-item.rs
@@ -14,5 +14,6 @@ fn main() {
     let v = f; //~ ERROR `f` is ambiguous
     match v {
         f => {} //~ ERROR `f` is ambiguous
+        mut f => {} // OK, unambiguously a fresh binding due to `mut`
     }
 }