diff --git a/pydantic/fields.py b/pydantic/fields.py
--- a/pydantic/fields.py
+++ b/pydantic/fields.py
@@ -554,13 +554,13 @@ def _type_analysis(self) -> None:  # noqa: C901 (ignore complexity)
             if isinstance(self.type_, type) and isinstance(None, self.type_):
                 self.allow_none = True
             return
-        if origin is Annotated:
+        elif origin is Annotated:
             self.type_ = get_args(self.type_)[0]
             self._type_analysis()
             return
-        if origin is Callable:
+        elif origin is Callable:
             return
-        if is_union(origin):
+        elif is_union(origin):
             types_ = []
             for type_ in get_args(self.type_):
                 if type_ is NoneType:
@@ -580,8 +580,7 @@ def _type_analysis(self) -> None:  # noqa: C901 (ignore complexity)
             else:
                 self.sub_fields = [self._create_sub_type(t, f'{self.name}_{display_as_type(t)}') for t in types_]
             return
-
-        if issubclass(origin, Tuple):  # type: ignore
+        elif issubclass(origin, Tuple):  # type: ignore
             # origin == Tuple without item type
             args = get_args(self.type_)
             if not args:  # plain tuple
@@ -599,8 +598,7 @@ def _type_analysis(self) -> None:  # noqa: C901 (ignore complexity)
                 self.shape = SHAPE_TUPLE
                 self.sub_fields = [self._create_sub_type(t, f'{self.name}_{i}') for i, t in enumerate(args)]
             return
-
-        if issubclass(origin, List):
+        elif issubclass(origin, List):
             # Create self validators
             get_validators = getattr(self.type_, '__get_validators__', None)
             if get_validators:
@@ -636,6 +634,11 @@ def _type_analysis(self) -> None:  # noqa: C901 (ignore complexity)
         elif issubclass(origin, Sequence):
             self.type_ = get_args(self.type_)[0]
             self.shape = SHAPE_SEQUENCE
+        # priority to most common mapping: dict
+        elif origin is dict or origin is Dict:
+            self.key_field = self._create_sub_type(get_args(self.type_)[0], 'key_' + self.name, for_keys=True)
+            self.type_ = get_args(self.type_)[1]
+            self.shape = SHAPE_DICT
         elif issubclass(origin, DefaultDict):
             self.key_field = self._create_sub_type(get_args(self.type_)[0], 'key_' + self.name, for_keys=True)
             self.type_ = get_args(self.type_)[1]
@@ -644,10 +647,6 @@ def _type_analysis(self) -> None:  # noqa: C901 (ignore complexity)
             self.key_field = self._create_sub_type(get_args(self.type_)[0], 'key_' + self.name, for_keys=True)
             self.type_ = int
             self.shape = SHAPE_COUNTER
-        elif issubclass(origin, Dict):
-            self.key_field = self._create_sub_type(get_args(self.type_)[0], 'key_' + self.name, for_keys=True)
-            self.type_ = get_args(self.type_)[1]
-            self.shape = SHAPE_DICT
         elif issubclass(origin, Mapping):
             self.key_field = self._create_sub_type(get_args(self.type_)[0], 'key_' + self.name, for_keys=True)
             self.type_ = get_args(self.type_)[1]

diff --git a/tests/test_main.py b/tests/test_main.py
--- a/tests/test_main.py
+++ b/tests/test_main.py
@@ -2,7 +2,20 @@
 from collections import defaultdict
 from copy import deepcopy
 from enum import Enum
-from typing import Any, Callable, ClassVar, Counter, DefaultDict, Dict, List, Mapping, Optional, Type, get_type_hints
+from typing import (
+    Any,
+    Callable,
+    ClassVar,
+    Counter,
+    DefaultDict,
+    Dict,
+    List,
+    Mapping,
+    Optional,
+    Type,
+    TypeVar,
+    get_type_hints,
+)
 from uuid import UUID, uuid4
 
 import pytest
@@ -1976,6 +1989,27 @@ class Model(BaseModel):
     assert repr(m) == "Model(x={'one': 1, 'two': 2})"
 
 
