Auto merge of #27265 - steveklabnik:rollup, r=steveklabnik
- Successful merges: #27137, #27145, #27177, #27193, #27212, #27220, #27229, #27235, #27238, #27244, #27251 - Failed merges:
This commit is contained in:
commit
82d40cb2ba
@ -1636,6 +1636,10 @@ The type of a function declared in an extern block is `extern "abi" fn(A1, ...,
|
||||
An) -> R`, where `A1...An` are the declared types of its arguments and `R` is
|
||||
the declared return type.
|
||||
|
||||
It is valid to add the `link` attribute on an empty extern block. You can use
|
||||
this to satisfy the linking requirements of extern blocks elsewhere in your code
|
||||
(including upstream crates) instead of adding the attribute to each extern block.
|
||||
|
||||
## Visibility and Privacy
|
||||
|
||||
These two terms are often used interchangeably, and what they are attempting to
|
||||
|
@ -63,7 +63,7 @@
|
||||
* [No stdlib](no-stdlib.md)
|
||||
* [Intrinsics](intrinsics.md)
|
||||
* [Lang items](lang-items.md)
|
||||
* [Link args](link-args.md)
|
||||
* [Advanced linking](advanced-linking.md)
|
||||
* [Benchmark Tests](benchmark-tests.md)
|
||||
* [Box Syntax and Patterns](box-syntax-and-patterns.md)
|
||||
* [Slice Patterns](slice-patterns.md)
|
||||
|
151
src/doc/trpl/advanced-linking.md
Normal file
151
src/doc/trpl/advanced-linking.md
Normal file
@ -0,0 +1,151 @@
|
||||
% Advanced Linking
|
||||
|
||||
The common cases of linking with Rust have been covered earlier in this book,
|
||||
but supporting the range of linking possibilities made available by other
|
||||
languages is important for Rust to achieve seamless interaction with native
|
||||
libraries.
|
||||
|
||||
# Link args
|
||||
|
||||
There is one other way to tell `rustc` how to customize linking, and that is via
|
||||
the `link_args` attribute. This attribute is applied to `extern` blocks and
|
||||
specifies raw flags which need to get passed to the linker when producing an
|
||||
artifact. An example usage would be:
|
||||
|
||||
``` no_run
|
||||
#![feature(link_args)]
|
||||
|
||||
#[link_args = "-foo -bar -baz"]
|
||||
extern {}
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
Note that this feature is currently hidden behind the `feature(link_args)` gate
|
||||
because this is not a sanctioned way of performing linking. Right now `rustc`
|
||||
shells out to the system linker (`gcc` on most systems, `link.exe` on MSVC),
|
||||
so it makes sense to provide extra command line
|
||||
arguments, but this will not always be the case. In the future `rustc` may use
|
||||
LLVM directly to link native libraries, in which case `link_args` will have no
|
||||
meaning. You can achieve the same effect as the `link-args` attribute with the
|
||||
`-C link-args` argument to `rustc`.
|
||||
|
||||
It is highly recommended to *not* use this attribute, and rather use the more
|
||||
formal `#[link(...)]` attribute on `extern` blocks instead.
|
||||
|
||||
# Static linking
|
||||
|
||||
Static linking refers to the process of creating output that contain all
|
||||
required libraries and so don't need libraries installed on every system where
|
||||
you want to use your compiled project. Pure-Rust dependencies are statically
|
||||
linked by default so you can use created binaries and libraries without
|
||||
installing the Rust everywhere. By contrast, native libraries
|
||||
(e.g. `libc` and `libm`) usually dynamically linked, but it is possible to
|
||||
change this and statically link them as well.
|
||||
|
||||
Linking is a very platform dependent topic — on some platforms, static linking
|
||||
may not be possible at all! This section assumes some basic familiarity with
|
||||
linking on your platform of choice.
|
||||
|
||||
## Linux
|
||||
|
||||
By default, all Rust programs on Linux will link to the system `libc` along with
|
||||
a number of other libraries. Let's look at an example on a 64-bit Linux machine
|
||||
with GCC and `glibc` (by far the most common `libc` on Linux):
|
||||
|
||||
``` text
|
||||
$ cat example.rs
|
||||
fn main() {}
|
||||
$ rustc example.rs
|
||||
$ ldd example
|
||||
linux-vdso.so.1 => (0x00007ffd565fd000)
|
||||
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fa81889c000)
|
||||
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa81867e000)
|
||||
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fa818475000)
|
||||
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fa81825f000)
|
||||
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa817e9a000)
|
||||
/lib64/ld-linux-x86-64.so.2 (0x00007fa818cf9000)
|
||||
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa817b93000)
|
||||
```
|
||||
|
||||
Dynamic linking on Linux can be undesirable if you wish to use new library
|
||||
features on old systems or target systems which do not have the required
|
||||
dependencies for your program to run.
|
||||
|
||||
Static linking is supported via an alternative `libc`, `musl` - this must be
|
||||
enabled at Rust compile-time with some prerequisites available. You can compile
|
||||
your own version of Rust with `musl` enabled and install it into a custom
|
||||
directory with the instructions below:
|
||||
|
||||
```text
|
||||
$ mkdir musldist
|
||||
$ PREFIX=$(pwd)/musldist
|
||||
$
|
||||
$ # Build musl
|
||||
$ wget http://www.musl-libc.org/releases/musl-1.1.10.tar.gz
|
||||
[...]
|
||||
$ tar xf musl-1.1.10.tar.gz
|
||||
$ cd musl-1.1.10/
|
||||
musl-1.1.10 $ ./configure --disable-shared --prefix=$PREFIX
|
||||
[...]
|
||||
musl-1.1.10 $ make
|
||||
[...]
|
||||
musl-1.1.10 $ make install
|
||||
[...]
|
||||
musl-1.1.10 $ cd ..
|
||||
$ du -h musldist/lib/libc.a
|
||||
2.2M musldist/lib/libc.a
|
||||
$
|
||||
$ # Build libunwind.a
|
||||
$ wget http://llvm.org/releases/3.6.1/llvm-3.6.1.src.tar.xz
|
||||
$ tar xf llvm-3.6.1.src.tar.xz
|
||||
$ cd llvm-3.6.1.src/projects/
|
||||
llvm-3.6.1.src/projects $ svn co http://llvm.org/svn/llvm-project/libcxxabi/trunk/ libcxxabi
|
||||
llvm-3.6.1.src/projects $ svn co http://llvm.org/svn/llvm-project/libunwind/trunk/ libunwind
|
||||
llvm-3.6.1.src/projects $ sed -i 's#^\(include_directories\).*$#\0\n\1(../libcxxabi/include)#' libunwind/CMakeLists.txt
|
||||
llvm-3.6.1.src/projects $ mkdir libunwind/build
|
||||
llvm-3.6.1.src/projects $ cd libunwind/build
|
||||
llvm-3.6.1.src/projects/libunwind/build $ cmake -DLLVM_PATH=../../.. -DLIBUNWIND_ENABLE_SHARED=0 ..
|
||||
llvm-3.6.1.src/projects/libunwind/build $ make
|
||||
llvm-3.6.1.src/projects/libunwind/build $ cp lib/libunwind.a $PREFIX/lib/
|
||||
llvm-3.6.1.src/projects/libunwind/build $ cd cd ../../../../
|
||||
$ du -h musldist/lib/libunwind.a
|
||||
164K musldist/lib/libunwind.a
|
||||
$
|
||||
$ # Build musl-enabled rust
|
||||
$ git clone https://github.com/rust-lang/rust.git muslrust
|
||||
$ cd muslrust
|
||||
muslrust $ ./configure --target=x86_64-unknown-linux-musl --musl-root=$PREFIX --prefix=$PREFIX
|
||||
muslrust $ make
|
||||
muslrust $ make install
|
||||
muslrust $ cd ..
|
||||
$ du -h musldist/bin/rustc
|
||||
12K musldist/bin/rustc
|
||||
```
|
||||
|
||||
You now have a build of a `musl`-enabled Rust! Because we've installed it to a
|
||||
custom prefix we need to make sure our system can the binaries and appropriate
|
||||
libraries when we try and run it:
|
||||
|
||||
```text
|
||||
$ export PATH=$PREFIX/bin:$PATH
|
||||
$ export LD_LIBRARY_PATH=$PREFIX/lib:$LD_LIBRARY_PATH
|
||||
```
|
||||
|
||||
Let's try it out!
|
||||
|
||||
```text
|
||||
$ echo 'fn main() { println!("hi!"); panic!("failed"); }' > example.rs
|
||||
$ rustc --target=x86_64-unknown-linux-musl example.rs
|
||||
$ ldd example
|
||||
not a dynamic executable
|
||||
$ ./example
|
||||
hi!
|
||||
thread '<main>' panicked at 'failed', example.rs:1
|
||||
```
|
||||
|
||||
Success! This binary can be copied to almost any Linux machine with the same
|
||||
machine architecture and run without issues.
|
||||
|
||||
`cargo build` also permits the `--target` option so you should be able to build
|
||||
your crates as normal. However, you may need to recompile your native libraries
|
||||
against `musl` before they can be linked against.
|
@ -1,25 +0,0 @@
|
||||
% Link args
|
||||
|
||||
There is one other way to tell rustc how to customize linking, and that is via
|
||||
the `link_args` attribute. This attribute is applied to `extern` blocks and
|
||||
specifies raw flags which need to get passed to the linker when producing an
|
||||
artifact. An example usage would be:
|
||||
|
||||
``` no_run
|
||||
#![feature(link_args)]
|
||||
|
||||
#[link_args = "-foo -bar -baz"]
|
||||
extern {}
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
Note that this feature is currently hidden behind the `feature(link_args)` gate
|
||||
because this is not a sanctioned way of performing linking. Right now rustc
|
||||
shells out to the system linker, so it makes sense to provide extra command line
|
||||
arguments, but this will not always be the case. In the future rustc may use
|
||||
LLVM directly to link native libraries, in which case `link_args` will have no
|
||||
meaning.
|
||||
|
||||
It is highly recommended to *not* use this attribute, and rather use the more
|
||||
formal `#[link(...)]` attribute on `extern` blocks instead.
|
||||
|
@ -88,6 +88,24 @@ for x in 0..10 {
|
||||
}
|
||||
```
|
||||
|
||||
You may also encounter situations where you have nested loops and need to
|
||||
specify which one your `break` or `continue` statement is for. Like most
|
||||
other languages, by default a `break` or `continue` will apply to innermost
|
||||
loop. In a sitation where you would like to a `break` or `continue` for one
|
||||
of the outer loops, you can use labels to specify which loop the `break` or
|
||||
`continue` statement applies to. This will only print when both `x` and `y` are
|
||||
odd:
|
||||
|
||||
```rust
|
||||
'outer: for x in 0..10 {
|
||||
'inner: for y in 0..10 {
|
||||
if x % 2 == 0 { continue 'outer; } // continues the loop over x
|
||||
if y % 2 == 0 { continue 'inner; } // continues the loop over y
|
||||
println!("x: {}, y: {}", x, y);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Both `continue` and `break` are valid in both `while` loops and [`for` loops][for].
|
||||
|
||||
[for]: for-loops.html
|
||||
|
@ -1057,6 +1057,10 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeTo<Idx> {
|
||||
/// The `Deref` trait is used to specify the functionality of dereferencing
|
||||
/// operations like `*v`.
|
||||
///
|
||||
/// `Deref` also enables ['`Deref` coercions'][coercions].
|
||||
///
|
||||
/// [coercions]: ../../book/deref-coercions.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// A struct with a single field which is accessible via dereferencing the
|
||||
@ -1111,6 +1115,10 @@ impl<'a, T: ?Sized> Deref for &'a mut T {
|
||||
/// The `DerefMut` trait is used to specify the functionality of dereferencing
|
||||
/// mutably like `*v = 1;`
|
||||
///
|
||||
/// `DerefMut` also enables ['`Deref` coercions'][coercions].
|
||||
///
|
||||
/// [coercions]: ../../book/deref-coercions.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// A struct with a single field which is modifiable via dereferencing the
|
||||
|
@ -967,6 +967,9 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
Some(def::DefVariant(enum_def, variant_def, _)) => {
|
||||
(lookup_variant_by_id(tcx, enum_def, variant_def), None)
|
||||
}
|
||||
Some(def::DefStruct(_)) => {
|
||||
return Ok(ConstVal::Struct(e.id))
|
||||
}
|
||||
_ => (None, None)
|
||||
};
|
||||
let const_expr = match const_expr {
|
||||
|
@ -20,9 +20,7 @@ pub fn opts() -> TargetOptions {
|
||||
linker_is_gnu: true,
|
||||
has_rpath: true,
|
||||
position_independent_executables: true,
|
||||
pre_link_args: vec!(
|
||||
),
|
||||
archive_format: "bsd".to_string(),
|
||||
archive_format: "gnu".to_string(),
|
||||
|
||||
.. Default::default()
|
||||
}
|
||||
|
@ -12,6 +12,56 @@
|
||||
|
||||
register_long_diagnostics! {
|
||||
|
||||
E0373: r##"
|
||||
This error occurs when an attempt is made to use data captured by a closure,
|
||||
when that data may no longer exist. It's most commonly seen when attempting to
|
||||
return a closure:
|
||||
|
||||
```
|
||||
fn foo() -> Box<Fn(u32) -> u32> {
|
||||
let x = 0u32;
|
||||
Box::new(|y| x + y)
|
||||
}
|
||||
```
|
||||
|
||||
Notice that `x` is stack-allocated by `foo()`. By default, Rust captures
|
||||
closed-over data by reference. This means that once `foo()` returns, `x` no
|
||||
longer exists. An attempt to access `x` within the closure would thus be unsafe.
|
||||
|
||||
Another situation where this might be encountered is when spawning threads:
|
||||
|
||||
```
|
||||
fn foo() {
|
||||
let x = 0u32;
|
||||
let y = 1u32;
|
||||
|
||||
let thr = std::thread::spawn(|| {
|
||||
x + y
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
Since our new thread runs in parallel, the stack frame containing `x` and `y`
|
||||
may well have disappeared by the time we try to use them. Even if we call
|
||||
`thr.join()` within foo (which blocks until `thr` has completed, ensuring the
|
||||
stack frame won't disappear), we will not succeed: the compiler cannot prove
|
||||
that this behaviour is safe, and so won't let us do it.
|
||||
|
||||
The solution to this problem is usually to switch to using a `move` closure.
|
||||
This approach moves (or copies, where possible) data into the closure, rather
|
||||
than taking references to it. For example:
|
||||
|
||||
```
|
||||
fn foo() -> Box<Fn(u32) -> u32> {
|
||||
let x = 0u32;
|
||||
Box::new(move |y| x + y)
|
||||
}
|
||||
```
|
||||
|
||||
Now that the closure has its own copy of the data, there's no need to worry
|
||||
about safety.
|
||||
"##,
|
||||
|
||||
E0381: r##"
|
||||
It is not allowed to use or capture an uninitialized variable. For example:
|
||||
|
||||
@ -28,7 +78,6 @@ used.
|
||||
}
|
||||
|
||||
register_diagnostics! {
|
||||
E0373, // closure may outlive current fn, but it borrows {}, which is owned by current fn
|
||||
E0382, // use of partially/collaterally moved value
|
||||
E0383, // partial reinitialization of uninitialized structure
|
||||
E0384, // reassignment of immutable variable
|
||||
|
@ -426,6 +426,57 @@ use something_which_doesnt_exist;
|
||||
Please verify you didn't misspell the import's name.
|
||||
"##,
|
||||
|
||||
E0437: r##"
|
||||
Trait impls can only implement associated types that are members of the trait in
|
||||
question. This error indicates that you attempted to implement an associated
|
||||
type whose name does not match the name of any associated type in the trait.
|
||||
|
||||
Here is an example that demonstrates the error:
|
||||
|
||||
```
|
||||
trait Foo {}
|
||||
|
||||
impl Foo for i32 {
|
||||
type Bar = bool;
|
||||
}
|
||||
```
|
||||
|
||||
The solution to this problem is to remove the extraneous associated type:
|
||||
|
||||
```
|
||||
trait Foo {}
|
||||
|
||||
impl Foo for i32 {}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0438: r##"
|
||||
Trait impls can only implement associated constants that are members of the
|
||||
trait in question. This error indicates that you attempted to implement an
|
||||
associated constant whose name does not match the name of any associated
|
||||
constant in the trait.
|
||||
|
||||
Here is an example that demonstrates the error:
|
||||
|
||||
```
|
||||
#![feature(associated_consts)]
|
||||
|
||||
trait Foo {}
|
||||
|
||||
impl Foo for i32 {
|
||||
const BAR: bool = true;
|
||||
}
|
||||
```
|
||||
|
||||
The solution to this problem is to remove the extraneous associated constant:
|
||||
|
||||
```
|
||||
trait Foo {}
|
||||
|
||||
impl Foo for i32 {}
|
||||
```
|
||||
"##
|
||||
|
||||
}
|
||||
|
||||
register_diagnostics! {
|
||||
@ -468,6 +519,4 @@ register_diagnostics! {
|
||||
E0432, // unresolved import
|
||||
E0434, // can't capture dynamic environment in a fn item
|
||||
E0435, // attempt to use a non-constant value in a constant
|
||||
E0437, // type is not a member of trait
|
||||
E0438, // const is not a member of trait
|
||||
}
|
||||
|
@ -1316,6 +1316,45 @@ fn main() {
|
||||
```
|
||||
"##,
|
||||
|
||||
E0120: r##"
|
||||
An attempt was made to implement Drop on a trait, which is not allowed: only
|
||||
structs and enums can implement Drop. An example causing this error:
|
||||
|
||||
```
|
||||
trait MyTrait {}
|
||||
|
||||
impl Drop for MyTrait {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
```
|
||||
|
||||
A workaround for this problem is to wrap the trait up in a struct, and implement
|
||||
Drop on that. An example is shown below:
|
||||
|
||||
```
|
||||
trait MyTrait {}
|
||||
struct MyWrapper<T: MyTrait> { foo: T }
|
||||
|
||||
impl <T: MyTrait> Drop for MyWrapper<T> {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Alternatively, wrapping trait objects requires something like the following:
|
||||
|
||||
```
|
||||
trait MyTrait {}
|
||||
|
||||
//or Box<MyTrait>, if you wanted an owned trait object
|
||||
struct MyWrapper<'a> { foo: &'a MyTrait }
|
||||
|
||||
impl <'a> Drop for MyWrapper<'a> {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0121: r##"
|
||||
In order to be consistent with Rust's lack of global type inference, type
|
||||
placeholders are disallowed by design in item signatures.
|
||||
@ -1895,6 +1934,62 @@ type Foo = Trait<Bar=i32>; // ok!
|
||||
```
|
||||
"##,
|
||||
|
||||
E0223: r##"
|
||||
An attempt was made to retrieve an associated type, but the type was ambiguous.
|
||||
For example:
|
||||
|
||||
```
|
||||
trait MyTrait {type X; }
|
||||
|
||||
fn main() {
|
||||
let foo: MyTrait::X;
|
||||
}
|
||||
```
|
||||
|
||||
The problem here is that we're attempting to take the type of X from MyTrait.
|
||||
Unfortunately, the type of X is not defined, because it's only made concrete in
|
||||
implementations of the trait. A working version of this code might look like:
|
||||
|
||||
```
|
||||
trait MyTrait {type X; }
|
||||
struct MyStruct;
|
||||
|
||||
impl MyTrait for MyStruct {
|
||||
type X = u32;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let foo: <MyStruct as MyTrait>::X;
|
||||
}
|
||||
```
|
||||
|
||||
This syntax specifies that we want the X type from MyTrait, as made concrete in
|
||||
MyStruct. The reason that we cannot simply use `MyStruct::X` is that MyStruct
|
||||
might implement two different traits with identically-named associated types.
|
||||
This syntax allows disambiguation between the two.
|
||||
"##,
|
||||
|
||||
E0225: r##"
|
||||
You attempted to use multiple types as bounds for a closure or trait object.
|
||||
Rust does not currently support this. A simple example that causes this error:
|
||||
|
||||
```
|
||||
fn main() {
|
||||
let _: Box<std::io::Read+std::io::Write>;
|
||||
}
|
||||
```
|
||||
|
||||
Builtin traits are an exception to this rule: it's possible to have bounds of
|
||||
one non-builtin type, plus any number of builtin types. For example, the
|
||||
following compiles correctly:
|
||||
|
||||
```
|
||||
fn main() {
|
||||
let _: Box<std::io::Read+Copy+Sync>;
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0232: r##"
|
||||
The attribute must have a value. Erroneous code example:
|
||||
|
||||
@ -2195,7 +2290,6 @@ register_diagnostics! {
|
||||
E0103,
|
||||
E0104,
|
||||
E0118,
|
||||
E0120,
|
||||
E0122,
|
||||
E0123,
|
||||
E0127,
|
||||
@ -2233,9 +2327,7 @@ register_diagnostics! {
|
||||
E0221, // ambiguous associated type in bounds
|
||||
//E0222, // Error code E0045 (variadic function must have C calling
|
||||
// convention) duplicate
|
||||
E0223, // ambiguous associated type
|
||||
E0224, // at least one non-builtin train is required for an object type
|
||||
E0225, // only the builtin traits can be used as closure or object bounds
|
||||
E0226, // only a single explicit lifetime bound is permitted
|
||||
E0227, // ambiguous lifetime bound, explicit lifetime bound required
|
||||
E0228, // explicit lifetime bound required
|
||||
|
@ -434,9 +434,9 @@ pub fn panicking() -> bool {
|
||||
|
||||
/// Invokes a closure, capturing the cause of panic if one occurs.
|
||||
///
|
||||
/// This function will return `Ok(())` if the closure does not panic, and will
|
||||
/// return `Err(cause)` if the closure panics. The `cause` returned is the
|
||||
/// object with which panic was originally invoked.
|
||||
/// This function will return `Ok` with the closure's result if the closure
|
||||
/// does not panic, and will return `Err(cause)` if the closure panics. The
|
||||
/// `cause` returned is the object with which panic was originally invoked.
|
||||
///
|
||||
/// It is currently undefined behavior to unwind from Rust code into foreign
|
||||
/// code, so this function is particularly useful when Rust is called from
|
||||
|
@ -1,4 +1,7 @@
|
||||
S 2015-07-17 d4432b3
|
||||
bitrig-x86_64 af77768e0eb0f4c7ec5a8e36047a08053b54b230
|
||||
freebsd-i386 b049325e5b2efe5f4884f3dafda448c1dac49b4f
|
||||
freebsd-x86_64 a59e397188dbfe67456a6301df5ca13c7e238ab9
|
||||
linux-i386 93f6216a35d3bed3cedf244c9aff4cd716336bd9
|
||||
linux-x86_64 d8f4967fc71a153c925faecf95a7feadf7e463a4
|
||||
macos-i386 29852c4d4b5a851f16d627856a279cae5bf9bd01
|
||||
|
21
src/test/compile-fail/issue-27008.rs
Normal file
21
src/test/compile-fail/issue-27008.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
struct S;
|
||||
|
||||
fn main() {
|
||||
let b = [0; S];
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected `usize`
|
||||
//~| found `S`
|
||||
//~| expected usize
|
||||
//~| found struct `S`
|
||||
//~| ERROR expected positive integer for repeat count, found struct
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user