diff options
| author | bors <bors@rust-lang.org> | 2022-08-25 21:27:38 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-08-25 21:27:38 +0000 |
| commit | cfb5ae26a4496b7d35180f15e47ada0f3897c7e8 (patch) | |
| tree | 3cc1936bac16b1090e75c50417549e2e459031e3 /compiler/rustc_middle/src | |
| parent | 7480389611f9d04bd34adf41a2b3029be4eb815e (diff) | |
| parent | cbc6bd20191554421b3d4a377cd01169212da23b (diff) | |
| download | rust-cfb5ae26a4496b7d35180f15e47ada0f3897c7e8.tar.gz rust-cfb5ae26a4496b7d35180f15e47ada0f3897c7e8.zip | |
Auto merge of #100748 - SparrowLii:query_depth, r=cjgillot
add `depth_limit` in `QueryVTable` to avoid entering a new tcx in `layout_of` Fixes #49735 Updates #48685 The `layout_of` query needs to check whether it overflows the depth limit, and the current implementation needs to create a new `ImplicitCtxt` inside `layout_of`. However, `start_query` will already create a new `ImplicitCtxt`, so we can check the depth limit in `start_query`. We can tell whether we need to check the depth limit simply by whether the return value of `to_debug_str` of the query is `layout_of`. But I think adding the `depth_limit` field in `QueryVTable` may be more elegant and more scalable.
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/query/mod.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/layout.rs | 61 |
3 files changed, 29 insertions, 39 deletions
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 16de6ebfe58..9bb9d50d1e8 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1309,6 +1309,7 @@ rustc_queries! { query layout_of( key: ty::ParamEnvAnd<'tcx, Ty<'tcx>> ) -> Result<ty::layout::TyAndLayout<'tcx>, ty::layout::LayoutError<'tcx>> { + depth_limit desc { "computing layout of `{}`", key.value } remap_env_constness } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 0a0f45ce1a0..0f34aa10a12 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1857,8 +1857,8 @@ pub mod tls { /// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query. pub diagnostics: Option<&'a Lock<ThinVec<Diagnostic>>>, - /// Used to prevent layout from recursing too deeply. - pub layout_depth: usize, + /// Used to prevent queries from calling too deeply. + pub query_depth: usize, /// The current dep graph task. This is used to add dependencies to queries /// when executing them. @@ -1872,7 +1872,7 @@ pub mod tls { tcx, query: None, diagnostics: None, - layout_depth: 0, + query_depth: 0, task_deps: TaskDepsRef::Ignore, } } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index f5505590168..384f17b3cdf 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -229,49 +229,38 @@ fn layout_of<'tcx>( tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, ) -> Result<TyAndLayout<'tcx>, LayoutError<'tcx>> { - ty::tls::with_related_context(tcx, move |icx| { - let (param_env, ty) = query.into_parts(); - debug!(?ty); - - if !tcx.recursion_limit().value_within_limit(icx.layout_depth) { - tcx.sess.fatal(&format!("overflow representing the type `{}`", ty)); + let (param_env, ty) = query.into_parts(); + debug!(?ty); + + let param_env = param_env.with_reveal_all_normalized(tcx); + let unnormalized_ty = ty; + + // FIXME: We might want to have two different versions of `layout_of`: + // One that can be called after typecheck has completed and can use + // `normalize_erasing_regions` here and another one that can be called + // before typecheck has completed and uses `try_normalize_erasing_regions`. + let ty = match tcx.try_normalize_erasing_regions(param_env, ty) { + Ok(t) => t, + Err(normalization_error) => { + return Err(LayoutError::NormalizationFailure(ty, normalization_error)); } + }; - // Update the ImplicitCtxt to increase the layout_depth - let icx = ty::tls::ImplicitCtxt { layout_depth: icx.layout_depth + 1, ..icx.clone() }; - - ty::tls::enter_context(&icx, |_| { - let param_env = param_env.with_reveal_all_normalized(tcx); - let unnormalized_ty = ty; - - // FIXME: We might want to have two different versions of `layout_of`: - // One that can be called after typecheck has completed and can use - // `normalize_erasing_regions` here and another one that can be called - // before typecheck has completed and uses `try_normalize_erasing_regions`. - let ty = match tcx.try_normalize_erasing_regions(param_env, ty) { - Ok(t) => t, - Err(normalization_error) => { - return Err(LayoutError::NormalizationFailure(ty, normalization_error)); - } - }; - - if ty != unnormalized_ty { - // Ensure this layout is also cached for the normalized type. - return tcx.layout_of(param_env.and(ty)); - } + if ty != unnormalized_ty { + // Ensure this layout is also cached for the normalized type. + return tcx.layout_of(param_env.and(ty)); + } - let cx = LayoutCx { tcx, param_env }; + let cx = LayoutCx { tcx, param_env }; - let layout = cx.layout_of_uncached(ty)?; - let layout = TyAndLayout { ty, layout }; + let layout = cx.layout_of_uncached(ty)?; + let layout = TyAndLayout { ty, layout }; - cx.record_layout_for_printing(layout); + cx.record_layout_for_printing(layout); - sanity_check_layout(&cx, &layout); + sanity_check_layout(&cx, &layout); - Ok(layout) - }) - }) + Ok(layout) } pub struct LayoutCx<'tcx, C> { |
