Skip to content

Commit 0b3d0cd

Browse files
committed
Add Limit struct.
Fixes #9286.
1 parent fe00358 commit 0b3d0cd

File tree

16 files changed

+84
-24
lines changed

16 files changed

+84
-24
lines changed

Cargo.lock

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/hir_def/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ hir_expand = { path = "../hir_expand", version = "0.0.0" }
3131
mbe = { path = "../mbe", version = "0.0.0" }
3232
cfg = { path = "../cfg", version = "0.0.0" }
3333
tt = { path = "../tt", version = "0.0.0" }
34+
limit = { path = "../limit", version = "0.0.0" }
3435

3536
[dev-dependencies]
3637
test_utils = { path = "../test_utils" }

crates/hir_def/src/body.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use hir_expand::{
1515
ast_id_map::AstIdMap, hygiene::Hygiene, AstId, ExpandResult, HirFileId, InFile, MacroDefId,
1616
};
1717
use la_arena::{Arena, ArenaMap};
18+
use limit::Limit;
1819
use profile::Count;
1920
use rustc_hash::FxHashMap;
2021
use syntax::{ast, AstNode, AstPtr, SyntaxNodePtr};
@@ -53,10 +54,10 @@ pub struct Expander {
5354
}
5455

5556
#[cfg(test)]
56-
const EXPANSION_RECURSION_LIMIT: usize = 32;
57+
const EXPANSION_RECURSION_LIMIT: Limit = Limit::new(32);
5758

5859
#[cfg(not(test))]
59-
const EXPANSION_RECURSION_LIMIT: usize = 128;
60+
const EXPANSION_RECURSION_LIMIT: Limit = Limit::new(128);
6061

