Skip to content

Commit 25b3db3

Browse files
committed
Auto merge of rust-lang#80560 - Mark-Simulacrum:beta-next, r=Mark-Simulacrum
[beta] backports This backports accepted PRs and switches to bootstrapping from the released compiler: * de-stabilize unsized raw ptr methods for Weak rust-lang#80422 * Use package name for top-level directory in bare tarballs rust-lang#80397 * Prevent caching normalization results with a cycle rust-lang#80246 r? `@Mark-Simulacrum`
2 parents 05b6023 + 89164cd commit 25b3db3

18 files changed

+174
-77
lines changed

compiler/rustc_infer/src/traits/project.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ impl ProjectionCacheKey<'tcx> {
9090
pub enum ProjectionCacheEntry<'tcx> {
9191
InProgress,
9292
Ambiguous,
93+
Recur,
9394
Error,
9495
NormalizedTy(NormalizedTy<'tcx>),
9596
}
@@ -143,7 +144,12 @@ impl<'tcx> ProjectionCache<'_, 'tcx> {
143144
"ProjectionCacheEntry::insert_ty: adding cache entry: key={:?}, value={:?}",
144145
key, value
145146
);
146-
let fresh_key = self.map().insert(key, ProjectionCacheEntry::NormalizedTy(value));
147+
let mut map = self.map();
148+
if let Some(ProjectionCacheEntry::Recur) = map.get(&key) {
149+
debug!("Not overwriting Recur");
150+
return;
151+
}
152+
let fresh_key = map.insert(key, ProjectionCacheEntry::NormalizedTy(value));
147153
assert!(!fresh_key, "never started projecting `{:?}`", key);
148154
}
149155

@@ -197,6 +203,14 @@ impl<'tcx> ProjectionCache<'_, 'tcx> {
197203
assert!(!fresh, "never started projecting `{:?}`", key);
198204
}
199205

206+
/// Indicates that while trying to normalize `key`, `key` was required to
207+
/// be normalized again. Selection or evaluation should eventually report
208+
/// an error here.
209+
pub fn recur(&mut self, key: ProjectionCacheKey<'tcx>) {
210+
let fresh = self.map().insert(key, ProjectionCacheEntry::Recur);
211+
assert!(!fresh, "never started projecting `{:?}`", key);
212+
}
213+
200214
/// Indicates that trying to normalize `key` resulted in
201215
/// error.
202216
pub fn error(&mut self, key: ProjectionCacheKey<'tcx>) {

compiler/rustc_trait_selection/src/traits/project.rs

+16-7
Original file line numberDiff line numberDiff line change
@@ -496,12 +496,6 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
496496
return Ok(None);
497497
}
498498
Err(ProjectionCacheEntry::InProgress) => {
499-
// If while normalized A::B, we are asked to normalize
500-
// A::B, just return A::B itself. This is a conservative
501-
// answer, in the sense that A::B *is* clearly equivalent
502-
// to A::B, though there may be a better value we can
503-
// find.
504-
505499
// Under lazy normalization, this can arise when
506500
// bootstrapping. That is, imagine an environment with a
507501
// where-clause like `A::B == u32`. Now, if we are asked
@@ -512,6 +506,14 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
512506

513507
debug!("found cache entry: in-progress");
514508

509+
// Cache that normalizing this projection resulted in a cycle. This
510+
// should ensure that, unless this happens within a snapshot that's
511+
// rolled back, fulfillment or evaluation will notice the cycle.
512+
513+
infcx.inner.borrow_mut().projection_cache().recur(cache_key);
514+
return Err(InProgress);
515+
}
516+
Err(ProjectionCacheEntry::Recur) => {
515517
return Err(InProgress);
516518
}
517519
Err(ProjectionCacheEntry::NormalizedTy(ty)) => {
@@ -734,7 +736,14 @@ fn project_type<'cx, 'tcx>(
734736

735737
if !selcx.tcx().sess.recursion_limit().value_within_limit(obligation.recursion_depth) {
736738
debug!("project: overflow!");
737-
return Err(ProjectionTyError::TraitSelectionError(SelectionError::Overflow));
739+
match selcx.query_mode() {
740+
super::TraitQueryMode::Standard => {
741+
selcx.infcx().report_overflow_error(&obligation, true);
742+
}
743+
super::TraitQueryMode::Canonical => {
744+
return Err(ProjectionTyError::TraitSelectionError(SelectionError::Overflow));
745+
}
746+
}
738747
}
739748

740749
let obligation_trait_ref = &obligation.predicate.trait_ref(selcx.tcx());

compiler/rustc_trait_selection/src/traits/select/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
291291
self.infcx.tcx
292292
}
293293

294+
pub(super) fn query_mode(&self) -> TraitQueryMode {
295+
self.query_mode
296+
}
297+
294298
///////////////////////////////////////////////////////////////////////////
295299
// Selection
296300
//

library/alloc/src/rc.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1749,7 +1749,7 @@ struct WeakInner<'a> {
17491749
strong: &'a Cell<usize>,
17501750
}
17511751

