tell users to use -t py310
diff --git a/CHANGES.md b/CHANGES.md
index e5f4a1fdf82..dae7df7c9d5 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -4,6 +4,7 @@
 
 ### _Black_
 
+- Point users to using `--target-version py310` if we detect 3.10-only syntax (#2668)
 - Cell magics are now only processed if they are known Python cell magics. Earlier, all
   cell magics were tokenized, leading to possible indentation errors e.g. with
   `%%writefile`. (#2630)
diff --git a/src/black/parsing.py b/src/black/parsing.py
index e38405637cd..825c50eb6d5 100644
--- a/src/black/parsing.py
+++ b/src/black/parsing.py
@@ -42,6 +42,11 @@
         ast3 = ast27 = ast
 
 
+PY310_HINT: Final[
+    str
+] = "Consider using --target-version py310 to parse Python 3.10 code."
+
+
 class InvalidInput(ValueError):
     """Raised when input source code fails all parse attempts."""
 
@@ -95,7 +100,8 @@ def lib2to3_parse(src_txt: str, target_versions: Iterable[TargetVersion] = ()) -
     if not src_txt.endswith("\n"):
         src_txt += "\n"
 
-    for grammar in get_grammars(set(target_versions)):
+    grammars = get_grammars(set(target_versions))
+    for grammar in grammars:
         drv = driver.Driver(grammar)
         try:
             result = drv.parse_string(src_txt, True)
@@ -110,6 +116,12 @@ def lib2to3_parse(src_txt: str, target_versions: Iterable[TargetVersion] = ()) -
                 faulty_line = "<line number missing in source>"
             exc = InvalidInput(f"Cannot parse: {lineno}:{column}: {faulty_line}")
     else:
+        if pygram.python_grammar_soft_keywords not in grammars and matches_grammar(
+            src_txt, pygram.python_grammar_soft_keywords
+        ):
+            original_msg = exc.args[0]
+            msg = f"{original_msg}\n{PY310_HINT}"
+            raise InvalidInput(msg) from None
         raise exc from None
 
     if isinstance(result, Leaf):
@@ -117,6 +129,16 @@ def lib2to3_parse(src_txt: str, target_versions: Iterable[TargetVersion] = ()) -
     return result
 
 
+def matches_grammar(src_txt: str, grammar: Grammar) -> bool:
+    drv = driver.Driver(grammar)
+    try:
+        drv.parse_string(src_txt, True)
+    except ParseError:
+        return False
+    else:
+        return True
+
+
 def lib2to3_unparse(node: Node) -> str:
     """Given a lib2to3 node, return its string representation."""
     code = str(node)
diff --git a/tests/test_format.py b/tests/test_format.py
index d44be1e8712..30099aaf1bc 100644
--- a/tests/test_format.py
+++ b/tests/test_format.py
@@ -210,6 +210,15 @@ def test_patma_invalid() -> None:
     exc_info.match("Cannot parse: 10:11")
 
 
+def test_patma_hint() -> None:
+    source, expected = read_data("pattern_matching_simple")
+    mode = black.Mode(target_versions={black.TargetVersion.PY39})
+    with pytest.raises(black.parsing.InvalidInput) as exc_info:
+        assert_format(source, expected, mode, minimum_version=(3, 10))
+
+    exc_info.match(black.parsing.PY310_HINT)
+
+
 def test_docstring_no_string_normalization() -> None:
     """Like test_docstring but with string normalization off."""
     source, expected = read_data("docstring_no_string_normalization")