6162
impl CfgExpander {
6263
pub(crate) fn new(
@@ -99,7 +100,7 @@ impl Expander {
99100
db: &dyn DefDatabase,
100101
macro_call: ast::MacroCall,
101102
) -> Result<ExpandResult<Option<(Mark, T)>>, UnresolvedMacro> {
102-
if self.recursion_limit + 1 > EXPANSION_RECURSION_LIMIT {
103+
if EXPANSION_RECURSION_LIMIT.check(self.recursion_limit + 1).is_err() {
103104
cov_mark::hit!(your_stack_belongs_to_me);
104105
return Ok(ExpandResult::str_err(
105106
"reached recursion limit during macro expansion".into(),

crates/hir_def/src/nameres/collector.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use hir_expand::{
1919
use hir_expand::{InFile, MacroCallLoc};
2020
use itertools::Itertools;
2121
use la_arena::Idx;
22+
use limit::Limit;
2223
use rustc_hash::{FxHashMap, FxHashSet};
2324
use syntax::ast;
2425

@@ -49,9 +50,9 @@ use crate::{
4950
UnresolvedMacro,
5051
};
5152

52-
const GLOB_RECURSION_LIMIT: usize = 100;
53-
const EXPANSION_DEPTH_LIMIT: usize = 128;
54-
const FIXED_POINT_LIMIT: usize = 8192;
53+
const GLOB_RECURSION_LIMIT: Limit = Limit::new(100);
54+
const EXPANSION_DEPTH_LIMIT: Limit = Limit::new(128);
55+
const FIXED_POINT_LIMIT: Limit = Limit::new(8192);
5556

5657
pub(super) fn collect_defs(
5758
db: &dyn DefDatabase,
@@ -357,7 +358,7 @@ impl DefCollector<'_> {
357358
}
358359

359360
i += 1;
360-
if i == FIXED_POINT_LIMIT {
361+
if FIXED_POINT_LIMIT.check(i).is_err() {
361362
log::error!("name resolution is stuck");
362363
break 'outer;
363364
}
@@ -924,7 +925,7 @@ impl DefCollector<'_> {
924925
import_type: ImportType,
925926
depth: usize,
926927
) {
927-
if depth > GLOB_RECURSION_LIMIT {
928+
if GLOB_RECURSION_LIMIT.check(depth).is_err() {
928929
// prevent stack overflows (but this shouldn't be possible)
929930
panic!("infinite recursion in glob imports!");
930931
}
@@ -1157,7 +1158,7 @@ impl DefCollector<'_> {
11571158
macro_call_id: MacroCallId,
11581159
depth: usize,
11591160
) {
1160-
if depth > EXPANSION_DEPTH_LIMIT {
1161+
if EXPANSION_DEPTH_LIMIT.check(depth).is_err() {
11611162
cov_mark::hit!(macro_expansion_overflow);
11621163
log::warn!("macro expansion is too deep");
11631164
return;

crates/hir_def/src/nameres/mod_resolution.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
//! This module resolves `mod foo;` declaration to file.
22
use base_db::{AnchoredPath, FileId};
33
use hir_expand::name::Name;
4+
use limit::Limit;
45
use syntax::SmolStr;
56

67
use crate::{db::DefDatabase, HirFileId};
78

8-
const MOD_DEPTH_LIMIT: u32 = 32;
9+
const MOD_DEPTH_LIMIT: Limit = Limit::new(32);
910

1011
#[derive(Clone, Debug)]
1112
pub(super) struct ModDir {
@@ -25,7 +26,7 @@ impl ModDir {
2526
}
2627
fn child(&self, dir_path: DirPath, root_non_dir_owner: bool) -> Option<ModDir> {
2728
let depth = self.depth + 1;
28-
if depth > MOD_DEPTH_LIMIT {
29+
if MOD_DEPTH_LIMIT.check(depth as usize).is_err() {
2930
log::error!("MOD_DEPTH_LIMIT exceeded");
3031
cov_mark::hit!(circular_mods);
3132
return None;

crates/hir_expand/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ parser = { path = "../parser", version = "0.0.0" }
2121
profile = { path = "../profile", version = "0.0.0" }
2222
tt = { path = "../tt", version = "0.0.0" }
2323
mbe = { path = "../mbe", version = "0.0.0" }
24+
limit = { path = "../limit", version = "0.0.0" }
2425

2526
[dev-dependencies]
2627
test_utils = { path = "../test_utils" }

crates/hir_expand/src/db.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use std::sync::Arc;
44

55
use base_db::{salsa, SourceDatabase};
6+
use limit::Limit;
67
use mbe::{ExpandError, ExpandResult};
78
use parser::FragmentKind;
89
use syntax::{
@@ -21,7 +22,7 @@ use crate::{
2122
///
2223
/// If an invocation produces more tokens than this limit, it will not be stored in the database and
2324
/// an error will be emitted.
24-
const TOKEN_LIMIT: usize = 524288;
25+
const TOKEN_LIMIT: Limit = Limit::new(524288);
2526

2627
#[derive(Debug, Clone, Eq, PartialEq)]
2728
pub enum TokenExpander {
@@ -356,10 +357,12 @@ fn macro_expand_with_arg(
356357
let ExpandResult { value: tt, err } = macro_rules.expand(db, id, &macro_arg.0);
357358
// Set a hard limit for the expanded tt
358359
let count = tt.count();
359-
if count > TOKEN_LIMIT {
360+
// XXX: Make ExpandResult a real error and use .map_err instead?
361+
if TOKEN_LIMIT.check(count).is_err() {
360362
return ExpandResult::str_err(format!(
361363
"macro invocation exceeds token limit: produced {} tokens, limit is {}",
362-
count, TOKEN_LIMIT,
364+
count,
365+
TOKEN_LIMIT.inner(),
363366
));
364367
}
365368

crates/hir_ty/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ hir_expand = { path = "../hir_expand", version = "0.0.0" }
2929
base_db = { path = "../base_db", version = "0.0.0" }
3030
profile = { path = "../profile", version = "0.0.0" }
3131
syntax = { path = "../syntax", version = "0.0.0" }
32+
limit = { path = "../limit", version = "0.0.0" }
3233

3334
[dev-dependencies]
3435
test_utils = { path = "../test_utils" }

crates/hir_ty/src/autoderef.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use base_db::CrateId;
99
use chalk_ir::{cast::Cast, fold::Fold, interner::HasInterner, VariableKind};
1010
use hir_def::lang_item::LangItemTarget;
1111
use hir_expand::name::name;
12+
use limit::Limit;
1213
use log::{info, warn};
1314

1415
use crate::{
@@ -17,6 +18,8 @@ use crate::{
1718
Ty, TyBuilder, TyKind,
1819
};
1920

21+
const AUTODEREF_RECURSION_LIMIT: Limit = Limit::new(10);
22+
2023
pub(crate) enum AutoderefKind {
2124
Builtin,
2225
Overloaded,
@@ -63,7 +66,7 @@ impl Iterator for Autoderef<'_> {
6366
return Some((self.ty.clone(), 0));
6467
}
6568

66-
if self.steps.len() >= AUTODEREF_RECURSION_LIMIT {
69+
if AUTODEREF_RECURSION_LIMIT.check(self.steps.len() + 1).is_err() {
6770
return None;
6871
}
6972

@@ -87,8 +90,6 @@ impl Iterator for Autoderef<'_> {
8790
}
8891
}
8992

90-
const AUTODEREF_RECURSION_LIMIT: usize = 10;
91-
9293
// FIXME: replace uses of this with Autoderef above
9394
pub fn autoderef<'a>(
9495
db: &'a dyn HirDatabase,
@@ -99,7 +100,7 @@ pub fn autoderef<'a>(
99100
successors(Some(ty), move |ty| {
100101
deref(db, krate?, InEnvironment { goal: ty, environment: environment.clone() })
101102
})
102-
.take(AUTODEREF_RECURSION_LIMIT)
103+
.take(AUTODEREF_RECURSION_LIMIT.inner())
103104
}
104105

105106
pub(crate) fn deref(

crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ pub(crate) fn replace_derive_with_manual_impl(
6565
current_crate,
6666
NameToImport::Exact(trait_name.to_string()),
6767
items_locator::AssocItemSearch::Exclude,
68-
Some(items_locator::DEFAULT_QUERY_SEARCH_LIMIT),
68+
Some(items_locator::DEFAULT_QUERY_SEARCH_LIMIT.inner()),
6969
)
7070
.filter_map(|item| match ModuleDef::from(item.as_module_def_id()?) {
7171
ModuleDef::Trait(trait_) => Some(trait_),

0 commit comments

Comments
 (0)