Merge pull request #13351 from slavapestov/invalid-use-of-polymorphic-init

Diagnose an invalid use of non-polymorphic constructors
diff --git a/docs/DebuggingTheCompiler.rst b/docs/DebuggingTheCompiler.rst
index 9d75f29..d0736e0 100644
--- a/docs/DebuggingTheCompiler.rst
+++ b/docs/DebuggingTheCompiler.rst
@@ -2,6 +2,7 @@
 
 .. highlight:: none
 
+============================
 Debugging the Swift Compiler
 ============================
 
@@ -67,12 +68,85 @@
 The output of all these dump options (except ``-dump-ast``) can be redirected
 with an additional ``-o <file>`` option.
 
+Debugging the Type Checker
+--------------------------
+
+Enabling Logging
+~~~~~~~~~~~~~~~~
+
+To enable logging in the type checker, use the following argument: ``-Xfrontend -debug-constraints``.
+This will cause the typechecker to log its internal state as it solves
+constraints and present the final type checked solution, e.g.::
+
+  ---Constraint solving for the expression at [test.swift:3:10 - line:3:10]---
+  ---Initial constraints for the given expression---
+  (integer_literal_expr type='$T0' location=test.swift:3:10 range=[test.swift:3:10 - line:3:10] value=0)
+  Score: 0 0 0 0 0 0 0 0 0 0 0 0 0
+  Contextual Type: Int
+  Type Variables:
+    #0 = $T0 [inout allowed]
+
+  Active Constraints:
+
+  Inactive Constraints:
+    $T0 literal conforms to ExpressibleByIntegerLiteral [[locator@0x7ffa3a865a00 [IntegerLiteral@test.swift:3:10]]];
+    $T0 conv Int [[locator@0x7ffa3a865a00 [IntegerLiteral@test.swift:3:10]]];
+  ($T0 literal=3 bindings=(subtypes of) (default from ExpressibleByIntegerLiteral) Int)
+  Active bindings: $T0 := Int
+  (trying $T0 := Int
+    (found solution 0 0 0 0 0 0 0 0 0 0 0 0 0)
+  )
+  ---Solution---
+  Fixed score: 0 0 0 0 0 0 0 0 0 0 0 0 0
+  Type variables:
+    $T0 as Int
+
+  Overload choices:
+
+  Constraint restrictions:
+
+  Disjunction choices:
+
+  Conformances:
+    At locator@0x7ffa3a865a00 [IntegerLiteral@test.swift:3:10]
+  (normal_conformance type=Int protocol=ExpressibleByIntegerLiteral lazy
+    (normal_conformance type=Int protocol=_ExpressibleByBuiltinIntegerLiteral lazy))
+  (found solution 0 0 0 0 0 0 0 0 0 0 0 0 0)
+  ---Type-checked expression---
+  (call_expr implicit type='Int' location=test.swift:3:10 range=[test.swift:3:10 - line:3:10] arg_labels=_builtinIntegerLiteral:
+    (constructor_ref_call_expr implicit type='(_MaxBuiltinIntegerType) -> Int' location=test.swift:3:10 range=[test.swift:3:10 - line:3:10]
+      (declref_expr implicit type='(Int.Type) -> (_MaxBuiltinIntegerType) -> Int' location=test.swift:3:10 range=[test.swift:3:10 - line:3:10] decl=Swift.(file).Int.init(_builtinIntegerLiteral:) function_ref=single)
+      (type_expr implicit type='Int.Type' location=test.swift:3:10 range=[test.swift:3:10 - line:3:10] typerepr='Int'))
+    (tuple_expr implicit type='(_builtinIntegerLiteral: Int2048)' location=test.swift:3:10 range=[test.swift:3:10 - line:3:10] names=_builtinIntegerLiteral
+      (integer_literal_expr type='Int2048' location=test.swift:3:10 range=[test.swift:3:10 - line:3:10] value=0)))
+
+When using the integrated swift-repl, one can dump the same output for each
+expression as one evaluates the expression by enabling constraints debugging by
+typing ``:constraints debug on``::
+
+  $ swift -frontend -repl -enable-objc-interop -module-name REPL
+  ***  You are running Swift's integrated REPL,  ***
+  ***  intended for compiler and stdlib          ***
+  ***  development and testing purposes only.    ***
+  ***  The full REPL is built as part of LLDB.   ***
+  ***  Type ':help' for assistance.              ***
+  (swift) :constraints debug on
+
+Asserting on First Error
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+When changing the typechecker, one can cause a series of cascading errors. Since
+Swift doesn't assert on such errors, one has to know more about the typechecker
+to know where to stop in the debugger. Rather than doing that, one can use the
+option ``-Xllvm -swift-diagnostics-assert-on-error=1`` to cause the
+DiagnosticsEngine to assert upon the first error, providing the signal that the
+debugger needs to know that it should attach.
 
 Debugging on SIL Level
