Skip to content

Commit 974109a

Browse files
authored
Merge pull request #62 from coord-e/coord-e/ty-param-always-defer
Always defer local def analysis if it contains type params
2 parents 8466706 + 7dc0ab6 commit 974109a

2 files changed

Lines changed: 77 additions & 15 deletions

File tree

src/analyze.rs

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,24 @@ impl<'tcx> ReplacePlacesVisitor<'tcx> {
106106
}
107107
}
108108

109+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
110+
enum DeferredDefMode {
111+
Analyze,
112+
NoAnalyze,
113+
}
114+
115+
impl DeferredDefMode {
116+
fn should_analyze(&self) -> bool {
117+
matches!(self, DeferredDefMode::Analyze)
118+
}
119+
}
120+
109121
#[derive(Debug, Clone)]
110122
struct DeferredDefTy<'tcx> {
123+
// this is different from a key in defs when the def is extern_spec_fn
124+
local_def_id: LocalDefId,
111125
cache: Rc<RefCell<HashMap<mir_ty::GenericArgsRef<'tcx>, rty::RefinedType>>>,
126+
mode: DeferredDefMode,
112127
}
113128

114129
#[derive(Debug, Clone)]
@@ -290,12 +305,40 @@ impl<'tcx> Analyzer<'tcx> {
290305
self.defs.insert(def_id, DefTy::Concrete(rty));
291306
}
292307

293-
pub fn register_deferred_def(&mut self, def_id: DefId) {
294-
tracing::info!(def_id = ?def_id, "register_deferred_def");
308+
pub fn register_deferred_def(&mut self, local_def_id: LocalDefId) {
309+
self.register_deferred_def_impl(
310+
local_def_id.to_def_id(),
311+
local_def_id,
312+
DeferredDefMode::Analyze,
313+
);
314+
}
315+
316+
pub fn register_deferred_def_without_analysis(
317+
&mut self,
318+
target_def_id: DefId,
319+
local_def_id: LocalDefId,
320+
) {
321+
self.register_deferred_def_impl(target_def_id, local_def_id, DeferredDefMode::NoAnalyze);
322+
}
323+
324+
fn register_deferred_def_impl(
325+
&mut self,
326+
target_def_id: DefId,
327+
local_def_id: LocalDefId,
328+
mode: DeferredDefMode,
329+
) {
330+
tracing::info!(
331+
?target_def_id,
332+
?local_def_id,
333+
?mode,
334+
"register_deferred_def"
335+
);
295336
self.defs.insert(
296-
def_id,
337+
target_def_id,
297338
DefTy::Deferred(DeferredDefTy {
339+
local_def_id,
298340
cache: Rc::new(RefCell::new(HashMap::new())),
341+
mode,
299342
}),
300343
);
301344
}
@@ -312,10 +355,10 @@ impl<'tcx> Analyzer<'tcx> {
312355
def_id: DefId,
313356
generic_args: mir_ty::GenericArgsRef<'tcx>,
314357
) -> Option<rty::RefinedType> {
358+
let type_builder = TypeBuilder::new(self.tcx, def_id);
359+
315360
let deferred_ty = match self.defs.get(&def_id)? {
316361
DefTy::Concrete(rty) => {
317-
let type_builder = TypeBuilder::new(self.tcx, def_id);
318-
319362
let mut def_ty = rty.clone();
320363
def_ty.instantiate_ty_params(
321364
generic_args
@@ -333,16 +376,29 @@ impl<'tcx> Analyzer<'tcx> {
333376
if let Some(rty) = deferred_ty_cache.borrow().get(&generic_args) {
334377
return Some(rty.clone());
335378
}
379+
let deferred_ty_mode = deferred_ty.mode;
336380

337-
let mut analyzer = self.local_def_analyzer(def_id.as_local()?);
381+
let mut analyzer = self.local_def_analyzer(deferred_ty.local_def_id);
338382
analyzer.generic_args(generic_args);
339383

340-
let expected = analyzer.expected_ty();
384+
let mut expected = analyzer.expected_ty();
385+
// parameters in annotations are left as params
386+
// TODO: remove this after annotation V2
387+
expected.instantiate_ty_params(
388+
generic_args
389+
.types()
390+
.map(|ty| type_builder.build(ty))
391+
.map(rty::RefinedType::unrefined)
392+
.collect(),
393+
);
341394
deferred_ty_cache
342395
.borrow_mut()
343396
.insert(generic_args, expected.clone());
397+
tracing::info!(?def_id, rty = %expected.display(), ?generic_args, "deferred def");
344398

345-
analyzer.run(&expected);
399+
if deferred_ty_mode.should_analyze() {
400+
analyzer.run(&expected);
401+
}
346402
Some(expected)
347403
}
348404

src/analyze/crate_.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,16 +94,22 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> {
9494
return;
9595
}
9696

97+
let target_def_id = if analyzer.is_annotated_as_extern_spec_fn() {
98+
analyzer.extern_spec_fn_target_def_id()
99+
} else {
100+
local_def_id.to_def_id()
101+
};
102+
97103
use mir_ty::TypeVisitableExt as _;
98-
if sig.has_param() && !analyzer.is_fully_annotated() {
99-
self.ctx.register_deferred_def(local_def_id.to_def_id());
104+
if sig.has_param() {
105+
if self.skip_analysis.contains(&local_def_id) {
106+
self.ctx
107+
.register_deferred_def_without_analysis(target_def_id, local_def_id);
108+
} else {
109+
self.ctx.register_deferred_def(local_def_id);
110+
}
100111
} else {
101112
let expected = analyzer.expected_ty();
102-
let target_def_id = if analyzer.is_annotated_as_extern_spec_fn() {
103-
analyzer.extern_spec_fn_target_def_id()
104-
} else {
105-
local_def_id.to_def_id()
106-
};
107113
self.ctx.register_def(target_def_id, expected);
108114
}
109115
}

0 commit comments

Comments
 (0)