Auto merge of #68803 - Dylan-DPC:rollup-b4x6ghj, r=Dylan-DPC
Rollup of 8 pull requests Successful merges: - #68678 (Install robots.txt into rust-docs tarballs) - #68711 (Added upper bound of what vecs and boxes can allocate) - #68744 (Do not ICE in `type-alias-impl-trait` with save-analysis) - #68777 (Clean up E0263 explanation) - #68787 (Optimize core::ptr::align_offset (part 1)) - #68797 (Fix links to types instead of modules) - #68798 (Test that `#[track_caller]` as `fn()` respects RT / CTFE equivalence) - #68800 (Stabilize `core::iter::once_with()`) Failed merges: r? @ghost
This commit is contained in:
commit
8417d68de5
19 changed files with 123 additions and 42 deletions
|
@ -105,6 +105,7 @@ impl Step for Docs {
|
||||||
t!(fs::create_dir_all(&dst));
|
t!(fs::create_dir_all(&dst));
|
||||||
let src = builder.doc_out(host);
|
let src = builder.doc_out(host);
|
||||||
builder.cp_r(&src, &dst);
|
builder.cp_r(&src, &dst);
|
||||||
|
builder.install(&builder.src.join("src/doc/robots.txt"), &dst, 0o644);
|
||||||
|
|
||||||
let mut cmd = rust_installer(builder);
|
let mut cmd = rust_installer(builder);
|
||||||
cmd.arg("generate")
|
cmd.arg("generate")
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# NB: This file is not automatically deployed. After changes, it needs to be uploaded manually to doc.rust-lang.org
|
|
||||||
User-agent: *
|
User-agent: *
|
||||||
Disallow: /0.3/
|
Disallow: /0.3/
|
||||||
Disallow: /0.4/
|
Disallow: /0.4/
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
//!
|
//!
|
||||||
//! [`Box<T>`], casually referred to as a 'box', provides the simplest form of
|
//! [`Box<T>`], casually referred to as a 'box', provides the simplest form of
|
||||||
//! heap allocation in Rust. Boxes provide ownership for this allocation, and
|
//! heap allocation in Rust. Boxes provide ownership for this allocation, and
|
||||||
//! drop their contents when they go out of scope.
|
//! drop their contents when they go out of scope. Boxes also ensure that they
|
||||||
|
//! never allocate more than `isize::MAX` bytes.
|
||||||
//!
|
//!
|
||||||
//! # Examples
|
//! # Examples
|
||||||
//!
|
//!
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
//! Vectors have `O(1)` indexing, amortized `O(1)` push (to the end) and
|
//! Vectors have `O(1)` indexing, amortized `O(1)` push (to the end) and
|
||||||
//! `O(1)` pop (from the end).
|
//! `O(1)` pop (from the end).
|
||||||
//!
|
//!
|
||||||
|
//! Vectors ensure they never allocate more than `isize::MAX` bytes.
|
||||||
|
//!
|
||||||
//! # Examples
|
//! # Examples
|
||||||
//!
|
//!
|
||||||
//! You can explicitly create a [`Vec<T>`] with [`new`]:
|
//! You can explicitly create a [`Vec<T>`] with [`new`]:
|
||||||
|
|
|
@ -327,7 +327,7 @@ pub use self::sources::{empty, Empty};
|
||||||
pub use self::sources::{from_fn, FromFn};
|
pub use self::sources::{from_fn, FromFn};
|
||||||
#[stable(feature = "iter_once", since = "1.2.0")]
|
#[stable(feature = "iter_once", since = "1.2.0")]
|
||||||
pub use self::sources::{once, Once};
|
pub use self::sources::{once, Once};
|
||||||
#[unstable(feature = "iter_once_with", issue = "57581")]
|
#[stable(feature = "iter_once_with", since = "1.43.0")]
|
||||||
pub use self::sources::{once_with, OnceWith};
|
pub use self::sources::{once_with, OnceWith};
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use self::sources::{repeat, Repeat};
|
pub use self::sources::{repeat, Repeat};
|
||||||
|
|
|
@ -399,12 +399,12 @@ pub fn once<T>(value: T) -> Once<T> {
|
||||||
///
|
///
|
||||||
/// [`once_with`]: fn.once_with.html
|
/// [`once_with`]: fn.once_with.html
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
#[unstable(feature = "iter_once_with", issue = "57581")]
|
#[stable(feature = "iter_once_with", since = "1.43.0")]
|
||||||
pub struct OnceWith<F> {
|
pub struct OnceWith<F> {
|
||||||
gen: Option<F>,
|
gen: Option<F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "iter_once_with", issue = "57581")]
|
#[stable(feature = "iter_once_with", since = "1.43.0")]
|
||||||
impl<A, F: FnOnce() -> A> Iterator for OnceWith<F> {
|
impl<A, F: FnOnce() -> A> Iterator for OnceWith<F> {
|
||||||
type Item = A;
|
type Item = A;
|
||||||
|
|
||||||
|
@ -420,24 +420,24 @@ impl<A, F: FnOnce() -> A> Iterator for OnceWith<F> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "iter_once_with", issue = "57581")]
|
#[stable(feature = "iter_once_with", since = "1.43.0")]
|
||||||
impl<A, F: FnOnce() -> A> DoubleEndedIterator for OnceWith<F> {
|
impl<A, F: FnOnce() -> A> DoubleEndedIterator for OnceWith<F> {
|
||||||
fn next_back(&mut self) -> Option<A> {
|
fn next_back(&mut self) -> Option<A> {
|
||||||
self.next()
|
self.next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "iter_once_with", issue = "57581")]
|
#[stable(feature = "iter_once_with", since = "1.43.0")]
|
||||||
impl<A, F: FnOnce() -> A> ExactSizeIterator for OnceWith<F> {
|
impl<A, F: FnOnce() -> A> ExactSizeIterator for OnceWith<F> {
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
self.gen.iter().len()
|
self.gen.iter().len()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "iter_once_with", issue = "57581")]
|
#[stable(feature = "iter_once_with", since = "1.43.0")]
|
||||||
impl<A, F: FnOnce() -> A> FusedIterator for OnceWith<F> {}
|
impl<A, F: FnOnce() -> A> FusedIterator for OnceWith<F> {}
|
||||||
|
|
||||||
#[unstable(feature = "iter_once_with", issue = "57581")]
|
#[stable(feature = "iter_once_with", since = "1.43.0")]
|
||||||
unsafe impl<A, F: FnOnce() -> A> TrustedLen for OnceWith<F> {}
|
unsafe impl<A, F: FnOnce() -> A> TrustedLen for OnceWith<F> {}
|
||||||
|
|
||||||
/// Creates an iterator that lazily generates a value exactly once by invoking
|
/// Creates an iterator that lazily generates a value exactly once by invoking
|
||||||
|
@ -458,8 +458,6 @@ unsafe impl<A, F: FnOnce() -> A> TrustedLen for OnceWith<F> {}
|
||||||
/// Basic usage:
|
/// Basic usage:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(iter_once_with)]
|
|
||||||
///
|
|
||||||
/// use std::iter;
|
/// use std::iter;
|
||||||
///
|
///
|
||||||
/// // one is the loneliest number
|
/// // one is the loneliest number
|
||||||
|
@ -476,8 +474,6 @@ unsafe impl<A, F: FnOnce() -> A> TrustedLen for OnceWith<F> {}
|
||||||
/// `.foorc`:
|
/// `.foorc`:
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// #![feature(iter_once_with)]
|
|
||||||
///
|
|
||||||
/// use std::iter;
|
/// use std::iter;
|
||||||
/// use std::fs;
|
/// use std::fs;
|
||||||
/// use std::path::PathBuf;
|
/// use std::path::PathBuf;
|
||||||
|
@ -500,7 +496,7 @@ unsafe impl<A, F: FnOnce() -> A> TrustedLen for OnceWith<F> {}
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable(feature = "iter_once_with", issue = "57581")]
|
#[stable(feature = "iter_once_with", since = "1.43.0")]
|
||||||
pub fn once_with<A, F: FnOnce() -> A>(gen: F) -> OnceWith<F> {
|
pub fn once_with<A, F: FnOnce() -> A>(gen: F) -> OnceWith<F> {
|
||||||
OnceWith { gen: Some(gen) }
|
OnceWith { gen: Some(gen) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,6 @@
|
||||||
#![feature(intrinsics)]
|
#![feature(intrinsics)]
|
||||||
#![feature(try_find)]
|
#![feature(try_find)]
|
||||||
#![feature(is_sorted)]
|
#![feature(is_sorted)]
|
||||||
#![feature(iter_once_with)]
|
|
||||||
#![feature(lang_items)]
|
#![feature(lang_items)]
|
||||||
#![feature(link_llvm_intrinsics)]
|
#![feature(link_llvm_intrinsics)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
|
|
|
@ -1081,9 +1081,8 @@ pub(crate) unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize {
|
||||||
// uses e.g., subtraction `mod n`. It is entirely fine to do them `mod
|
// uses e.g., subtraction `mod n`. It is entirely fine to do them `mod
|
||||||
// usize::max_value()` instead, because we take the result `mod n` at the end
|
// usize::max_value()` instead, because we take the result `mod n` at the end
|
||||||
// anyway.
|
// anyway.
|
||||||
inverse = inverse.wrapping_mul(2usize.wrapping_sub(x.wrapping_mul(inverse)))
|
inverse = inverse.wrapping_mul(2usize.wrapping_sub(x.wrapping_mul(inverse)));
|
||||||
& (going_mod - 1);
|
if going_mod >= m {
|
||||||
if going_mod > m {
|
|
||||||
return inverse & (m - 1);
|
return inverse & (m - 1);
|
||||||
}
|
}
|
||||||
going_mod = going_mod.wrapping_mul(going_mod);
|
going_mod = going_mod.wrapping_mul(going_mod);
|
||||||
|
@ -1115,26 +1114,33 @@ pub(crate) unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize {
|
||||||
let gcdpow = intrinsics::cttz_nonzero(stride).min(intrinsics::cttz_nonzero(a));
|
let gcdpow = intrinsics::cttz_nonzero(stride).min(intrinsics::cttz_nonzero(a));
|
||||||
let gcd = 1usize << gcdpow;
|
let gcd = 1usize << gcdpow;
|
||||||
|
|
||||||
if p as usize & (gcd - 1) == 0 {
|
if p as usize & (gcd.wrapping_sub(1)) == 0 {
|
||||||
// This branch solves for the following linear congruence equation:
|
// This branch solves for the following linear congruence equation:
|
||||||
//
|
//
|
||||||
// $$ p + so ≡ 0 mod a $$
|
// ` p + so = 0 mod a `
|
||||||
//
|
//
|
||||||
// $p$ here is the pointer value, $s$ – stride of `T`, $o$ offset in `T`s, and $a$ – the
|
// `p` here is the pointer value, `s` - stride of `T`, `o` offset in `T`s, and `a` - the
|
||||||
// requested alignment.
|
// requested alignment.
|
||||||
//
|
//
|
||||||
// g = gcd(a, s)
|
// With `g = gcd(a, s)`, and the above asserting that `p` is also divisible by `g`, we can
|
||||||
// o = (a - (p mod a))/g * ((s/g)⁻¹ mod a)
|
// denote `a' = a/g`, `s' = s/g`, `p' = p/g`, then this becomes equivalent to:
|
||||||
//
|
//
|
||||||
// The first term is “the relative alignment of p to a”, the second term is “how does
|
// ` p' + s'o = 0 mod a' `
|
||||||
// incrementing p by s bytes change the relative alignment of p”. Division by `g` is
|
// ` o = (a' - (p' mod a')) * (s'^-1 mod a') `
|
||||||
// necessary to make this equation well formed if $a$ and $s$ are not co-prime.
|
|
||||||
//
|
//
|
||||||
// Furthermore, the result produced by this solution is not “minimal”, so it is necessary
|
// The first term is "the relative alignment of `p` to `a`" (divided by the `g`), the second
|
||||||
// to take the result $o mod lcm(s, a)$. We can replace $lcm(s, a)$ with just a $a / g$.
|
// term is "how does incrementing `p` by `s` bytes change the relative alignment of `p`" (again
|
||||||
let j = a.wrapping_sub(pmoda) >> gcdpow;
|
// divided by `g`).
|
||||||
let k = smoda >> gcdpow;
|
// Division by `g` is necessary to make the inverse well formed if `a` and `s` are not
|
||||||
return intrinsics::unchecked_rem(j.wrapping_mul(mod_inv(k, a)), a >> gcdpow);
|
// co-prime.
|
||||||
|
//
|
||||||
|
// Furthermore, the result produced by this solution is not "minimal", so it is necessary
|
||||||
|
// to take the result `o mod lcm(s, a)`. We can replace `lcm(s, a)` with just a `a'`.
|
||||||
|
let a2 = a >> gcdpow;
|
||||||
|
let a2minus1 = a2.wrapping_sub(1);
|
||||||
|
let s2 = smoda >> gcdpow;
|
||||||
|
let minusp2 = a2.wrapping_sub(pmoda >> gcdpow);
|
||||||
|
return (minusp2.wrapping_mul(mod_inv(s2, a2))) & a2minus1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cannot be aligned at all.
|
// Cannot be aligned at all.
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#![feature(hashmap_internals)]
|
#![feature(hashmap_internals)]
|
||||||
#![feature(try_find)]
|
#![feature(try_find)]
|
||||||
#![feature(is_sorted)]
|
#![feature(is_sorted)]
|
||||||
#![feature(iter_once_with)]
|
|
||||||
#![feature(pattern)]
|
#![feature(pattern)]
|
||||||
#![feature(range_is_empty)]
|
#![feature(range_is_empty)]
|
||||||
#![feature(raw)]
|
#![feature(raw)]
|
||||||
|
|
|
@ -1,7 +1,16 @@
|
||||||
A lifetime name cannot be declared more than once in the same scope. For
|
A lifetime was declared more than once in the same scope.
|
||||||
example:
|
|
||||||
|
Erroneous code example:
|
||||||
|
|
||||||
```compile_fail,E0263
|
```compile_fail,E0263
|
||||||
// error, lifetime name `'a` declared twice in the same scope
|
fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str, z: &'a str) { // error!
|
||||||
fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { }
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Two lifetimes cannot have the same name. To fix this example, change
|
||||||
|
the second `'a` lifetime into something else (`'c` for example):
|
||||||
|
|
||||||
|
```
|
||||||
|
fn foo<'a, 'b, 'c>(x: &'a str, y: &'b str, z: &'c str) { // ok!
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -837,8 +837,11 @@ fn has_typeck_tables(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||||
return tcx.has_typeck_tables(outer_def_id);
|
return tcx.has_typeck_tables(outer_def_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
let id = tcx.hir().as_local_hir_id(def_id).unwrap();
|
if let Some(id) = tcx.hir().as_local_hir_id(def_id) {
|
||||||
primary_body_of(tcx, id).is_some()
|
primary_body_of(tcx, id).is_some()
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn used_trait_imports(tcx: TyCtxt<'_>, def_id: DefId) -> &DefIdSet {
|
fn used_trait_imports(tcx: TyCtxt<'_>, def_id: DefId) -> &DefIdSet {
|
||||||
|
|
|
@ -163,11 +163,11 @@
|
||||||
//! [`Iterator`]: iter/trait.Iterator.html
|
//! [`Iterator`]: iter/trait.Iterator.html
|
||||||
//! [`Mutex`]: sync/struct.Mutex.html
|
//! [`Mutex`]: sync/struct.Mutex.html
|
||||||
//! [`Option<T>`]: option/enum.Option.html
|
//! [`Option<T>`]: option/enum.Option.html
|
||||||
//! [`Rc`]: rc/index.html
|
//! [`Rc`]: rc/struct.Rc.html
|
||||||
//! [`RefCell`]: cell/struct.RefCell.html
|
//! [`RefCell`]: cell/struct.RefCell.html
|
||||||
//! [`Result<T, E>`]: result/enum.Result.html
|
//! [`Result<T, E>`]: result/enum.Result.html
|
||||||
//! [`String`]: string/struct.String.html
|
//! [`String`]: string/struct.String.html
|
||||||
//! [`Vec<T>`]: vec/index.html
|
//! [`Vec<T>`]: vec/struct.Vec.html
|
||||||
//! [array]: primitive.array.html
|
//! [array]: primitive.array.html
|
||||||
//! [slice]: primitive.slice.html
|
//! [slice]: primitive.slice.html
|
||||||
//! [`atomic`]: sync/atomic/index.html
|
//! [`atomic`]: sync/atomic/index.html
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
// Ensure that a `#[track_caller]` function, returning `caller_location()`,
|
||||||
|
// which coerced (to a function pointer) and called, inside a `const fn`,
|
||||||
|
// in turn called, results in the same output irrespective of whether
|
||||||
|
// we're in a const or runtime context.
|
||||||
|
|
||||||
|
// run-pass
|
||||||
|
// compile-flags: -Z unleash-the-miri-inside-of-you
|
||||||
|
|
||||||
|
#![feature(core_intrinsics, const_caller_location, track_caller, const_fn)]
|
||||||
|
|
||||||
|
type L = &'static std::panic::Location<'static>;
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
const fn attributed() -> L {
|
||||||
|
std::intrinsics::caller_location()
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn calling_attributed() -> L {
|
||||||
|
// We need `-Z unleash-the-miri-inside-of-you` for this as we don't have `const fn` pointers.
|
||||||
|
let ptr: fn() -> L = attributed;
|
||||||
|
ptr() //~ WARN skipping const checks
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
const CONSTANT: L = calling_attributed();
|
||||||
|
let runtime = calling_attributed();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
(runtime.file(), runtime.line(), runtime.column()),
|
||||||
|
(CONSTANT.file(), CONSTANT.line(), CONSTANT.column()),
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
warning: skipping const checks
|
||||||
|
--> $DIR/caller-location-fnptr-rt-ctfe-equiv.rs:21:5
|
||||||
|
|
|
||||||
|
LL | ptr()
|
||||||
|
| ^^^^^
|
||||||
|
|
17
src/test/ui/save-analysis/issue-68621.rs
Normal file
17
src/test/ui/save-analysis/issue-68621.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// compile-flags: -Zsave-analysis
|
||||||
|
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
trait Trait {}
|
||||||
|
|
||||||
|
trait Service {
|
||||||
|
type Future: Trait;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Struct;
|
||||||
|
|
||||||
|
impl Service for Struct {
|
||||||
|
type Future = impl Trait; //~ ERROR: could not find defining uses
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
8
src/test/ui/save-analysis/issue-68621.stderr
Normal file
8
src/test/ui/save-analysis/issue-68621.stderr
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
error: could not find defining uses
|
||||||
|
--> $DIR/issue-68621.rs:14:5
|
||||||
|
|
|
||||||
|
LL | type Future = impl Trait;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// compile-flags: -Zsave-analysis
|
||||||
|
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
type Closure = impl FnOnce(); //~ ERROR: type mismatch resolving
|
type Closure = impl FnOnce(); //~ ERROR: type mismatch resolving
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0271]: type mismatch resolving `<[closure@$DIR/issue-63279.rs:6:5: 6:28] as std::ops::FnOnce<()>>::Output == ()`
|
error[E0271]: type mismatch resolving `<[closure@$DIR/issue-63279.rs:8:5: 8:28] as std::ops::FnOnce<()>>::Output == ()`
|
||||||
--> $DIR/issue-63279.rs:3:1
|
--> $DIR/issue-63279.rs:5:1
|
||||||
|
|
|
|
||||||
LL | type Closure = impl FnOnce();
|
LL | type Closure = impl FnOnce();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found `()`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found `()`
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// compile-flags: -Zsave-analysis
|
||||||
// check-pass
|
// check-pass
|
||||||
|
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue