Skip to content

Commit 72d6606

Browse files
committed
Auto merge of #89903 - matthiaskrgr:rollup-s0c69xl, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #86011 (move implicit `Sized` predicate to end of list) - #89821 (Add a strange test for `unsafe_code` lint.) - #89859 (add dedicated error variant for writing the discriminant of an uninhabited enum variant) - #89870 (Suggest Box::pin when Pin::new is used instead) - #89880 (Use non-checking TLS relocation in aarch64 asm! sym test.) - #89885 (add long explanation for E0183) - #89894 (Remove unused dependencies from rustc_const_eval) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 313e71a + e45c222 commit 72d6606

35 files changed

+236
-114
lines changed

Cargo.lock

-2
Original file line numberDiff line numberDiff line change
@@ -3736,8 +3736,6 @@ dependencies = [
37363736
name = "rustc_const_eval"
37373737
version = "0.0.0"
37383738
dependencies = [
3739-
"either",
3740-
"gsgdt",
37413739
"rustc_apfloat",
37423740
"rustc_ast",
37433741
"rustc_attr",

compiler/rustc_const_eval/Cargo.toml

-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ edition = "2021"
77
doctest = false
88

99
[dependencies]
10-
either = "1.5.0"
11-
gsgdt = "0.1.2"
1210
tracing = "0.1"
1311
rustc_apfloat = { path = "../rustc_apfloat" }
1412
rustc_ast = { path = "../rustc_ast" }

compiler/rustc_const_eval/src/interpret/operand.rs

+1
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
618618
}
619619

620620
/// Read discriminant, return the runtime value as well as the variant index.
621+
/// Can also legally be called on non-enums (e.g. through the discriminant_value intrinsic)!
621622
pub fn read_discriminant(
622623
&self,
623624
op: &OpTy<'tcx, M::PointerTag>,

compiler/rustc_const_eval/src/interpret/place.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -988,10 +988,23 @@ where
988988
variant_index: VariantIdx,
989989
dest: &PlaceTy<'tcx, M::PointerTag>,
990990
) -> InterpResult<'tcx> {
991+
// This must be an enum or generator.
992+
match dest.layout.ty.kind() {
993+
ty::Adt(adt, _) => assert!(adt.is_enum()),
994+
ty::Generator(..) => {}
995+
_ => span_bug!(
996+
self.cur_span(),
997+
"write_discriminant called on non-variant-type (neither enum nor generator)"
998+
),
999+
}
9911000
// Layout computation excludes uninhabited variants from consideration
9921001
// therefore there's no way to represent those variants in the given layout.
1002+
// Essentially, uninhabited variants do not have a tag that corresponds to their
1003+
// discriminant, so we cannot do anything here.
1004+
// When evaluating we will always error before even getting here, but ConstProp 'executes'
1005+
// dead code, so we cannot ICE here.
9931006
if dest.layout.for_variant(self, variant_index).abi.is_uninhabited() {
994-
throw_ub!(Unreachable);
1007+
throw_ub!(UninhabitedEnumVariantWritten)
9951008
}
9961009

9971010
match dest.layout.variants {

compiler/rustc_error_codes/src/error_codes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ E0164: include_str!("./error_codes/E0164.md"),
9292
E0165: include_str!("./error_codes/E0165.md"),
9393
E0170: include_str!("./error_codes/E0170.md"),
9494
E0178: include_str!("./error_codes/E0178.md"),
95+
E0183: include_str!("./error_codes/E0183.md"),
9596
E0184: include_str!("./error_codes/E0184.md"),
9697
E0185: include_str!("./error_codes/E0185.md"),
9798
E0186: include_str!("./error_codes/E0186.md"),
@@ -513,7 +514,6 @@ E0785: include_str!("./error_codes/E0785.md"),
513514
// E0173, // manual implementations of unboxed closure traits are experimental
514515
// E0174,
515516
// E0182, // merged into E0229
516-
E0183,
517517
// E0187, // cannot infer the kind of the closure
518518
// E0188, // can not cast an immutable reference to a mutable pointer
519519
// E0189, // deprecated: can only cast a boxed pointer to a boxed object
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
Manual implemetation of a `Fn*` trait.
2+
3+
Erroneous code example:
4+
5+
```compile_fail,E0183
6+
struct MyClosure {
7+
foo: i32
8+
}
9+
10+
impl FnOnce<()> for MyClosure { // error
11+
type Output = ();
12+
extern "rust-call" fn call_once(self, args: ()) -> Self::Output {
13+
println!("{}", self.foo);
14+
}
15+
}
16+
```
17+
18+
Manually implementing `Fn`, `FnMut` or `FnOnce` is unstable
19+
and requires `#![feature(fn_traits, unboxed_closures)]`.
20+
21+
```
22+
#![feature(fn_traits, unboxed_closures)]
23+
24+
struct MyClosure {
25+
foo: i32
26+
}
27+
28+
impl FnOnce<()> for MyClosure { // ok!
29+
type Output = ();
30+
extern "rust-call" fn call_once(self, args: ()) -> Self::Output {
31+
println!("{}", self.foo);
32+
}
33+
}
34+
```
35+
36+
The argumements must be a tuple representing the argument list.
37+
For more info, see the [tracking issue][iss29625]:
38+
39+
[iss29625]: https://github.com/rust-lang/rust/issues/29625

compiler/rustc_middle/src/mir/interpret/error.rs

+5
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,8 @@ pub enum UndefinedBehaviorInfo<'tcx> {
287287
target_size: u64,
288288
data_size: u64,
289289
},
290+
/// A discriminant of an uninhabited enum variant is written.
291+
UninhabitedEnumVariantWritten,
290292
}
291293

