interpret: err instead of ICE on size mismatches in to_bits_or_ptr_internal
We did this a while ago already for `to_i32()` and friends, but missed this one. That became quite annoying when I was debugging an ICE caused by `read_pointer` in a Miri shim where the code was passing an argument at the wrong type.
Having `scalar_to_ptr` be fallible is consistent with all the other `Scalar::to_*` methods being fallible. I added `unwrap` only in code outside the interpreter, which is no worse off than before now in terms of panics.
r? ````@oli-obk````
Hide cross-crate `#[doc(hidden)]` associated items in trait impls
Fixes#95717.
r? ```@GuillaumeGomez```
This is the bug I ran into in #95316.
```@rustbot``` label T-rustdoc A-cross-crate-reexports
Reduce the amount of unstable features used in libproc_macro
This makes it easier to adapt the source for stable when copying it into rust-analyzer to load rustc compiled proc macros.
CI: update `rustc-perf` version used in CI and also the corresponding PGO benchmarks
The old version was from May 2021. The `rustc-perf` benchmarks have seen a significant overhaul recently, so let's see if the new benchmarks can improve PGO performance.
Remove explicit delimiter token trees from `Delimited`.
They were introduced by the final commit in #95159 and gave a
performance win. But since the introduction of `MatcherLoc` they are no
longer needed. This commit reverts that change, making the code a bit
simpler.
r? `@petrochenkov`
[macro_metavar_expr] Add tests to ensure the feature requirement
These tests should have been added in the initial implementation they were unintentionally forgotten
cc #83527
r? ````@petrochenkov````
Strict provenance lints
See #95488.
This PR introduces two unstable (allow by default) lints to which lint on int2ptr and ptr2int casts, as the former is not possible in the strict provenance model and the latter can be written nicer using the `.addr()` API.
Based on an initial version of the lint by ```@Gankra``` in #95199.
assert_uninit_valid: ensure we detect at least arrays of uninhabited types
We can't easily extend this check to *all* arrays (Cc https://github.com/rust-lang/rust/pull/87041), but it turns out the existing check already catches arrays of uninhabited types. So let's make sure it stays that way by adding them to the test.
Since https://github.com/rust-lang/rust/pull/95340 landed, Miri with
-Zmiri-check-number-validity produces an error on the test suites of
some crates which implement concurrency tools, because it seems like
such crates tend to use std::sync::mpsc in their tests. This fixes the
problem by storing pointer bytes in a pointer.
Inspired by the zulip conversation about how `Layout` should better enforce `size < isize::MAX as usize`, this uses an N-variant enum on N-bit platforms to require at the validity level that the existing invariant of "must be a power of two" is upheld.
This was MIRI can catch it, and means there's a more-specific type for `Layout` to store than just `NonZeroUsize`.
Cached stable hash cleanups
r? `@nnethercote`
Add a sanity assertion in debug mode to check that the cached hashes are actually the ones we get if we compute the hash each time.
Add a new data structure that bundles all the hash-caching work to make it easier to re-use it for different interned data structures
They were introduced by the final commit in #95159 and gave a
performance win. But since the introduction of `MatcherLoc` they are no
longer needed. This commit reverts that change, making the code a bit
simpler.
Enforce well formedness for type alias impl trait's hidden type
fixes#84657
This was not an issue with return-position-impl-trait because the generic bounds of the function are the same as those of the opaque type, and the hidden type must already be well formed within the function.
With type-alias-impl-trait the hidden type could be defined in a function that has *more* lifetime bounds than the type alias. This is fine, but the hidden type must still be well formed without those additional bounds.
Relevant commit messages from squashed history in order:
Add initial version of ThinBox
update test to actually capture failure
swap to middle ptr impl based on matthieu-m's design
Fix stack overflow in debug impl
The previous version would take a `&ThinBox<T>` and deref it once, which
resulted in a no-op and the same type, which it would then print causing
an endless recursion. I've switched to calling `deref` by name to let
method resolution handle deref the correct number of times.
I've also updated the Drop impl for good measure since it seemed like it
could be falling prey to the same bug, and I'll be adding some tests to
verify that the drop is happening correctly.
add test to verify drop is behaving
add doc examples and remove unnecessary Pointee bounds
ThinBox: use NonNull
ThinBox: tests for size
Apply suggestions from code review
Co-authored-by: Alphyr <47725341+a1phyr@users.noreply.github.com>
use handle_alloc_error and fix drop signature
update niche and size tests
add cfg for allocating APIs
check null before calculating offset
add test for zst and trial usage
prevent optimizer induced ub in drop and cleanup metadata gathering
account for arbitrary size and alignment metadata
Thank you nika and thomcc!
Update library/alloc/src/boxed/thin.rs
Co-authored-by: Josh Triplett <josh@joshtriplett.org>
Update library/alloc/src/boxed/thin.rs
Co-authored-by: Josh Triplett <josh@joshtriplett.org>
* split `fuzzy_provenance_casts` into a ptr2int and a int2ptr lint
* feature gate both lints
* update documentation to be more realistic short term
* add tests for these lints
Windows: Increase a pipe's buffer capacity to 64kb
This brings it inline with typical Linux defaults: https://www.man7.org/linux/man-pages/man7/pipe.7.html
> Since Linux 2.6.11, the pipe capacity is 16 pages (i.e., 65,536 bytes in a system with a page size of 4096 bytes).
This may also help with #45572 and #95759 but does not fix either issue. It simply makes them much less likely to be encountered.
Promote x86_64-unknown-none target to Tier 2 and distribute build artifacts
This implements https://github.com/rust-lang/compiler-team/issues/499 , in which the compiler team accepted the x86_64-unknown-none target for promotion to a Tier 2 platform.
Mailmap update
I noticed there are a lot of contributors who appear multiple times in https://thanks.rust-lang.org/rust/all-time/, which makes their "rank" on that page inaccurate. For example Nick Cameron currently appears at rank 21 with 2010 contributions and at rank 27 with 1287 contributions, because some of those are from nrc⁠```@ncameron.org``` and some from ncameron⁠```@mozilla.com.``` In reality Nick's rank would be 11 if counted correctly, which is a large difference.
Solving this in a totally automated way is tricky because it involves figuring out whether Nick is 1 person with multiple emails, or is 2 people sharing the same name.
This PR addresses a subset of the cases: only where a person has committed under multiple names using the same email. This is still not something that can be totally automated (e.g. by modifying https://github.com/rust-lang/thanks to dedup by email instead of name+email) because:
- Some emails are not necessarily unique to one contributor, such as `ubuntu@localhost`.
- It involves some judgement and mindfulness in picking the "canonical name" among the names used with a particular email. This is the name that will appear on thanks.rust-lang.org. Humans change their names sometimes and can be sensitive or picky about the use of names that are no longer preferred.
For the purpose of this PR, I've tried to stick to the following heuristics which should be unobjectionable:
- If one of the names is currently set as the display name on the contributor's GitHub profile, prefer that name.
- If one of the names is used exclusively over the others in chronologically newer pull requests, prefer the newest name.
- If one of the names has whitespace and the other doesn't (i.e. is username-like), such as `Foo Bar` vs `FooBar` or `foobar` or `foo-bar123`, but otherwise closely resemble one another, then prefer the human-like name.
- If none of the above suffice in determining a canonical name and the contributor has some other name set on their GitHub profile, use the name from the GitHub profile.
- If no name on their GitHub profile but the profile links to their personal website which unambiguously identifies their preferred name, then use that name.
I'm also thinking about how to handle cases like Nick's, but that will be a project for a different PR. Basically I'd like to be able to find cases of the same person making commits that differ in name *and* email by looking at all the commits present in pull requests opened by the same GitHub user.
<details>
<summary>script</summary>
```toml
[dependencies]
anyhow = "1.0"
git2 = "0.14"
mailmap = "0.1"
```
```rust
use anyhow::{bail, Context, Result};
use git2::{Commit, Oid, Repository};
use mailmap::{Author, Mailmap};
use std::collections::{BTreeMap as Map, BTreeSet as Set};
use std::fmt::{self, Debug};
use std::fs;
use std::path::Path;
const REPO: &str = "/git/rust";
fn main() -> Result<()> {
let repo = Repository::open(REPO)?;
let head_oid = repo
.head()?
.target()
.context("expected head to be a direct reference")?;
let head = repo.find_commit(head_oid)?;
let mailmap_path = Path::new(REPO).join(".mailmap");
let mailmap_contents = fs::read_to_string(mailmap_path)?;
let mailmap = match Mailmap::from_string(mailmap_contents) {
Ok(mailmap) => mailmap,
Err(box_error) => bail!("{}", box_error),
};
let mut history = Set::new();
let mut merges = Vec::new();
let mut authors = Set::new();
let mut emails = Map::new();
let mut all_authors = Set::new();
traverse_left(head, &mut history, &mut merges, &mut authors, &mailmap)?;
while let Some((commit, i)) = merges.pop() {
let right = commit.parents().nth(i).unwrap();
authors.clear();
traverse_left(right, &mut history, &mut merges, &mut authors, &mailmap)?;
for author in &authors {
all_authors.insert(author.clone());
if !author.email.is_empty() {
emails
.entry(author.email.clone())
.or_insert_with(Map::new)
.entry(author.name.clone())
.or_insert_with(Set::new);
}
}
if let Some(summary) = commit.summary() {
if let Some(pr) = parse_summary(summary)? {
for author in &authors {
if !author.email.is_empty() {
emails
.get_mut(&author.email)
.unwrap()
.get_mut(&author.name)
.unwrap()
.insert(pr);
}
}
}
}
}
for (email, names) in emails {
if names.len() > 1 {
println!("<{}>", email);
for (name, prs) in names {
let prs = DebugSet(prs.iter().rev());
println!(" {} {:?}", name, prs);
}
}
}
eprintln!("{} commits", history.len());
eprintln!("{} authors", all_authors.len());
Ok(())
}
fn traverse_left<'repo>(
mut commit: Commit<'repo>,
history: &mut Set<Oid>,
merges: &mut Vec<(Commit<'repo>, usize)>,
authors: &mut Set<Author>,
mailmap: &Mailmap,
) -> Result<()> {
loop {
let oid = commit.id();
if !history.insert(oid) {
return Ok(());
}
let author = author(mailmap, &commit);
let is_bors = author.name == "bors" && author.email == "bors@rust-lang.org";
if !is_bors {
authors.insert(author);
}
let mut parents = commit.parents();
let parent = match parents.next() {
Some(parent) => parent,
None => return Ok(()),
};
for i in 1..1 + parents.len() {
merges.push((commit.clone(), i));
}
commit = parent;
}
}
fn parse_summary(summary: &str) -> Result<Option<PullRequest>> {
let mut rest = None;
for prefix in [
"Auto merge of #",
"Merge pull request #",
" Manual merge of #",
"auto merge of #",
"auto merge of pull req #",
"rollup merge of #",
"Rollup merge of #",
"Rollup merge of #",
"Rollup merge of ",
"Merge PR #",
"Merge #",
"Merged #",
] {
if summary.starts_with(prefix) {
rest = Some(&summary[prefix.len()..]);
break;
}
}
let rest = match rest {
Some(rest) => rest,
None => return Ok(None),
};
let end = rest.find([' ', ':']).unwrap_or(rest.len());
let number = match rest[..end].parse::<u32>() {
Ok(number) => number,
Err(err) => {
eprintln!("{}", summary);
bail!(err);
}
};
Ok(Some(PullRequest(number)))
}
fn author(mailmap: &Mailmap, commit: &Commit) -> Author {
let signature = commit.author();
let name = String::from_utf8_lossy(signature.name_bytes()).into_owned();
let email = String::from_utf8_lossy(signature.email_bytes()).into_owned();
mailmap.canonicalize(&Author { name, email })
}
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
struct PullRequest(u32);
impl Debug for PullRequest {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "#{}", self.0)
}
}
struct DebugSet<T>(T);
impl<T> Debug for DebugSet<T>
where
T: Iterator + Clone,
T::Item: Debug,
{
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.debug_set().entries(self.0.clone()).finish()
}
}
```
</details>