diff --git a/doc/manual.html b/doc/manual.html
index 5295ec79ea3b53c997cd11a62948501efeaf7b32..d20d07424efae1b77963d4c6c045d490d8eeeb0c 100644
--- a/doc/manual.html
+++ b/doc/manual.html
@@ -1644,9 +1644,6 @@
           <dt><code><strong>above</strong>: boolean</code></dt>
           <dd>Causes the widget to be placed above instead of below
           the text of the line.</dd>
-          <dt><code><strong>showIfHidden</strong>: boolean</code></dt>
-          <dd>When true, will cause the widget to be rendered even if
-          the line it is associated with is hidden.</dd>
           <dt><code><strong>handleMouseEvents</strong>: boolean</code></dt>
           <dd>Determines whether the editor will capture mouse and
           drag events occurring in this widget. Default is false—the
diff --git a/doc/upgrade_v4.html b/doc/upgrade_v4.html
index 88a02066d18e389ea2fcc119003f823b3cc450cd..9680151a0b68061e9383a14b23d7b9d8a69cf5f7 100644
--- a/doc/upgrade_v4.html
+++ b/doc/upgrade_v4.html
@@ -19,6 +19,7 @@
     <li><a href="#beforeSelectionChange">The beforeSelectionChange event</a>
     <li><a href="#replaceSelection">replaceSelection and collapsing</a>
     <li><a href="#changeEvent">change event data</a>
+    <li><a href="#showIfHidden">showIfHidden option to line widgets</a>
     <li><a href="#module">Module loaders</a>
     <li><a href="#shareddata">Mutating shared data structures</a></li>
     <li><a href="#deprecated">Deprecated interfaces dropped</a>
@@ -82,6 +83,16 @@ events. Existing code will probably continue to work unmodified.</p>
 
 </section>
 
+<section id=showIfHidden><h2>showIfHidden option to line widgets</h2>
+
+<p>This option, which conceptually caused line widgets to be visible
+even if their line was hidden, was never really well-defined, and was
+buggy from the start. It would be a rather expensive feature, both in
+code complexity and run-time performance, to implement properly. It
+has been dropped entirely in 4.0.</p>
+
+</section>
+
 <section id=module><h2>Module loaders</h2>
 
 <p>All modules in the CodeMirror distribution are now wrapped in a
diff --git a/lib/codemirror.js b/lib/codemirror.js
index ae4de0b71806e3512b154a583466378ff045fd12..e9896eea50ca1be3a1b9824cde193b6d3d36e048 100644
--- a/lib/codemirror.js
+++ b/lib/codemirror.js
@@ -5371,7 +5371,7 @@
       if (widget.insertAt == null) widgets.push(widget);
       else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget);
       widget.line = line;
-      if (!lineIsHidden(cm.doc, line) || widget.showIfHidden) {
+      if (!lineIsHidden(cm.doc, line)) {
         var aboveVisible = heightAtLine(line) < cm.doc.scrollTop;
         updateLineHeight(line, line.height + widgetHeight(widget));
         if (aboveVisible) addToScrollPos(cm, null, widget.height);