292294
impl fmt::Display for UndefinedBehaviorInfo<'_> {
@@ -391,6 +393,9 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> {
391393
"scalar size mismatch: expected {} bytes but got {} bytes instead",
392394
target_size, data_size
393395
),
396+
UninhabitedEnumVariantWritten => {
397+
write!(f, "writing discriminant of an uninhabited enum")
398+
}
394399
}
395400
}
396401
}

compiler/rustc_typeck/src/bounds.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,16 @@ impl<'tcx> Bounds<'tcx> {
6464
})
6565
});
6666

67-
sized_predicate
68-
.into_iter()
69-
.chain(self.region_bounds.iter().map(|&(region_bound, span)| {
67+
self.region_bounds
68+
.iter()
69+
.map(|&(region_bound, span)| {
7070
(
7171
region_bound
7272
.map_bound(|region_bound| ty::OutlivesPredicate(param_ty, region_bound))
7373
.to_predicate(tcx),
7474
span,
7575
)
76-
}))
76+
})
7777
.chain(self.trait_bounds.iter().map(|&(bound_trait_ref, span, constness)| {
7878
let predicate = bound_trait_ref.with_constness(constness).to_predicate(tcx);
7979
(predicate, span)
@@ -83,6 +83,7 @@ impl<'tcx> Bounds<'tcx> {
8383
.iter()
8484
.map(|&(projection, span)| (projection.to_predicate(tcx), span)),
8585
)
86+
.chain(sized_predicate.into_iter())
8687
.collect()
8788
}
8889
}

compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs

+60-30
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
88
use rustc_hir as hir;
99
use rustc_hir::def::{CtorOf, DefKind};
1010
use rustc_hir::lang_items::LangItem;
11-
use rustc_hir::{Expr, ExprKind, ItemKind, Node, Stmt, StmtKind};
11+
use rustc_hir::{Expr, ExprKind, ItemKind, Node, Path, QPath, Stmt, StmtKind, TyKind};
1212
use rustc_infer::infer;
1313
use rustc_middle::lint::in_external_macro;
1414
use rustc_middle::ty::{self, Binder, Ty};
15-
use rustc_span::symbol::kw;
15+
use rustc_span::symbol::{kw, sym};
1616

1717
use std::iter;
1818

@@ -350,6 +350,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
350350
}
351351

352352
/// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
353+
#[instrument(skip(self, err))]
353354
pub(in super::super) fn suggest_calling_boxed_future_when_appropriate(
354355
&self,
355356
err: &mut DiagnosticBuilder<'_>,
@@ -368,41 +369,70 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
368369
if pin_did.is_none() || self.tcx.lang_items().owned_box().is_none() {
369370
return false;
370371
}
371-
match expected.kind() {
372-
ty::Adt(def, _) if Some(def.did) == pin_did => (),
373-
_ => return false,
374-
}
375372
let box_found = self.tcx.mk_box(found);
376373
let pin_box_found = self.tcx.mk_lang_item(box_found, LangItem::Pin).unwrap();
377374
let pin_found = self.tcx.mk_lang_item(found, LangItem::Pin).unwrap();
378-
if self.can_coerce(pin_box_found, expected) {
379-
debug!("can coerce {:?} to {:?}, suggesting Box::pin", pin_box_found, expected);
380-
match found.kind() {
381-
ty::Adt(def, _) if def.is_box() => {
382-
err.help("use `Box::pin`");
383-
}
384-
_ => {
385-
err.multipart_suggestion(
386-
"you need to pin and box this expression",
387-
vec![
388-
(expr.span.shrink_to_lo(), "Box::pin(".to_string()),
389-
(expr.span.shrink_to_hi(), ")".to_string()),
390-
],
391-
Applicability::MaybeIncorrect,
392-
);
375+
match expected.kind() {
376+
ty::Adt(def, _) if Some(def.did) == pin_did => {
377+
if self.can_coerce(pin_box_found, expected) {
378+
debug!("can coerce {:?} to {:?}, suggesting Box::pin", pin_box_found, expected);
379+
match found.kind() {
380+
ty::Adt(def, _) if def.is_box() => {
381+
err.help("use `Box::pin`");
382+
}
383+
_ => {
384+
err.multipart_suggestion(
385+
"you need to pin and box this expression",
386+
vec![
387+
(expr.span.shrink_to_lo(), "Box::pin(".to_string()),
388+
(expr.span.shrink_to_hi(), ")".to_string()),
389+
],
390+
Applicability::MaybeIncorrect,
391+
);
392+
}
393+
}
394+
true
395+
} else if self.can_coerce(pin_found, expected) {
396+
match found.kind() {
397+
ty::Adt(def, _) if def.is_box() => {
398+
err.help("use `Box::pin`");
399+
true
400+
}
401+
_ => false,
402+
}
403+
} else {
404+
false
393405
}
394406
}
395-
true
396-
} else if self.can_coerce(pin_found, expected) {
397-
match found.kind() {
398-
ty::Adt(def, _) if def.is_box() => {
399-
err.help("use `Box::pin`");
400-
true
407+
ty::Adt(def, _) if def.is_box() && self.can_coerce(box_found, expected) => {
408+
// Check if the parent expression is a call to Pin::new. If it
409+
// is and we were expecting a Box, ergo Pin<Box<expected>>, we
410+
// can suggest Box::pin.
411+
let parent = self.tcx.hir().get_parent_node(expr.hir_id);
412+
let fn_name = match self.tcx.hir().find(parent) {
413+
Some(Node::Expr(Expr { kind: ExprKind::Call(fn_name, _), .. })) => fn_name,
414+
_ => return false,
415+
};
416+
match fn_name.kind {
417+
ExprKind::Path(QPath::TypeRelative(
418+
hir::Ty {
419+
kind: TyKind::Path(QPath::Resolved(_, Path { res: recv_ty, .. })),
420+
..
421+
},
422+
method,
423+
)) if Some(recv_ty.def_id()) == pin_did && method.ident.name == sym::new => {
424+
err.span_suggestion(
425+
fn_name.span,
426+
"use `Box::pin` to pin and box this expression",
427+
"Box::pin".to_string(),
428+
Applicability::MachineApplicable,
429+
);
430+
true
431+
}
432+
_ => false,
401433
}
402-
_ => false,
403434
}
404-
} else {
405-
false
435+
_ => false,
406436
}
407437
}
408438

src/test/ui/asm/aarch64/sym.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ macro_rules! static_tls_addr {
5555
// Add the top 12 bits of the symbol's offset
5656
"add {out}, {out}, :tprel_hi12:{sym}",
5757
// And the bottom 12 bits
58-
"add {out}, {out}, :tprel_lo12:{sym}",
58+
"add {out}, {out}, :tprel_lo12_nc:{sym}",
5959
out = out(reg) result,
6060
sym = sym $s
6161
);

src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ note: required by a bound in `std::hash::Hash::hash`
1111
--> $SRC_DIR/core/src/hash/mod.rs:LL:COL
1212
|
1313
LL | fn hash<H: Hasher>(&self, state: &mut H);
14-
| ^ required by this bound in `std::hash::Hash::hash`
14+
| ^^^^^^ required by this bound in `std::hash::Hash::hash`
1515
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
1616

1717
error: aborting due to previous error

src/test/ui/derives/derives-span-Hash-enum.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ note: required by a bound in `std::hash::Hash::hash`
1111
--> $SRC_DIR/core/src/hash/mod.rs:LL:COL
1212
|
1313
LL | fn hash<H: Hasher>(&self, state: &mut H);
14-
| ^ required by this bound in `std::hash::Hash::hash`
14+
| ^^^^^^ required by this bound in `std::hash::Hash::hash`
1515
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
1616

1717
error: aborting due to previous error

src/test/ui/derives/derives-span-Hash-struct.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ note: required by a bound in `std::hash::Hash::hash`
1111
--> $SRC_DIR/core/src/hash/mod.rs:LL:COL
1212
|
1313
LL | fn hash<H: Hasher>(&self, state: &mut H);
14-
| ^ required by this bound in `std::hash::Hash::hash`
14+
| ^^^^^^ required by this bound in `std::hash::Hash::hash`
1515
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
1616

1717
error: aborting due to previous error

src/test/ui/derives/derives-span-Hash-tuple-struct.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ note: required by a bound in `std::hash::Hash::hash`
1111
--> $SRC_DIR/core/src/hash/mod.rs:LL:COL
1212
|
1313
LL | fn hash<H: Hasher>(&self, state: &mut H);
14-
| ^ required by this bound in `std::hash::Hash::hash`
14+
| ^^^^^^ required by this bound in `std::hash::Hash::hash`
1515
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
1616

1717
error: aborting due to previous error

src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -101,5 +101,5 @@ LL | impl FnOnce<()> for Baz {
101101

102102
error: aborting due to 12 previous errors
103103

104-
Some errors have detailed explanations: E0229, E0658.
105-
For more information about an error, try `rustc --explain E0229`.
104+
Some errors have detailed explanations: E0183, E0229, E0658.
105+
For more information about an error, try `rustc --explain E0183`.

src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@ LL | impl FnOnce<(u32, u32)> for Test {
2626

2727
error: aborting due to 3 previous errors
2828

29-
For more information about this error, try `rustc --explain E0658`.
29+
Some errors have detailed explanations: E0183, E0658.
30+
For more information about an error, try `rustc --explain E0183`.

src/test/ui/generic-associated-types/issue-74816.stderr

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,34 @@
1-
error[E0277]: the trait bound `Self: Trait1` is not satisfied
1+
error[E0277]: the size for values of type `Self` cannot be known at compilation time
22
--> $DIR/issue-74816.rs:9:5
33
|
44
LL | type Associated: Trait1 = Self;
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait1` is not implemented for `Self`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
66
|
77
note: required by a bound in `Trait2::Associated`
8-
--> $DIR/issue-74816.rs:9:22
8+
--> $DIR/issue-74816.rs:9:5
99
|
1010
LL | type Associated: Trait1 = Self;
11-
| ^^^^^^ required by this bound in `Trait2::Associated`
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait2::Associated`
1212
help: consider further restricting `Self`
1313
|
14-
LL | trait Trait2: Trait1 {
15-
| ++++++++
14+
LL | trait Trait2: Sized {
15+
| +++++++
1616

17-
error[E0277]: the size for values of type `Self` cannot be known at compilation time
17+
error[E0277]: the trait bound `Self: Trait1` is not satisfied
1818
--> $DIR/issue-74816.rs:9:5
1919
|
2020
LL | type Associated: Trait1 = Self;
21-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait1` is not implemented for `Self`
2222
|
2323
note: required by a bound in `Trait2::Associated`
24-
--> $DIR/issue-74816.rs:9:5
24+
--> $DIR/issue-74816.rs:9:22
2525
|
2626
LL | type Associated: Trait1 = Self;
27-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait2::Associated`
27+
| ^^^^^^ required by this bound in `Trait2::Associated`
2828
help: consider further restricting `Self`
2929
|
30-
LL | trait Trait2: Sized {
31-
| +++++++
30+
LL | trait Trait2: Trait1 {
31+
| ++++++++
3232

3333
error: aborting due to 2 previous errors
3434

src/test/ui/generic-associated-types/issue-86483.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ LL | for<'a> T: 'a,
2020
| ^^
2121

2222
error[E0311]: the parameter type `T` may not live long enough
23-
--> $DIR/issue-86483.rs:9:5
23+
--> $DIR/issue-86483.rs:9:19
2424
|
2525
LL | pub trait IceIce<T>
2626
| - help: consider adding an explicit lifetime bound...: `T: 'a`
2727
...
2828
LL | type Ice<'v>: IntoIterator<Item = &'v T>;
29-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
29+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
3030
|
3131
note: ...that is required by this bound
3232
--> $DIR/issue-86483.rs:7:16

0 commit comments

Comments
 (0)