Skip to content

Commit 78ed922

Browse files
committed
add: reference trait-side definitions for require/ensure annotations of
functions in impl blocks
1 parent 0c08a03 commit 78ed922

1 file changed

Lines changed: 32 additions & 12 deletions

File tree

src/analyze/local_def.rs

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,13 @@ pub struct Analyzer<'tcx, 'ctx> {
5353
}
5454

5555
impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> {
56-
fn extract_require_annot<T>(&self, resolver: T) -> Option<AnnotFormula<T::Output>>
56+
fn extract_require_annot<T>(&self, def_id: DefId, resolver: T) -> Option<AnnotFormula<T::Output>>
5757
where
5858
T: annot::Resolver,
5959
{
6060
let mut require_annot = None;
6161
for attrs in self.tcx.get_attrs_by_path(
62-
self.local_def_id.to_def_id(),
62+
def_id,
6363
&analyze::annot::requires_path(),
6464
) {
6565
if require_annot.is_some() {
@@ -72,13 +72,13 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> {
7272
require_annot
7373
}
7474

75-
fn extract_ensure_annot<T>(&self, resolver: T) -> Option<AnnotFormula<T::Output>>
75+
fn extract_ensure_annot<T>(&self, def_id: DefId, resolver: T) -> Option<AnnotFormula<T::Output>>
7676
where
7777
T: annot::Resolver,
7878
{
7979
let mut ensure_annot = None;
8080
for attrs in self.tcx.get_attrs_by_path(
81-
self.local_def_id.to_def_id(),
81+
def_id,
8282
&analyze::annot::ensures_path(),
8383
) {
8484
if ensure_annot.is_some() {
@@ -252,6 +252,14 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> {
252252
|| (all_params_annotated && has_ret)
253253
}
254254

255+
pub fn get_trait_item(&mut self) -> Option<LocalDefId>
256+
{
257+
let impl_item_assoc = self.tcx.opt_associated_item(self.local_def_id.to_def_id())?;
258+
let trait_item_id = impl_item_assoc.trait_item_def_id.and_then(|id| id.as_local())?;
259+
260+
Some(trait_item_id)
261+
}
262+
255263
pub fn expected_ty(&mut self) -> rty::RefinedType {
256264
let sig = self
257265
.ctx
@@ -268,14 +276,26 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> {
268276
param_resolver.push_param(input_ident.name, input_ty.to_sort());
269277
}
270278

271-
let mut require_annot = self.extract_require_annot(&param_resolver);
272-
let mut ensure_annot = {
273-
let output_ty = self.type_builder.build(sig.output());
274-
let resolver = annot::StackedResolver::default()
275-
.resolver(analyze::annot::ResultResolver::new(output_ty.to_sort()))
276-
.resolver((&param_resolver).map(rty::RefinedTypeVar::Free));
277-
self.extract_ensure_annot(resolver)
278-
};
279+
let mut require_annot = self.extract_require_annot(self.local_def_id.to_def_id(), &param_resolver);
280+
281+
let output_ty = self.type_builder.build(sig.output());
282+
let result_param_resolver = annot::StackedResolver::default()
283+
.resolver(analyze::annot::ResultResolver::new(output_ty.to_sort()))
284+
.resolver((&param_resolver).map(rty::RefinedTypeVar::Free));
285+
let mut ensure_annot = self.extract_ensure_annot(self.local_def_id.to_def_id(), &result_param_resolver);
286+
287+
if let Some(trait_item_id) = self.get_trait_item(){
288+
tracing::info!("trait item fonud: {}", self.tcx.item_name(trait_item_id.into()).to_string());
289+
let trait_require_annot = self.extract_require_annot(trait_item_id.into(), &param_resolver);
290+
let trait_ensure_annot = self.extract_ensure_annot(trait_item_id.into(), &result_param_resolver);
291+
292+
assert!(require_annot.is_none() || trait_require_annot.is_none());
293+
require_annot = require_annot.or(trait_require_annot);
294+
295+
assert!(ensure_annot.is_none() || trait_ensure_annot.is_none());
296+
ensure_annot = ensure_annot.or(trait_ensure_annot);
297+
}
298+
279299
let param_annots = self.extract_param_annots(&param_resolver);
280300
let ret_annot = self.extract_ret_annot(&param_resolver);
281301

0 commit comments

Comments
 (0)