Skip to content

Commit bc15dd6

Browse files
committed
Wrap recursion in ensure_sufficient_stack.
1 parent 1321a2d commit bc15dd6

File tree

1 file changed

+91
-88
lines changed

1 file changed

+91
-88
lines changed

src/librustc_lint/builtin.rs

+91-88
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree};
2929
use rustc_ast::visit::{FnCtxt, FnKind};
3030
use rustc_ast_pretty::pprust::{self, expr_to_string};
3131
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
32+
use rustc_data_structures::stack::ensure_sufficient_stack;
3233
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
3334
use rustc_feature::{deprecated_attributes, AttributeGate, AttributeTemplate, AttributeType};
3435
use rustc_feature::{GateIssue, Stability};
@@ -2188,16 +2189,17 @@ impl ClashingExternDeclarations {
21882189
kind.is_primitive() || matches!(kind, RawPtr(..) | Ref(..))
21892190
};
21902191

2191-
match (a_kind, b_kind) {
2192-
(Adt(a_def, a_substs), Adt(b_def, b_substs)) => {
2193-
let a = a.subst(cx.tcx, a_substs);
2194-
let b = b.subst(cx.tcx, b_substs);
2195-
debug!("Comparing {:?} and {:?}", a, b);
2192+
ensure_sufficient_stack(|| {
2193+
match (a_kind, b_kind) {
2194+
(Adt(a_def, a_substs), Adt(b_def, b_substs)) => {
2195+
let a = a.subst(cx.tcx, a_substs);
2196+
let b = b.subst(cx.tcx, b_substs);
2197+
debug!("Comparing {:?} and {:?}", a, b);
21962198

2197-
// Grab a flattened representation of all fields.
2198-
let a_fields = a_def.variants.iter().flat_map(|v| v.fields.iter());
2199-
let b_fields = b_def.variants.iter().flat_map(|v| v.fields.iter());
2200-
compare_layouts(a, b)
2199+
// Grab a flattened representation of all fields.
2200+
let a_fields = a_def.variants.iter().flat_map(|v| v.fields.iter());
2201+
let b_fields = b_def.variants.iter().flat_map(|v| v.fields.iter());
2202+
compare_layouts(a, b)
22012203
&& a_fields.eq_by(
22022204
b_fields,
22032205
|&ty::FieldDef { did: a_did, .. },
@@ -2211,88 +2213,89 @@ impl ClashingExternDeclarations {
22112213
)
22122214
},
22132215
)
2214-
}
2215-
(Array(a_ty, a_const), Array(b_ty, b_const)) => {
2216-
// For arrays, we also check the constness of the type.
2217-
a_const.val == b_const.val
2218-
&& structurally_same_type_impl(seen_types, cx, a_ty, b_ty, ckind)
2219-
}
2220-
(Slice(a_ty), Slice(b_ty)) => {
2221-
structurally_same_type_impl(seen_types, cx, a_ty, b_ty, ckind)
2222-
}
2223-
(RawPtr(a_tymut), RawPtr(b_tymut)) => {
2224-
a_tymut.mutbl == b_tymut.mutbl
2225-
&& structurally_same_type_impl(
2226-
seen_types,
2227-
cx,
2228-
&a_tymut.ty,
2229-
&b_tymut.ty,
2230-
ckind,
2231-
)
2232-
}
2233-
(Ref(_a_region, a_ty, a_mut), Ref(_b_region, b_ty, b_mut)) => {
2234-
// For structural sameness, we don't need the region to be same.
2235-
a_mut == b_mut
2236-
&& structurally_same_type_impl(seen_types, cx, a_ty, b_ty, ckind)
2237-
}
2238-
(FnDef(..), FnDef(..)) => {
2239-
let a_poly_sig = a.fn_sig(tcx);
2240-
let b_poly_sig = b.fn_sig(tcx);
2241-
2242-
// As we don't compare regions, skip_binder is fine.
2243-
let a_sig = a_poly_sig.skip_binder();
2244-
let b_sig = b_poly_sig.skip_binder();
2245-
2246-
(a_sig.abi, a_sig.unsafety, a_sig.c_variadic)
2247-
== (b_sig.abi, b_sig.unsafety, b_sig.c_variadic)
2248-
&& a_sig.inputs().iter().eq_by(b_sig.inputs().iter(), |a, b| {
2249-
structurally_same_type_impl(seen_types, cx, a, b, ckind)
2250-
})
2251-
&& structurally_same_type_impl(
2252-
seen_types,
2253-
cx,
2254-
a_sig.output(),
2255-
b_sig.output(),
2256-
ckind,
2257-
)
2258-
}
2259-
(Tuple(a_substs), Tuple(b_substs)) => {
2260-
a_substs.types().eq_by(b_substs.types(), |a_ty, b_ty| {
2216+
}
2217+
(Array(a_ty, a_const), Array(b_ty, b_const)) => {
2218+
// For arrays, we also check the constness of the type.
2219+
a_const.val == b_const.val
2220+
&& structurally_same_type_impl(seen_types, cx, a_ty, b_ty, ckind)
2221+
}
2222+
(Slice(a_ty), Slice(b_ty)) => {
22612223
structurally_same_type_impl(seen_types, cx, a_ty, b_ty, ckind)
2262-
})
2263-
}
2264-
// For these, it's not quite as easy to define structural-sameness quite so easily.
2265-
// For the purposes of this lint, take the conservative approach and mark them as
2266-
// not structurally same.
2267-
(Dynamic(..), Dynamic(..))
2268-
| (Error(..), Error(..))
2269-
| (Closure(..), Closure(..))
2270-
| (Generator(..), Generator(..))
2271-
| (GeneratorWitness(..), GeneratorWitness(..))
2272-
| (Projection(..), Projection(..))
2273-
| (Opaque(..), Opaque(..)) => false,
2274-
2275-
// These definitely should have been caught above.
2276-
(Bool, Bool) | (Char, Char) | (Never, Never) | (Str, Str) => unreachable!(),
2277-
2278-
// An Adt and a primitive or pointer type. This can be FFI-safe if non-null
2279-
// enum layout optimisation is being applied.
2280-
(Adt(..), other_kind) | (other_kind, Adt(..))
2281-
if is_primitive_or_pointer(other_kind) =>
2282-
{
2283-
let (primitive, adt) =
2284-
if is_primitive_or_pointer(&a.kind) { (a, b) } else { (b, a) };
2285-
if let Some(ty) = crate::types::repr_nullable_ptr(cx, adt, ckind) {
2286-
ty == primitive
2287-
} else {
2288-
compare_layouts(a, b)
22892224
}
2225+
(RawPtr(a_tymut), RawPtr(b_tymut)) => {
2226+
a_tymut.mutbl == b_tymut.mutbl
2227+
&& structurally_same_type_impl(
2228+
seen_types,
2229+
cx,
2230+
&a_tymut.ty,
2231+
&b_tymut.ty,
2232+
ckind,
2233+
)
2234+
}
2235+
(Ref(_a_region, a_ty, a_mut), Ref(_b_region, b_ty, b_mut)) => {
2236+
// For structural sameness, we don't need the region to be same.
2237+
a_mut == b_mut
2238+
&& structurally_same_type_impl(seen_types, cx, a_ty, b_ty, ckind)
2239+
}
2240+
(FnDef(..), FnDef(..)) => {
2241+
let a_poly_sig = a.fn_sig(tcx);
2242+
let b_poly_sig = b.fn_sig(tcx);
2243+
2244+
// As we don't compare regions, skip_binder is fine.
2245+
let a_sig = a_poly_sig.skip_binder();
2246+
let b_sig = b_poly_sig.skip_binder();
2247+
2248+
(a_sig.abi, a_sig.unsafety, a_sig.c_variadic)
2249+
== (b_sig.abi, b_sig.unsafety, b_sig.c_variadic)
2250+
&& a_sig.inputs().iter().eq_by(b_sig.inputs().iter(), |a, b| {
2251+
structurally_same_type_impl(seen_types, cx, a, b, ckind)
2252+
})
2253+
&& structurally_same_type_impl(
2254+
seen_types,
2255+
cx,
2256+
a_sig.output(),
2257+
b_sig.output(),
2258+
ckind,
2259+
)
2260+
}
2261+
(Tuple(a_substs), Tuple(b_substs)) => {
2262+
a_substs.types().eq_by(b_substs.types(), |a_ty, b_ty| {
2263+
structurally_same_type_impl(seen_types, cx, a_ty, b_ty, ckind)
2264+
})
2265+
}
2266+
// For these, it's not quite as easy to define structural-sameness quite so easily.
2267+
// For the purposes of this lint, take the conservative approach and mark them as
2268+
// not structurally same.
2269+
(Dynamic(..), Dynamic(..))
2270+
| (Error(..), Error(..))
2271+
| (Closure(..), Closure(..))
2272+
| (Generator(..), Generator(..))
2273+
| (GeneratorWitness(..), GeneratorWitness(..))
2274+
| (Projection(..), Projection(..))
2275+
| (Opaque(..), Opaque(..)) => false,
2276+
2277+
// These definitely should have been caught above.
2278+
(Bool, Bool) | (Char, Char) | (Never, Never) | (Str, Str) => unreachable!(),
2279+
2280+
// An Adt and a primitive or pointer type. This can be FFI-safe if non-null
2281+
// enum layout optimisation is being applied.
2282+
(Adt(..), other_kind) | (other_kind, Adt(..))
2283+
if is_primitive_or_pointer(other_kind) =>
2284+
{
2285+
let (primitive, adt) =
2286+
if is_primitive_or_pointer(&a.kind) { (a, b) } else { (b, a) };
2287+
if let Some(ty) = crate::types::repr_nullable_ptr(cx, adt, ckind) {
2288+
ty == primitive
2289+
} else {
2290+
compare_layouts(a, b)
2291+
}
2292+
}
2293+
// Otherwise, just compare the layouts. This may fail to lint for some
2294+
// incompatible types, but at the very least, will stop reads into
2295+
// uninitialised memory.
2296+
_ => compare_layouts(a, b),
22902297
}
2291-
// Otherwise, just compare the layouts. This may fail to lint for some
2292-
// incompatible types, but at the very least, will stop reads into
2293-
// uninitialised memory.
2294-
_ => compare_layouts(a, b),
2295-
}
2298+
})
22962299
}
22972300
}
22982301
let mut seen_types = FxHashSet::default();

0 commit comments

Comments
 (0)