diff --git a/mypy/checker.py b/mypy/checker.py
index 870c561852b6..59746059a573 100644
--- a/mypy/checker.py
+++ b/mypy/checker.py
@@ -36,7 +36,7 @@
     true_only, false_only, function_type, is_named_instance, union_items
 )
 from mypy.sametypes import is_same_type, is_same_types
-from mypy.messages import MessageBuilder
+from mypy.messages import MessageBuilder, make_inferred_type_note
 import mypy.checkexpr
 from mypy.checkmember import map_type_from_supertype, bind_self, erase_to_bound
 from mypy import messages
@@ -2313,15 +2313,20 @@ def check_subtype(self, subtype: Type, supertype: Type, context: Context,
             if self.should_suppress_optional_error([subtype]):
                 return False
             extra_info = []  # type: List[str]
+            note_msg = ''
             if subtype_label is not None or supertype_label is not None:
                 subtype_str, supertype_str = self.msg.format_distinctly(subtype, supertype)
                 if subtype_label is not None:
                     extra_info.append(subtype_label + ' ' + subtype_str)
                 if supertype_label is not None:
                     extra_info.append(supertype_label + ' ' + supertype_str)
+                note_msg = make_inferred_type_note(context, subtype,
+                                                   supertype, supertype_str)
             if extra_info:
                 msg += ' (' + ', '.join(extra_info) + ')'
             self.fail(msg, context)
+            if note_msg:
+                self.note(note_msg, context)
             return False
 
     def contains_none(self, t: Type) -> bool:
diff --git a/mypy/messages.py b/mypy/messages.py
index 5c2f5d16fdc7..f4e40b680dfa 100644
--- a/mypy/messages.py
+++ b/mypy/messages.py
@@ -17,7 +17,8 @@
 )
 from mypy.nodes import (
     TypeInfo, Context, MypyFile, op_methods, FuncDef, reverse_type_aliases,
-    ARG_POS, ARG_OPT, ARG_NAMED, ARG_NAMED_OPT, ARG_STAR, ARG_STAR2
+    ARG_POS, ARG_OPT, ARG_NAMED, ARG_NAMED_OPT, ARG_STAR, ARG_STAR2,
+    ReturnStmt, NameExpr, Var
 )
 
 
@@ -977,3 +978,31 @@ def pretty_or(args: List[str]) -> str:
     if len(quoted) == 2:
         return "{} or {}".format(quoted[0], quoted[1])
     return ", ".join(quoted[:-1]) + ", or " + quoted[-1]
+
+
+def make_inferred_type_note(context: Context, subtype: Type,
+                            supertype: Type, supertype_str: str) -> str:
+    """Explain that the user may have forgotten to type a variable.
+
+    The user does not expect an error if the inferred container type is the same as the return
+    type of a function and the argument type(s) are a subtype of the argument type(s) of the
+    return type. This note suggests that they add a type annotation with the return type instead
+    of relying on the inferred type.
+    """
+    from mypy.subtypes import is_subtype
+    if (isinstance(subtype, Instance) and
+            isinstance(supertype, Instance) and
+            subtype.type.fullname() == supertype.type.fullname() and
+            subtype.args and
+            supertype.args and
+            isinstance(context, ReturnStmt) and
+            isinstance(context.expr, NameExpr) and
+            isinstance(context.expr.node, Var) and
+            context.expr.node.is_inferred):
+        for subtype_arg, supertype_arg in zip(subtype.args, supertype.args):
+            if not is_subtype(subtype_arg, supertype_arg):
+                return ''
+        var_name = context.expr.name
+        return 'Perhaps you need a type annotation for "{}"? Suggestion: {}'.format(
+            var_name, supertype_str)
+    return ''
diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test
index 030fe788c5e2..6c93a47bf676 100644
--- a/test-data/unit/check-functions.test
+++ b/test-data/unit/check-functions.test
@@ -2067,3 +2067,59 @@ def some_method(self: badtype): pass # E: Name 'badtype' is not defined
 def fn(
         a: badtype) -> None: # E: Name 'badtype' is not defined
     pass
+
+[case testInferredTypeSubTypeOfReturnType]
+from typing import Union, Dict, List
+def f() -> List[Union[str, int]]:
+    x = ['a']
+    return x # E: Incompatible return value type (got List[str], expected List[Union[str, int]]) \
+# N: Perhaps you need a type annotation for "x"? Suggestion: List[Union[str, int]]
+
+def g() -> Dict[str, Union[str, int]]:
+    x = {'a': 'a'}
+    return x # E: Incompatible return value type (got Dict[str, str], expected Dict[str, Union[str, int]]) \
+# N: Perhaps you need a type annotation for "x"? Suggestion: Dict[str, Union[str, int]]
+
+def h() -> Dict[Union[str, int], str]:
+    x = {'a': 'a'}
+    return x # E: Incompatible return value type (got Dict[str, str], expected Dict[Union[str, int], str]) \
+# N: Perhaps you need a type annotation for "x"? Suggestion: Dict[Union[str, int], str]
+
+def i() -> List[Union[int, float]]:
+    x: List[int] = [1]
+    return x # E: Incompatible return value type (got List[int], expected List[Union[int, float]]) \
+# N: Perhaps you need a type annotation for "x"? Suggestion: List[Union[int, float]]
+
+[builtins fixtures/dict.pyi]
+
+[case testInferredTypeNotSubTypeOfReturnType]
+from typing import Union, List
+def f() -> List[Union[int, float]]:
+    x = ['a']
+    return x # E: Incompatible return value type (got List[str], expected List[Union[int, float]])
+
+def g() -> List[Union[str, int]]:
+    x = ('a', 2)
+    return x # E: Incompatible return value type (got "Tuple[str, int]", expected List[Union[str, int]])
+
+[builtins fixtures/list.pyi]
+
+[case testInferredTypeIsObjectMismatch]
+from typing import Union, Dict, List
+def f() -> Dict[str, Union[str, int]]:
+    x = {'a': 'a', 'b': 2}
+    return x # E: Incompatible return value type (got Dict[str, object], expected Dict[str, Union[str, int]])
+
+def g() -> Dict[str, Union[str, int]]:
+    x: Dict[str, Union[str, int]] = {'a': 'a', 'b': 2}
+    return x
+
+def h() -> List[Union[str, int]]:
+    x = ['a', 2]
+    return x # E: Incompatible return value type (got List[object], expected List[Union[str, int]])
+
+def i() -> List[Union[str, int]]:
+    x: List[Union[str, int]] = ['a', 2]
+    return x
+
+[builtins fixtures/dict.pyi]