1752-
impl<T: ?Sized> Weak<T> {
1752+
impl<T> Weak<T> {
17531753
/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
17541754
///
17551755
/// The pointer is valid only if there are some strong references. The pointer may be dangling,
@@ -1882,7 +1882,9 @@ impl<T: ?Sized> Weak<T> {
18821882
// SAFETY: we now have recovered the original Weak pointer, so can create the Weak.
18831883
Weak { ptr: unsafe { NonNull::new_unchecked(ptr) } }
18841884
}
1885+
}
18851886

1887+
impl<T: ?Sized> Weak<T> {
18861888
/// Attempts to upgrade the `Weak` pointer to an [`Rc`], delaying
18871889
/// dropping of the inner value if successful.
18881890
///

library/alloc/src/rc/tests.rs

-24
Original file line numberDiff line numberDiff line change
@@ -208,30 +208,6 @@ fn into_from_weak_raw() {
208208
}
209209
}
210210

211-
#[test]
212-
fn test_into_from_weak_raw_unsized() {
213-
use std::fmt::Display;
214-
use std::string::ToString;
215-
216-
let arc: Rc<str> = Rc::from("foo");
217-
let weak: Weak<str> = Rc::downgrade(&arc);
218-
219-
let ptr = Weak::into_raw(weak.clone());
220-
let weak2 = unsafe { Weak::from_raw(ptr) };
221-
222-
assert_eq!(unsafe { &*ptr }, "foo");
223-
assert!(weak.ptr_eq(&weak2));
224-
225-
let arc: Rc<dyn Display> = Rc::new(123);
226-
let weak: Weak<dyn Display> = Rc::downgrade(&arc);
227-
228-
let ptr = Weak::into_raw(weak.clone());
229-
let weak2 = unsafe { Weak::from_raw(ptr) };
230-
231-
assert_eq!(unsafe { &*ptr }.to_string(), "123");
232-
assert!(weak.ptr_eq(&weak2));
233-
}
234-
235211
#[test]
236212
fn get_mut() {
237213
let mut x = Rc::new(3);

library/alloc/src/sync.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1535,7 +1535,7 @@ struct WeakInner<'a> {
15351535
strong: &'a atomic::AtomicUsize,
15361536
}
15371537

1538-
impl<T: ?Sized> Weak<T> {
1538+
impl<T> Weak<T> {
15391539
/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
15401540
///
15411541
/// The pointer is valid only if there are some strong references. The pointer may be dangling,
@@ -1668,7 +1668,9 @@ impl<T: ?Sized> Weak<T> {
16681668
// SAFETY: we now have recovered the original Weak pointer, so can create the Weak.
16691669
unsafe { Weak { ptr: NonNull::new_unchecked(ptr) } }
16701670
}
1671+
}
16711672

1673+
impl<T: ?Sized> Weak<T> {
16721674
/// Attempts to upgrade the `Weak` pointer to an [`Arc`], delaying
16731675
/// dropping of the inner value if successful.
16741676
///

library/alloc/src/sync/tests.rs

-24
Original file line numberDiff line numberDiff line change
@@ -158,30 +158,6 @@ fn into_from_weak_raw() {
158158
}
159159
}
160160

161-
#[test]
162-
fn test_into_from_weak_raw_unsized() {
163-
use std::fmt::Display;
164-
use std::string::ToString;
165-
166-
let arc: Arc<str> = Arc::from("foo");
167-
let weak: Weak<str> = Arc::downgrade(&arc);
168-
169-
let ptr = Weak::into_raw(weak.clone());
170-
let weak2 = unsafe { Weak::from_raw(ptr) };
171-
172-
assert_eq!(unsafe { &*ptr }, "foo");
173-
assert!(weak.ptr_eq(&weak2));
174-
175-
let arc: Arc<dyn Display> = Arc::new(123);
176-
let weak: Weak<dyn Display> = Arc::downgrade(&arc);
177-
178-
let ptr = Weak::into_raw(weak.clone());
179-
let weak2 = unsafe { Weak::from_raw(ptr) };
180-
181-
assert_eq!(unsafe { &*ptr }.to_string(), "123");
182-
assert!(weak.ptr_eq(&weak2));
183-
}
184-
185161
#[test]
186162
fn test_cowarc_clone_make_mut() {
187163
let mut cow0 = Arc::new(75);

src/bootstrap/tarball.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,16 @@ impl<'a> Tarball<'a> {
241241
}
242242

243243
pub(crate) fn bare(self) -> PathBuf {
244+
// Bare tarballs should have the top level directory match the package
245+
// name, not "image". We rename the image directory just before passing
246+
// into rust-installer.
247+
let dest = self.temp_dir.join(self.package_name());
248+
t!(std::fs::rename(&self.image_dir, &dest));
249+
244250
self.run(|this, cmd| {
245251
cmd.arg("tarball")
246252
.arg("--input")
247-
.arg(&this.image_dir)
253+
.arg(&dest)
248254
.arg("--output")
249255
.arg(crate::dist::distdir(this.builder).join(this.package_name()));
250256
})

src/stage0.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# stable release's version number. `date` is the date where the release we're
1313
# bootstrapping off was released.
1414

15-
date: 2020-12-29
15+
date: 2020-12-31
1616
rustc: 1.49.0
1717

1818
# We use a nightly rustfmt to format the source because it solves some
@@ -39,4 +39,4 @@ rustc: 1.49.0
3939
# looking at a beta source tarball and it's uncommented we'll shortly comment it
4040
# out.
4141

42-
dev: 1
42+
#dev: 1

src/test/ui/associated-types/defaults-cyclic-fail-1.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ impl Tr for u32 {
2424
// ...but not in an impl that redefines one of the types.
2525
impl Tr for bool {
2626
type A = Box<Self::B>;
27-
//~^ ERROR type mismatch resolving `<bool as Tr>::B == _`
27+
//~^ ERROR overflow evaluating the requirement `<bool as Tr>::B == _`
2828
}
2929
// (the error is shown twice for some reason)
3030

3131
impl Tr for usize {
3232
type B = &'static Self::A;
33-
//~^ ERROR type mismatch resolving `<usize as Tr>::A == _`
33+
//~^ ERROR overflow evaluating the requirement `<usize as Tr>::A == _`
3434
}
3535

3636
fn main() {
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
error[E0271]: type mismatch resolving `<bool as Tr>::B == _`
1+
error[E0275]: overflow evaluating the requirement `<bool as Tr>::B == _`
22
--> $DIR/defaults-cyclic-fail-1.rs:26:5
33
|
44
LL | type A = Box<Self::B>;
5-
| ^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
5+
| ^^^^^^^^^^^^^^^^^^^^^^
66

7-
error[E0271]: type mismatch resolving `<usize as Tr>::A == _`
7+
error[E0275]: overflow evaluating the requirement `<usize as Tr>::A == _`
88
--> $DIR/defaults-cyclic-fail-1.rs:32:5
99
|
1010
LL | type B = &'static Self::A;
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
1212

1313
error: aborting due to 2 previous errors
1414

15-
For more information about this error, try `rustc --explain E0271`.
15+
For more information about this error, try `rustc --explain E0275`.

src/test/ui/associated-types/defaults-cyclic-fail-2.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ impl Tr for u32 {
2525

2626
impl Tr for bool {
2727
type A = Box<Self::B>;
28-
//~^ ERROR type mismatch resolving `<bool as Tr>::B == _`
28+
//~^ ERROR overflow evaluating the requirement `<bool as Tr>::B == _`
2929
}
3030
// (the error is shown twice for some reason)
3131

3232
impl Tr for usize {
3333
type B = &'static Self::A;
34-
//~^ ERROR type mismatch resolving `<usize as Tr>::A == _`
34+
//~^ ERROR overflow evaluating the requirement `<usize as Tr>::A == _`
3535
}
3636

3737
fn main() {
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
error[E0271]: type mismatch resolving `<bool as Tr>::B == _`
1+
error[E0275]: overflow evaluating the requirement `<bool as Tr>::B == _`
22
--> $DIR/defaults-cyclic-fail-2.rs:27:5
33
|
44
LL | type A = Box<Self::B>;
5-
| ^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
5+
| ^^^^^^^^^^^^^^^^^^^^^^
66

7-
error[E0271]: type mismatch resolving `<usize as Tr>::A == _`
7+
error[E0275]: overflow evaluating the requirement `<usize as Tr>::A == _`
88
--> $DIR/defaults-cyclic-fail-2.rs:33:5
99
|
1010
LL | type B = &'static Self::A;
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
1212

1313
error: aborting due to 2 previous errors
1414

15-
For more information about this error, try `rustc --explain E0271`.
15+
For more information about this error, try `rustc --explain E0275`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Regression test for #79714
2+
3+
trait Baz {}
4+
impl Baz for () {}
5+
impl<T> Baz for (T,) {}
6+
7+
trait Fiz {}
8+
impl Fiz for bool {}
9+
10+
trait Grault {
11+
type A;
12+
type B;
13+
}
14+
15+
impl<T: Grault> Grault for (T,)
16+
where
17+
Self::A: Baz,
18+
Self::B: Fiz,
19+
{
20+
type A = ();
21+
//~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
22+
type B = bool;
23+
//~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
24+
}
25+
//~^^^^^^^^^^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
26+
27+
fn main() {
28+
let x: <(_,) as Grault>::A = ();
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
2+
--> $DIR/impl-wf-cycle-1.rs:15:1
3+
|
4+
LL | / impl<T: Grault> Grault for (T,)
5+
LL | | where
6+
LL | | Self::A: Baz,
7+
LL | | Self::B: Fiz,
8+
... |
9+
LL | |
10+
LL | | }
11+
| |_^
12+
|
13+
= note: required because of the requirements on the impl of `Grault` for `(T,)`
14+
= note: 1 redundant requirements hidden
15+
= note: required because of the requirements on the impl of `Grault` for `(T,)`
16+
17+
error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
18+
--> $DIR/impl-wf-cycle-1.rs:20:5
19+
|
20+
LL | type A = ();
21+
| ^^^^^^^^^^^^
22+
|
23+
= note: required because of the requirements on the impl of `Grault` for `(T,)`
24+
= note: 1 redundant requirements hidden
25+
= note: required because of the requirements on the impl of `Grault` for `(T,)`
26+
27+
error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
28+
--> $DIR/impl-wf-cycle-1.rs:22:5
29+
|
30+
LL | type B = bool;
31+
| ^^^^^^^^^^^^^^
32+
|
33+
= note: required because of the requirements on the impl of `Grault` for `(T,)`
34+
= note: 1 redundant requirements hidden
35+
= note: required because of the requirements on the impl of `Grault` for `(T,)`
36+
37+
error: aborting due to 3 previous errors
38+
39+
For more information about this error, try `rustc --explain E0275`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Regression test for #79714
2+
3+
trait Grault {
4+
type A;
5+
}
6+
7+
impl<T: Grault> Grault for (T,)
8+
where
9+
Self::A: Copy,
10+
{
11+
type A = ();
12+
//~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
13+
}
14+
//~^^^^^^^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
15+
16+
fn main() {}

0 commit comments

Comments
 (0)