-~~~~~~~~~~~~~~~~~~~~~~
+----------------------
 
 Options for Dumping the SIL
-```````````````````````````
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Often it is not sufficient to dump the SIL at the beginning or end of the
 optimization pipeline.
@@ -92,7 +166,7 @@
 For details see ``PassManager.cpp``.
 
 Dumping the SIL and other Data in LLDB
-``````````````````````````````````````
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 When debugging the Swift compiler with LLDB (or Xcode, of course), there is
 even a more powerful way to examine the data in the compiler, e.g. the SIL.
@@ -125,7 +199,7 @@
 environment setting contains the path to the dot tool.
 
 Debugging and Profiling on SIL level
-````````````````````````````````````
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 The compiler provides a way to debug and profile on SIL level. To enable SIL
 debugging add the front-end option -gsil together with -g. Example::
@@ -141,7 +215,7 @@
 the build-script-impl option ``--build-sil-debugging-stdlib``.
 
 ViewCFG: Regex based CFG Printer
-````````````````````````````````
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 ViewCFG (``./utils/viewcfg``) is a script that parses a textual CFG (e.g. a llvm
 or sil function) and displays a .dot file of the CFG. Since the parsing is done
@@ -178,7 +252,7 @@
 **NOTE** Since we use open, .dot files should be associated with the Graphviz app for viewcfg to work.
 
 Using Breakpoints
-`````````````````
+~~~~~~~~~~~~~~~~~
 
 LLDB has very powerful breakpoints, which can be utilized in many ways to debug
 the compiler and Swift executables. The examples in this section show the LLDB
@@ -255,7 +329,7 @@
     (lldb) br set -i 84 -n GlobalARCOpts::run
 
 LLDB Scripts
-````````````
+~~~~~~~~~~~~
 
 LLDB has powerful capabilities of scripting in Python among other languages. An
 often overlooked, but very useful technique is the -s command to lldb. This
@@ -294,7 +368,7 @@
 needing to retype the various commands perfectly every time.
 
 Reducing SIL test cases using bug_reducer
-`````````````````````````````````````````
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 There is functionality provided in ./swift/utils/bug_reducer/bug_reducer.py for
 reducing SIL test cases by:
diff --git a/lib/AST/DiagnosticEngine.cpp b/lib/AST/DiagnosticEngine.cpp
index 11362ef..1aaf6ca 100644
--- a/lib/AST/DiagnosticEngine.cpp
+++ b/lib/AST/DiagnosticEngine.cpp
@@ -24,12 +24,13 @@
 #include "swift/AST/PrintOptions.h"
 #include "swift/AST/TypeRepr.h"
 #include "swift/Basic/SourceManager.h"
-#include "swift/Parse/Lexer.h" // bad dependency
 #include "swift/Config.h"
+#include "swift/Parse/Lexer.h" // bad dependency
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/Twine.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
 
 using namespace swift;
 
@@ -588,6 +589,11 @@
   llvm_unreachable("Unhandled DiagnosticKind in switch.");
 }
 
+/// A special option only for compiler writers that causes Diagnostics to assert
+/// when a failure diagnostic is emitted. Intended for use in the debugger.
+llvm::cl::opt<bool> AssertOnError("swift-diagnostics-assert-on-error",
+                                  llvm::cl::init(false));
+
 DiagnosticState::Behavior DiagnosticState::determineBehavior(DiagID id) {
   auto set = [this](DiagnosticState::Behavior lvl) {
     if (lvl == Behavior::Fatal) {
@@ -597,6 +603,7 @@
       anyErrorOccurred = true;
     }
 
+    assert((!AssertOnError || !anyErrorOccurred) && "We emitted an error?!");
     previousBehavior = lvl;
     return lvl;
   };