+@pytest.mark.skipif(sys.version_info < (3, 7), reason='generic classes need 3.7')
+def test_typing_non_coercion_of_dict_subclasses():
+    KT = TypeVar('KT')
+    VT = TypeVar('VT')
+
+    class MyDict(Dict[KT, VT]):
+        def __repr__(self):
+            return f'MyDict({super().__repr__()})'
+
+    class Model(BaseModel):
+        a: MyDict
+        b: MyDict[str, int]
+        c: Dict[str, int]
+        d: Mapping[str, int]
+
+    assert (
+        repr(Model(a=MyDict({'a': 1}), b=MyDict({'a': '1'}), c=MyDict({'a': '1'}), d=MyDict({'a': '1'})))
+        == "Model(a=MyDict({'a': 1}), b=MyDict({'a': 1}), c={'a': 1}, d=MyDict({'a': 1}))"
+    )
+
+
 def test_typing_coercion_defaultdict():
     class Model(BaseModel):
         x: DefaultDict[int, str]

AttributeError: name with frozendict[..., ...] and subclass (maybe Mapping+GenericAlias issue?)
# Bug

Using a [`frozendict`](https://github.com/Marco-Sulla/python-frozendict) as a model field works normally/correctly but when subscripted (eg: `frozendict[str, int]`), pydantic errors in some weird ways:
- the output has a `dict` (similar to #2311 and others, except even converting to `frozendict` explicitly or in a `@validator` doesn't work)
- on model subclasses, the `field.outer_type_` seems to be botched and missing attributes (but works fine on the original defining class)

```py
# pip3 install frozendict
from frozendict import frozendict
from pydantic import BaseModel


class Base(BaseModel):
    a: frozendict
    b: frozendict[str, int]


class Sub(Base):
    pass


def inspect(m: BaseModel):
    print(f"\t{m.__name__}\n")
    print(m(a=frozendict(a=1), b=frozendict(b=1)))
    print(m.__fields__)
    print(m.__fields__["b"].outer_type_)


# This doesn't error, but the sub-typed variant is replaced with a dict and the Field is a Mapping
inspect(Base)
# This errors when inspecting `b` ModelField.outer_type_, seemingly trying to access an uninitialized .name
inspect(Sub)
```
outputs
```
        Base

a=frozendict({'a': 1}) b={'b': 1}
{'a': ModelField(name='a', type=frozendict, required=True), 'b': ModelField(name='b', type=Mapping[str, int], required=True)}
frozendict.core.frozendict[str, int]
        Sub

a=frozendict({'a': 1}) b={'b': 1}
{'a': ModelField(name='a', type=frozendict, required=True), 'b': ModelField(name='b', type=Mapping[str, int], required=True)}
Traceback (most recent call last):
  File "/tmp/pydantic_error.py", line 25, in <module>
    inspect(Sub)
  File "/tmp/pydantic_error.py", line 19, in inspect
    print(m.__fields__["b"].outer_type_)
  File "pydantic/utils.py", line 396, in pydantic.utils.Representation.__repr__
  File "pydantic/utils.py", line 375, in genexpr
  File "pydantic/utils.py", line 375, in genexpr
  File "pydantic/fields.py", line 951, in pydantic.fields.ModelField.__repr_args__
AttributeError: name
```

The `type(frozendict[str, int])` is a `GenericAlias` and otherwise seems to be normal:

```
>>> type(frozendict[str, str])
<class 'types.GenericAlias'>
>>> get_origin(frozendict[str, str])
<class 'frozendict.core.frozendict'>
>>> get_args(frozendict[str, str])
(<class 'str'>, <class 'str'>)
>>>
>>>
>>> type(dict[str, str])
<class 'types.GenericAlias'>
>>> get_origin(dict[str, str])
<class 'dict'>
>>> get_args(dict[str, str])
(<class 'str'>, <class 'str'>)
```

### Checks

* [x] I added a descriptive title to this issue
* [x] I have searched (google, github) for similar issues and couldn't find anything
* [x] I have read and followed [the docs](https://pydantic-docs.helpmanual.io/) and still think this is a bug

Output of `python -c "import pydantic.utils; print(pydantic.utils.version_info())"`:
```
             pydantic version: 1.8.2
            pydantic compiled: True
                 install path: /Users/jacobhayes/src/github.com/replicahq/artigraph/.wt/type-dispatch/.direnv/python-3.9.6/lib/python3.9/site-packages/pydantic
               python version: 3.9.6 (default, Jul 20 2021, 13:51:27)  [Clang 12.0.5 (clang-1205.0.22.9)]
                     platform: macOS-11.4-x86_64-i386-64bit
     optional deps. installed: ['typing-extensions']
```

tests/test_main.py::test_typing_non_coercion_of_dict_subclasses
tests/test_main.py::test_success tests/test_main.py::test_ultra_simple_missing tests/test_main.py::test_ultra_simple_failed tests/test_main.py::test_ultra_simple_repr tests/test_main.py::test_default_factory_field tests/test_main.py::test_default_factory_no_type_field tests/test_main.py::test_comparing tests/test_main.py::test_nullable_strings_success tests/test_main.py::test_nullable_strings_fails tests/test_main.py::test_recursion tests/test_main.py::test_recursion_fails tests/test_main.py::test_not_required tests/test_main.py::test_infer_type tests/test_main.py::test_allow_extra tests/test_main.py::test_forbidden_extra_success tests/test_main.py::test_forbidden_extra_fails tests/test_main.py::test_disallow_mutation tests/test_main.py::test_extra_allowed tests/test_main.py::test_extra_ignored tests/test_main.py::test_set_attr tests/test_main.py::test_set_attr_invalid tests/test_main.py::test_any tests/test_main.py::test_alias tests/test_main.py::test_population_by_field_name tests/test_main.py::test_field_order tests/test_main.py::test_required tests/test_main.py::test_mutability tests/test_main.py::test_immutability[False-False] tests/test_main.py::test_immutability[False-True] tests/test_main.py::test_immutability[True-True] tests/test_main.py::test_not_frozen_are_not_hashable tests/test_main.py::test_with_declared_hash tests/test_main.py::test_frozen_with_hashable_fields_are_hashable tests/test_main.py::test_frozen_with_unhashable_fields_are_not_hashable tests/test_main.py::test_hash_function_give_different_result_for_different_object tests/test_main.py::test_const_validates tests/test_main.py::test_const_uses_default tests/test_main.py::test_const_validates_after_type_validators tests/test_main.py::test_const_with_wrong_value tests/test_main.py::test_const_with_validator tests/test_main.py::test_const_list tests/test_main.py::test_const_list_with_wrong_value tests/test_main.py::test_const_validation_json_serializable tests/test_main.py::test_validating_assignment_pass tests/test_main.py::test_validating_assignment_fail tests/test_main.py::test_validating_assignment_pre_root_validator_fail tests/test_main.py::test_validating_assignment_post_root_validator_fail tests/test_main.py::test_root_validator_many_values_change tests/test_main.py::test_enum_values tests/test_main.py::test_literal_enum_values tests/test_main.py::test_enum_raw tests/test_main.py::test_set_tuple_values tests/test_main.py::test_default_copy tests/test_main.py::test_arbitrary_type_allowed_validation_success tests/test_main.py::test_arbitrary_type_allowed_validation_fails tests/test_main.py::test_arbitrary_types_not_allowed tests/test_main.py::test_type_type_validation_success tests/test_main.py::test_type_type_subclass_validation_success tests/test_main.py::test_type_type_validation_fails_for_instance tests/test_main.py::test_type_type_validation_fails_for_basic_type tests/test_main.py::test_bare_type_type_validation_success tests/test_main.py::test_bare_type_type_validation_fails tests/test_main.py::test_annotation_field_name_shadows_attribute tests/test_main.py::test_value_field_name_shadows_attribute tests/test_main.py::test_class_var tests/test_main.py::test_fields_set tests/test_main.py::test_exclude_unset_dict tests/test_main.py::test_exclude_unset_recursive tests/test_main.py::test_dict_exclude_unset_populated_by_alias tests/test_main.py::test_dict_exclude_unset_populated_by_alias_with_extra tests/test_main.py::test_exclude_defaults tests/test_main.py::test_dir_fields tests/test_main.py::test_dict_with_extra_keys tests/test_main.py::test_root tests/test_main.py::test_root_list tests/test_main.py::test_root_nested tests/test_main.py::test_encode_nested_root tests/test_main.py::test_root_failed tests/test_main.py::test_root_undefined_failed tests/test_main.py::test_parse_root_as_mapping tests/test_main.py::test_parse_obj_non_mapping_root tests/test_main.py::test_parse_obj_nested_root tests/test_main.py::test_untouched_types tests/test_main.py::test_custom_types_fail_without_keep_untouched tests/test_main.py::test_model_iteration tests/test_main.py::test_model_export_nested_list[excluding tests/test_main.py::test_model_export_nested_list[should tests/test_main.py::test_model_export_nested_list[using tests/test_main.py::test_model_export_dict_exclusion[excluding tests/test_main.py::test_model_export_dict_exclusion[using tests/test_main.py::test_model_export_dict_exclusion[exclude tests/test_main.py::test_model_exclude_config_field_merging tests/test_main.py::test_model_export_exclusion_with_fields_and_config[None-expected0-kinds0] tests/test_main.py::test_model_export_exclusion_with_fields_and_config[None-expected0-kinds1] tests/test_main.py::test_model_export_exclusion_with_fields_and_config[None-expected0-kinds2] tests/test_main.py::test_model_export_exclusion_with_fields_and_config[None-expected0-kinds3] tests/test_main.py::test_model_export_exclusion_with_fields_and_config[None-expected0-kinds4] tests/test_main.py::test_model_export_exclusion_with_fields_and_config[None-expected0-kinds5] tests/test_main.py::test_model_export_exclusion_with_fields_and_config[None-expected0-kinds6] tests/test_main.py::test_model_export_exclusion_with_fields_and_config[exclude1-expected1-kinds0] tests/test_main.py::test_model_export_exclusion_with_fields_and_config[exclude1-expected1-kinds1] tests/test_main.py::test_model_export_exclusion_with_fields_and_config[exclude1-expected1-kinds2] tests/test_main.py::test_model_export_exclusion_with_fields_and_config[exclude1-expected1-kinds3] tests/test_main.py::test_model_export_exclusion_with_fields_and_config[exclude1-expected1-kinds4] tests/test_main.py::test_model_export_exclusion_with_fields_and_config[exclude1-expected1-kinds5] tests/test_main.py::test_model_export_exclusion_with_fields_and_config[exclude1-expected1-kinds6] tests/test_main.py::test_model_export_exclusion_with_fields_and_config[exclude2-expected2-kinds0] tests/test_main.py::test_model_export_exclusion_with_fields_and_config[exclude2-expected2-kinds1] tests/test_main.py::test_model_export_exclusion_with_fields_and_config[exclude2-expected2-kinds2] tests/test_main.py::test_model_export_exclusion_with_fields_and_config[exclude2-expected2-kinds3] tests/test_main.py::test_model_export_exclusion_with_fields_and_config[exclude2-expected2-kinds4] tests/test_main.py::test_model_export_exclusion_with_fields_and_config[exclude2-expected2-kinds5] tests/test_main.py::test_model_export_exclusion_with_fields_and_config[exclude2-expected2-kinds6] tests/test_main.py::test_model_export_exclusion_inheritance tests/test_main.py::test_model_export_with_true_instead_of_ellipsis tests/test_main.py::test_model_export_inclusion tests/test_main.py::test_model_export_inclusion_inheritance tests/test_main.py::test_custom_init_subclass_params tests/test_main.py::test_update_forward_refs_does_not_modify_module_dict tests/test_main.py::test_two_defaults tests/test_main.py::test_default_factory tests/test_main.py::test_default_factory_called_once tests/test_main.py::test_default_factory_called_once_2 tests/test_main.py::test_default_factory_validate_children tests/test_main.py::test_default_factory_parse tests/test_main.py::test_none_min_max_items tests/test_main.py::test_reuse_same_field tests/test_main.py::test_base_config_type_hinting tests/test_main.py::test_allow_mutation_field tests/test_main.py::test_repr_field tests/test_main.py::test_inherited_model_field_copy tests/test_main.py::test_inherited_model_field_untouched tests/test_main.py::test_mapping_retains_type_subclass tests/test_main.py::test_mapping_retains_type_defaultdict tests/test_main.py::test_mapping_retains_type_fallback_error tests/test_main.py::test_typing_coercion_dict tests/test_main.py::test_typing_coercion_defaultdict tests/test_main.py::test_typing_coercion_counter tests/test_main.py::test_typing_counter_value_validation tests/test_main.py::test_class_kwargs_config tests/test_main.py::test_class_kwargs_config_json_encoders tests/test_main.py::test_class_kwargs_config_and_attr_conflict tests/test_main.py::test_class_kwargs_custom_config