diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php
index 4b995c1..068f719 100644
--- a/core/lib/Drupal/Core/Form/FormBuilder.php
+++ b/core/lib/Drupal/Core/Form/FormBuilder.php
@@ -12,6 +12,7 @@
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Component\Utility\UrlHelper;
+use Drupal\Core\Access\AccessResultInterface;
 use Drupal\Core\Access\CsrfTokenGenerator;
 use Drupal\Core\DependencyInjection\ClassResolverInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
@@ -773,6 +774,15 @@ public function doBuildForm($form_id, &$element, FormStateInterface &$form_state
 
     // Recurse through all child elements.
     $count = 0;
+    if (isset($element['#access'])) {
+      $access = $element['#access'];
+      if ($access instanceof AccessResultInterface || $access === FALSE) {
+        $child_denied = $access;
+      }
+      else {
+        $child_access = NULL;
+      }
+    }
     foreach (Element::children($element) as $key) {
       // Prior to checking properties of child elements, their default
       // properties need to be loaded.
@@ -787,8 +797,8 @@ public function doBuildForm($form_id, &$element, FormStateInterface &$form_state
       }
 
       // Deny access to child elements if parent is denied.
-      if (isset($element['#access']) && !$element['#access']) {
-        $element[$key]['#access'] = FALSE;
+      if (isset($child_access)) {
+        $element[$key]['#access'] = $child_access;
       }
 
       // Make child elements inherit their parent's #disabled and #allow_focus
diff --git a/core/lib/Drupal/Core/Render/Element.php b/core/lib/Drupal/Core/Render/Element.php
index c0d3a4a..6a05224 100644
--- a/core/lib/Drupal/Core/Render/Element.php
+++ b/core/lib/Drupal/Core/Render/Element.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core\Render;
 
 use Drupal\Component\Utility\SafeMarkup;
+use Drupal\Core\Access\AccessResultInterface;
 
 /**
  * Provides helper methods for Drupal render elements.
@@ -137,7 +138,7 @@ public static function getVisibleChildren(array $elements) {
       $child = $elements[$key];
 
       // Skip un-accessible children.
-      if (isset($child['#access']) && !$child['#access']) {
+      if (isset($child['#access']) && (($child['#access'] instanceof AccessResultInterface && !$child['#access']->isAllowed()) || !$child['#access'])) {
         continue;
       }
 
diff --git a/core/lib/Drupal/Core/Render/Renderer.php b/core/lib/Drupal/Core/Render/Renderer.php
index 9ba7613..2d6d5bb 100644
--- a/core/lib/Drupal/Core/Render/Renderer.php
+++ b/core/lib/Drupal/Core/Render/Renderer.php
@@ -10,6 +10,7 @@
 use Drupal\Component\Utility\Crypt;
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Component\Utility\SafeMarkup;
+use Drupal\Core\Access\AccessResultInterface;
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Cache\CacheableMetadata;
 use Drupal\Core\Controller\ControllerResolverInterface;
@@ -138,7 +139,10 @@ protected function doRender(&$elements, $is_root_call = FALSE) {
     }
 
     // Early-return nothing if user does not have access.
-    if (empty($elements) || (isset($elements['#access']) && !$elements['#access'])) {
+    if (empty($elements)) {
+      return '';
+    }
+    if (isset($elements['#access']) && (($elements['#access'] instanceof AccessResultInterface && !$elements['#access']->isAllowed()) || !$elements['#access'])) {
       return '';
     }
 
