Skip to content

Conversation

@ShoyuVanilla
Copy link
Contributor

I found this while working on model-checking/verify-rust-std#382.

When you try to add #[proof_for_contract(Rc::<MaybeUninit<T>, A>::assume_init)] to a proof for this function https://doc.rust-lang.org/1.90.0/src/alloc/rc.rs.html#1211, kani fails to resolve Rc::<MaybeUninit<T>, A>::assume_init, as it compares the last two parts of the path string,

fn last_two_items_of_path_match(item_path: &str, generic_args: &str, name: &str) -> bool {
let parts: Vec<&str> = item_path.split("::").collect();
if parts.len() < 2 {
return false;
}
let actual_last_two =
format!("{}{}{}{}", "::", parts[parts.len() - 2], "::", parts[parts.len() - 1]);
let last_two = format!("{}{}{}", generic_args, "::", name);
// The last two components of the item_path should be the same as ::{generic_args}::{name}
last_two == actual_last_two
}

But rustc's TyCtxt::def_path_str emits the path rc::Rc::<core::mem::MaybeUninit<T>, A>::assmue_init even if there's use core::mem::MaybeUninit in scope. So the last two parts of it is ::MaybeUninit<T>, A>::assmue_init, instead of being ::<core::mem::MaybeUninit<T>, A>::assmue_init, and the resolution fails.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.

@ShoyuVanilla ShoyuVanilla requested a review from a team as a code owner October 25, 2025 05:28
@github-actions github-actions bot added Z-EndToEndBenchCI Tag a PR to run benchmark CI Z-CompilerBenchCI Tag a PR to run benchmark CI labels Oct 25, 2025
Err(ResolveError::UnexpectedType { tcx, item: base, expected: "module" })
}
};
base.map(|base| (base, segment.arguments))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to fix argument passings when it is prefixed with module paths like foo::bar::Baz::<..>


// The last two components of the item_path should be the same as ::{generic_args}::{name}
last_two == actual_last_two
last_two.chars().eq(actual_last_two.chars().filter(|c| !c.is_whitespace()))
Copy link
Contributor Author

@ShoyuVanilla ShoyuVanilla Oct 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We strip whitespaces from the generic args here:

fn generic_args_to_string<T: ToTokens>(args: &T) -> String {
args.to_token_stream().to_string().chars().filter(|c| !c.is_whitespace()).collect::<String>()
}

So multiple args like <T, A> become <T,A>. This is necessary for matching those things.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Z-CompilerBenchCI Tag a PR to run benchmark CI Z-EndToEndBenchCI Tag a PR to run benchmark CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant