Skip to content

Commit 1a8d094

Browse files
committed
Auto merge of rust-lang#113782 - matthiaskrgr:rollup-mmrjvx3, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - rust-lang#112741 (fix typo in `rustdoc/src/what-is-rustdoc.md`) - rust-lang#113535 (Add a sparc-unknown-none-elf target.) - rust-lang#113651 (self type param infer, avoid ICE) - rust-lang#113770 (Generate safe stable code for derives on empty enums) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 6f65ef5 + 93b9812 commit 1a8d094

File tree

16 files changed

+246
-27
lines changed

16 files changed

+246
-27
lines changed

compiler/rustc_builtin_macros/src/deriving/generic/mod.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -1134,20 +1134,30 @@ impl<'a> MethodDef<'a> {
11341134
trait_: &TraitDef<'b>,
11351135
enum_def: &'b EnumDef,
11361136
type_ident: Ident,
1137-
selflike_args: ThinVec<P<Expr>>,
1137+
mut selflike_args: ThinVec<P<Expr>>,
11381138
nonselflike_args: &[P<Expr>],
11391139
) -> BlockOrExpr {
1140+
assert!(
1141+
!selflike_args.is_empty(),
1142+
"static methods must use `expand_static_enum_method_body`",
1143+
);
1144+
11401145
let span = trait_.span;
11411146
let variants = &enum_def.variants;
11421147

11431148
// Traits that unify fieldless variants always use the tag(s).
11441149
let unify_fieldless_variants =
11451150
self.fieldless_variants_strategy == FieldlessVariantsStrategy::Unify;
11461151

1147-
// There is no sensible code to be generated for *any* deriving on a
1148-
// zero-variant enum. So we just generate a failing expression.
1152+
// For zero-variant enum, this function body is unreachable. Generate
1153+
// `match *self {}`. This produces machine code identical to `unsafe {
1154+
// core::intrinsics::unreachable() }` while being safe and stable.
11491155
if variants.is_empty() {
1150-
return BlockOrExpr(ThinVec::new(), Some(deriving::call_unreachable(cx, span)));
1156+
selflike_args.truncate(1);
1157+
let match_arg = cx.expr_deref(span, selflike_args.pop().unwrap());
1158+
let match_arms = ThinVec::new();
1159+
let expr = cx.expr_match(span, match_arg, match_arms);
1160+
return BlockOrExpr(ThinVec::new(), Some(expr));
11511161
}
11521162

11531163
let prefixes = iter::once("__self".to_string())

compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::FnCtxt;
22
use rustc_hir as hir;
33
use rustc_hir::def::Res;
44
use rustc_hir::def_id::DefId;
5-
use rustc_infer::traits::ObligationCauseCode;
5+
use rustc_infer::{infer::type_variable::TypeVariableOriginKind, traits::ObligationCauseCode};
66
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
77
use rustc_span::{self, symbol::kw, Span};
88
use rustc_trait_selection::traits;
@@ -267,8 +267,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
267267
type BreakTy = ty::GenericArg<'tcx>;
268268
fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow<Self::BreakTy> {
269269
if let Some(origin) = self.0.type_var_origin(ty)
270-
&& let rustc_infer::infer::type_variable::TypeVariableOriginKind::TypeParameterDefinition(_, def_id) =
271-
origin.kind
270+
&& let TypeVariableOriginKind::TypeParameterDefinition(_, def_id) = origin.kind
272271
&& let generics = self.0.tcx.generics_of(self.1)
273272
&& let Some(index) = generics.param_def_id_to_index(self.0.tcx, def_id)
274273
&& let Some(subst) = ty::GenericArgs::identity_for_item(self.0.tcx, self.1)

compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinte
163163
let ty_vars = infcx_inner.type_variables();
164164
let var_origin = ty_vars.var_origin(ty_vid);
165165
if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) = var_origin.kind
166-
&& !var_origin.span.from_expansion()
166+
&& name != kw::SelfUpper && !var_origin.span.from_expansion()
167167
{
168168
let generics = infcx.tcx.generics_of(infcx.tcx.parent(def_id));
169169
let idx = generics.param_def_id_to_index(infcx.tcx, def_id).unwrap();

compiler/rustc_target/src/spec/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1433,6 +1433,8 @@ supported_targets! {
14331433
("riscv64gc-unknown-linux-gnu", riscv64gc_unknown_linux_gnu),
14341434
("riscv64gc-unknown-linux-musl", riscv64gc_unknown_linux_musl),
14351435

1436+
("sparc-unknown-none-elf", sparc_unknown_none_elf),
1437+
14361438
("loongarch64-unknown-none", loongarch64_unknown_none),
14371439
("loongarch64-unknown-none-softfloat", loongarch64_unknown_none_softfloat),
14381440

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use crate::abi::Endian;
2+
use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
3+
4+
pub fn target() -> Target {
5+
let options = TargetOptions {
6+
linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No),
7+
linker: Some("sparc-elf-gcc".into()),
8+
endian: Endian::Big,
9+
cpu: "v7".into(),
10+
abi: "elf".into(),
11+
max_atomic_width: Some(32),
12+
atomic_cas: true,
13+
panic_strategy: PanicStrategy::Abort,
14+
relocation_model: RelocModel::Static,
15+
no_default_libraries: false,
16+
emit_debug_gdb_scripts: false,
17+
eh_frame_header: false,
18+
..Default::default()
19+
};
20+
Target {
21+
data_layout: "E-m:e-p:32:32-i64:64-f128:64-n32-S64".into(),
22+
llvm_target: "sparc-unknown-none-elf".into(),
23+
pointer_width: 32,
24+
arch: "sparc".into(),
25+
options,
26+
}
27+
}

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

+4-7
Original file line numberDiff line numberDiff line change
@@ -2388,14 +2388,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
23882388
// If there is only one implementation of the trait, suggest using it.
23892389
// Otherwise, use a placeholder comment for the implementation.
23902390
let (message, impl_suggestion) = if non_blanket_impl_count == 1 {(
2391-
"use the fully-qualified path to the only available implementation".to_string(),
2391+
"use the fully-qualified path to the only available implementation",
23922392
format!("<{} as ", self.tcx.type_of(impl_def_id).instantiate_identity())
2393-
)} else {(
2394-
format!(
2395-
"use a fully-qualified path to a specific available implementation ({} found)",
2396-
non_blanket_impl_count
2397-
),
2398-
"</* self type */ as ".to_string()
2393+
)} else {
2394+
("use a fully-qualified path to a specific available implementation",
2395+
"</* self type */ as ".to_string()
23992396
)};
24002397
let mut suggestions = vec![(
24012398
path.span.shrink_to_lo(),

src/doc/rustc/src/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
- [mipsisa\*r6\*-unknown-linux-gnu\*](platform-support/mips-release-6.md)
4040
- [nvptx64-nvidia-cuda](platform-support/nvptx64-nvidia-cuda.md)
4141
- [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md)
42+
- [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md)
4243
- [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md)
4344
- [\*-nto-qnx-\*](platform-support/nto-qnx.md)
4445
- [\*-unknown-netbsd\*](platform-support/netbsd.md)

src/doc/rustc/src/platform-support.md

+1
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ target | std | notes
176176
`thumbv8m.base-none-eabi` | * | Bare ARMv8-M Baseline
177177
`thumbv8m.main-none-eabi` | * | Bare ARMv8-M Mainline
178178
`thumbv8m.main-none-eabihf` | * | Bare ARMv8-M Mainline, hardfloat
179+
[`sparc-unknown-none-elf`](./platform-support/sparc-unknown-none-elf.md) | * | Bare 32-bit SPARC V7+
179180
`wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten
180181
`wasm32-unknown-unknown` | ✓ | WebAssembly
181182
`wasm32-wasi` | ✓ | WebAssembly with WASI
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
# `sparc-unknown-none-elf`
2+
3+
**Tier: 3**
4+
5+
Rust for bare-metal 32-bit SPARC V7 and V8 systems, e.g. the Gaisler LEON3.
6+
7+
| Target | Descriptions |
8+
| ---------------------- | ----------------------------------------- |
9+
| sparc-unknown-none-elf | SPARC V7 32-bit (freestanding, hardfloat) |
10+
11+
## Target maintainers
12+
13+
- Jonathan Pallant, <[email protected]>, https://ferrous-systems.com
14+
15+
## Requirements
16+
17+
This target is cross-compiled. There is no support for `std`. There is no
18+
default allocator, but it's possible to use `alloc` by supplying an allocator.
19+
20+
This allows the generated code to run in environments, such as kernels, which
21+
may need to avoid the use of such registers or which may have special
22+
considerations about the use of such registers (e.g. saving and restoring them
23+
to avoid breaking userspace code using the same registers). You can change code
24+
generation to use additional CPU features via the `-C target-feature=` codegen
25+
options to rustc, or via the `#[target_feature]` mechanism within Rust code.
26+
27+
By default, code generated with this target should run on any `SPARC` hardware;
28+
enabling additional target features may raise this baseline.
29+
30+
- `-Ctarget-cpu=v8` adds the extra SPARC V8 instructions.
31+
32+
- `-Ctarget-cpu=leon3` adds the SPARC V8 instructions and sets up scheduling to
33+
suit the Gaisler Leon3.
34+
35+
Functions marked `extern "C"` use the [standard SPARC architecture calling
36+
convention](https://sparc.org/technical-documents/).
37+
38+
This target generates ELF binaries. Any alternate formats or special
39+
considerations for binary layout will require linker options or linker scripts.
40+
41+
## Building the target
42+
43+
You can build Rust with support for the target by adding it to the `target`
44+
list in `config.toml`:
45+
46+
```toml
47+
[build]
48+
build-stage = 1
49+
target = ["sparc-unknown-none-elf"]
50+
```
51+
52+
## Building Rust programs
53+
54+
```text
55+
cargo build --target sparc-unknown-none-elf
56+
```
57+
58+
This target uses GCC as a linker, and so you will need an appropriate GCC
59+
compatible `sparc-unknown-none` toolchain.
60+
61+
The default linker name is `sparc-elf-gcc`, but you can override this in your
62+
project configuration.
63+
64+
## Testing
65+
66+
As `sparc-unknown-none-elf` supports a variety of different environments and does
67+
not support `std`, this target does not support running the Rust test suite.
68+
69+
## Cross-compilation toolchains and C code
70+
71+
This target was initially tested using [BCC2] from Gaisler, along with the TSIM
72+
Leon3 processor simulator. Both [BCC2] GCC and [BCC2] Clang have been shown to
73+
work. To work with these tools, your project configuration should contain
74+
something like:
75+
76+
[BCC2]: https://www.gaisler.com/index.php/downloads/compilers
77+
78+
`.cargo/config.toml`:
79+
```toml
80+
[target.sparc-unknown-none-elf]
81+
linker = "sparc-gaisler-elf-gcc"
82+
runner = "tsim-leon3"
83+
84+
[build]
85+
target = ["sparc-unknown-none-elf"]
86+
rustflags = "-Ctarget-cpu=leon3"
87+
88+
[unstable]
89+
build-std = ["core"]
90+
```
91+
92+
With this configuration, running `cargo run` will compile your code for the
93+
SPARC V8 compatible Gaisler Leon3 processor and then start the `tsim-leon3`
94+
simulator. Once the simulator is running, simply enter the command
95+
`run` to start the code executing in the simulator.
96+
97+
The default C toolchain libraries are linked in, so with the Gaisler [BCC2]
98+
toolchain, and using its default Leon3 BSP, you can use call the C `putchar`
99+
function and friends to output to the simulator console.
100+
101+
Here's a complete example:
102+
103+
```rust,ignore (cannot-test-this-because-it-assumes-special-libc-functions)
104+
#![no_std]
105+
#![no_main]
106+
107+
extern "C" {
108+
fn putchar(ch: i32);
109+
fn _exit(code: i32) -> !;
110+
}
111+
112+
#[no_mangle]
113+
extern "C" fn main() -> i32 {
114+
let message = "Hello, this is Rust!";
115+
for b in message.bytes() {
116+
unsafe {
117+
putchar(b as i32);
118+
}
119+
}
120+
0
121+
}
122+
123+
#[panic_handler]
124+
fn panic(_panic: &core::panic::PanicInfo) -> ! {
125+
unsafe {
126+
_exit(1);
127+
}
128+
}
129+
```
130+
131+
```console
132+
$ cargo run --target=sparc-unknown-none-elf
133+
Compiling sparc-demo-rust v0.1.0 (/work/sparc-demo-rust)
134+
Finished dev [unoptimized + debuginfo] target(s) in 3.44s
135+
Running `tsim-leon3 target/sparc-unknown-none-elf/debug/sparc-demo-rust`
136+
137+
TSIM3 LEON3 SPARC simulator, version 3.1.9 (evaluation version)
138+
139+
Copyright (C) 2023, Frontgrade Gaisler - all rights reserved.
140+
This software may only be used with a valid license.
141+
For latest updates, go to https://www.gaisler.com/
142+
Comments or bug-reports to [email protected]
143+
144+
This TSIM evaluation version will expire 2023-11-28
145+
146+
Number of CPUs: 2
147+
system frequency: 50.000 MHz
148+
icache: 1 * 4 KiB, 16 bytes/line (4 KiB total)
149+
dcache: 1 * 4 KiB, 16 bytes/line (4 KiB total)
150+
Allocated 8192 KiB SRAM memory, in 1 bank at 0x40000000
151+
Allocated 32 MiB SDRAM memory, in 1 bank at 0x60000000
152+
Allocated 8192 KiB ROM memory at 0x00000000
153+
section: .text, addr: 0x40000000, size: 20528 bytes
154+
section: .rodata, addr: 0x40005030, size: 128 bytes
155+
section: .data, addr: 0x400050b0, size: 1176 bytes
156+
read 347 symbols
157+
158+
tsim> run
159+
Initializing and starting from 0x40000000
160+
Hello, this is Rust!
161+
162+
Program exited normally on CPU 0.
163+
tsim>
164+
```

src/doc/rustdoc/src/what-is-rustdoc.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ top, with no contents.
3737
## Configuring rustdoc
3838

3939
There are two problems with this: first, why does it
40-
think that our package is named "lib"? Second, why does it not have any
40+
think that our crate is named "lib"? Second, why does it not have any
4141
contents?
4242

4343
The first problem is due to `rustdoc` trying to be helpful; like `rustc`,

src/tools/build-manifest/src/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ static TARGETS: &[&str] = &[
127127
"s390x-unknown-linux-gnu",
128128
"sparc64-unknown-linux-gnu",
129129
"sparcv9-sun-solaris",
130+
"sparc-unknown-none-elf",
130131
"thumbv6m-none-eabi",
131132
"thumbv7em-none-eabi",
132133
"thumbv7em-none-eabihf",

tests/ui/deriving/deriving-all-codegen.stdout

+5-9
Original file line numberDiff line numberDiff line change
@@ -798,24 +798,22 @@ impl ::core::marker::Copy for Enum0 { }
798798
#[automatically_derived]
799799
impl ::core::fmt::Debug for Enum0 {
800800
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
801-
unsafe { ::core::intrinsics::unreachable() }
801+
match *self {}
802802
}
803803
}
804804
#[automatically_derived]
805805
impl ::core::hash::Hash for Enum0 {
806806
#[inline]
807807
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
808-
unsafe { ::core::intrinsics::unreachable() }
808+
match *self {}
809809
}
810810
}
811811
#[automatically_derived]
812812
impl ::core::marker::StructuralPartialEq for Enum0 { }
813813
#[automatically_derived]
814814
impl ::core::cmp::PartialEq for Enum0 {
815815
#[inline]
816-
fn eq(&self, other: &Enum0) -> bool {
817-
unsafe { ::core::intrinsics::unreachable() }
818-
}
816+
fn eq(&self, other: &Enum0) -> bool { match *self {} }
819817
}
820818
#[automatically_derived]
821819
impl ::core::marker::StructuralEq for Enum0 { }
@@ -831,15 +829,13 @@ impl ::core::cmp::PartialOrd for Enum0 {
831829
#[inline]
832830
fn partial_cmp(&self, other: &Enum0)
833831
-> ::core::option::Option<::core::cmp::Ordering> {
834-
unsafe { ::core::intrinsics::unreachable() }
832+
match *self {}
835833
}
836834
}
837835
#[automatically_derived]
838836
impl ::core::cmp::Ord for Enum0 {
839837
#[inline]
840-
fn cmp(&self, other: &Enum0) -> ::core::cmp::Ordering {
841-
unsafe { ::core::intrinsics::unreachable() }
842-
}
838+
fn cmp(&self, other: &Enum0) -> ::core::cmp::Ordering { match *self {} }
843839
}
844840

845841
// A single-variant enum.

tests/ui/error-codes/E0283.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | fn create() -> u32;
77
LL | let cont: u32 = Generator::create();
88
| ^^^^^^^^^^^^^^^^^ cannot call associated function of trait
99
|
10-
help: use a fully-qualified path to a specific available implementation (2 found)
10+
help: use a fully-qualified path to a specific available implementation
1111
|
1212
LL | let cont: u32 = </* self type */ as Generator>::create();
1313
| +++++++++++++++++++ +

tests/ui/error-codes/E0790.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ LL | fn my_fn();
6363
LL | MyTrait2::my_fn();
6464
| ^^^^^^^^^^^^^^^ cannot call associated function of trait
6565
|
66-
help: use a fully-qualified path to a specific available implementation (2 found)
66+
help: use a fully-qualified path to a specific available implementation
6767
|
6868
LL | </* self type */ as MyTrait2>::my_fn();
6969
| +++++++++++++++++++ +
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Regression test for #113610 where we ICEd when trying to print
2+
// inference variables created by instantiating the self type parameter.
3+
4+
fn main() {
5+
let _ = (Default::default(),);
6+
//~^ ERROR cannot call associated function on trait
7+
}

0 commit comments

Comments
 (0)