diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/compiletest/compiletest.rs | 3 | ||||
| -rw-r--r-- | src/doc/reference.md | 12 | ||||
| -rw-r--r-- | src/doc/rustdoc.md | 295 | ||||
| -rw-r--r-- | src/doc/trpl/SUMMARY.md | 2 | ||||
| -rw-r--r-- | src/doc/trpl/crates-and-modules.md | 3 | ||||
| -rw-r--r-- | src/doc/trpl/documentation.md | 296 | ||||
| -rw-r--r-- | src/doc/trpl/more-strings.md | 283 | ||||
| -rw-r--r-- | src/doc/trpl/ownership.md | 16 | ||||
| -rw-r--r-- | src/doc/trpl/pointers.md | 8 | ||||
| -rw-r--r-- | src/liballoc/boxed.rs | 79 | ||||
| -rw-r--r-- | src/libcollections/slice.rs | 23 | ||||
| -rw-r--r-- | src/libcore/cell.rs | 4 | ||||
| -rw-r--r-- | src/liblibc/lib.rs | 24 | ||||
| -rw-r--r-- | src/librustc_trans/trans/debuginfo.rs | 8 | ||||
| -rw-r--r-- | src/libstd/collections/mod.rs | 54 | ||||
| -rw-r--r-- | src/libstd/rt/unwind.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sync/rwlock.rs | 10 | ||||
| -rw-r--r-- | src/libstd/thread.rs | 2 | ||||
| -rw-r--r-- | src/test/debuginfo/associated-types.rs | 152 |
19 files changed, 937 insertions, 339 deletions
diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 1a9a1c08b07..b3f0034ca89 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -248,6 +248,9 @@ pub fn run_tests(config: &Config) { // parallel (especially when we have lots and lots of child processes). // For context, see #8904 io::test::raise_fd_limit(); + // Prevent issue #21352 UAC blocking .exe containing 'patch' etc. on Windows + // If #11207 is resolved (adding manifest to .exe) this becomes unnecessary + os::setenv("__COMPAT_LAYER", "RunAsInvoker"); let res = test::run_tests_console(&opts, tests.into_iter().collect()); match res { Ok(true) => {} diff --git a/src/doc/reference.md b/src/doc/reference.md index 9ec4708eb2f..1bcb5a7b4a0 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -739,6 +739,15 @@ Rust syntax is restricted in two ways: * `concat!` : concatenates a comma-separated list of literals * `concat_idents!` : create a new identifier by concatenating the arguments +The following attributes are used for quasiquoting in procedural macros: + +* `quote_expr!` +* `quote_item!` +* `quote_pat!` +* `quote_stmt!` +* `quote_tokens!` +* `quote_ty!` + # Crates and source files Rust is a *compiled* language. Its semantics obey a *phase distinction* @@ -2028,6 +2037,9 @@ type int8_t = i8; item](#language-items) for more details. - `test` - indicates that this function is a test function, to only be compiled in case of `--test`. +- `should_fail` - indicates that this test function should panic, inverting the success condition. +- `cold` - The function is unlikely to be executed, so optimize it (and calls + to it) differently. ### Static-only attributes diff --git a/src/doc/rustdoc.md b/src/doc/rustdoc.md index 0b686eb76db..d4a25efec17 100644 --- a/src/doc/rustdoc.md +++ b/src/doc/rustdoc.md @@ -1,296 +1,3 @@ % Rust Documentation -`rustdoc` is the built-in tool for generating documentation. It integrates -with the compiler to provide accurate hyperlinking between usage of types and -their documentation. Furthermore, by not using a separate parser, it will -never reject your valid Rust code. - -# Creating Documentation - -Documenting Rust APIs is quite simple. To document a given item, we have "doc -comments": - -~~~ -# #![allow(unused_attribute)] -// the "link" crate attribute is currently required for rustdoc, but normally -// isn't needed. -#![crate_id = "universe"] -#![crate_type="lib"] - -//! Tools for dealing with universes (this is a doc comment, and is shown on -//! the crate index page. The ! makes it apply to the parent of the comment, -//! rather than what follows). - -# mod workaround_the_outer_function_rustdoc_inserts { -/// Widgets are very common (this is a doc comment, and will show up on -/// Widget's documentation). -pub struct Widget { - /// All widgets have a purpose (this is a doc comment, and will show up - /// the field's documentation). - purpose: String, - /// Humans are not allowed to understand some widgets - understandable: bool -} - -pub fn recalibrate() { - //! Recalibrate a pesky universe (this is also a doc comment, like above, - //! the documentation will be applied to the *parent* item, so - //! `recalibrate`). - /* ... */ -} -# } -~~~ - -Documentation can also be controlled via the `doc` attribute on items. This is -implicitly done by the compiler when using the above form of doc comments -(converting the slash-based comments to `#[doc]` attributes). - -~~~ -#[doc = " -Calculates the factorial of a number. - -Given the input integer `n`, this function will calculate `n!` and return it. -"] -pub fn factorial(n: int) -> int { if n < 2 {1} else {n * factorial(n - 1)} } -# fn main() {} -~~~ - -The `doc` attribute can also be used to control how rustdoc emits documentation -in some cases. - -``` -// Rustdoc will inline documentation of a `pub use` into this crate when the -// `pub use` reaches across crates, but this behavior can also be disabled. -#[doc(no_inline)] -pub use std::option::Option; -# fn main() {} -``` - -Doc comments are markdown, and are currently parsed with the -[hoedown][hoedown] library. rustdoc does not yet do any fanciness such as -referencing other items inline, like javadoc's `@see`. One exception to this -is that the first paragraph will be used as the "summary" of an item in the -generated documentation: - -~~~ -/// A whizbang. Does stuff. (this line is the summary) -/// -/// Whizbangs are ... -struct Whizbang; -~~~ - -To generate the docs, run `rustdoc universe.rs`. By default, it generates a -directory called `doc`, with the documentation for `universe` being in -`doc/universe/index.html`. If you are using other crates with `extern crate`, -rustdoc will even link to them when you use their types, as long as their -documentation has already been generated by a previous run of rustdoc, or the -crate advertises that its documentation is hosted at a given URL. - -The generated output can be controlled with the `doc` crate attribute, which -is how the above advertisement works. An example from the `libstd` -documentation: - -~~~ -#[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", - html_root_url = "http://doc.rust-lang.org/")]; -~~~ - -The `html_root_url` is the prefix that rustdoc will apply to any references to -that crate's types etc. - -rustdoc can also generate JSON, for consumption by other tools, with -`rustdoc --output-format json`, and also consume already-generated JSON with -`rustdoc --input-format json`. - -rustdoc also supports personalizing the output from crates' documentation, -similar to markdown options. - -- `--html-in-header FILE`: includes the contents of `FILE` at the - end of the `<head>...</head>` section. -- `--html-before-content FILE`: includes the contents of `FILE` - directly after `<body>`, before the rendered content (including the - search bar). -- `--html-after-content FILE`: includes the contents of `FILE` - after all the rendered content. - -# Using the Documentation - -The web pages generated by rustdoc present the same logical hierarchy that one -writes a library with. Every kind of item (function, struct, etc) has its own -color, and one can always click on a colored type to jump to its -documentation. There is a search bar at the top, which is powered by some -JavaScript and a statically-generated search index. No special web server is -required for the search. - -[hoedown]: https://github.com/hoedown/hoedown - -# Testing the Documentation - -`rustdoc` has support for testing code examples which appear in the -documentation. This is helpful for keeping code examples up to date with the -source code. - -To test documentation, the `--test` argument is passed to rustdoc: - -~~~ {.sh} -rustdoc --test crate.rs -~~~ - -## Defining tests - -Rust documentation currently uses the markdown format, and rustdoc treats all -code blocks as testable-by-default unless they carry a language tag of another -language. In order to not run a test over a block of code, the `ignore` string -can be added to the three-backtick form of markdown code block. - -~~~md -``` -// This is a testable code block -``` - -```rust{.example} -// This is rust and also testable -``` - -```ignore -// This is not a testable code block -``` - - // This is a testable code block (4-space indent) - -```sh -# this is shell code and not tested -``` -~~~ - -You can specify that the test's execution should fail with the `should_fail` -directive. - -~~~md -```should_fail -// This code block is expected to generate a panic when run -``` -~~~ - -You can specify that the code block should be compiled but not run with the -`no_run` directive. - -~~~md -```no_run -// This code will be compiled but not executed -``` -~~~ - -Lastly, you can specify that a code block be compiled as if `--test` -were passed to the compiler using the `test_harness` directive. - -~~~md -```test_harness -#[test] -fn foo() { - panic!("oops! (will run & register as a failed test)") -} -``` -~~~ - -Rustdoc also supplies some extra sugar for helping with some tedious -documentation examples. If a line is prefixed with `# `, then the line -will not show up in the HTML documentation, but it will be used when -testing the code block (NB. the space after the `#` is required, so -that one can still write things like `#[derive(Eq)]`). - -~~~md -``` -# /!\ The three following lines are comments, which are usually stripped off by -# the doc-generating tool. In order to display them anyway in this particular -# case, the character following the leading '#' is not a usual space like in -# these first five lines but a non breakable one. -# // showing 'fib' in this documentation would just be tedious and detracts from -# // what's actually being documented. -# fn fib(n: int) { n + 2 } - -spawn(move || { fib(200); }) -``` -~~~ - -The documentation online would look like `spawn(move || { fib(200); })`, but when -testing this code, the `fib` function will be included (so it can compile). - -Rustdoc will automatically add a `main()` wrapper around your code, and in the right -place. For example: - -``` -/// ``` -/// use std::rc::Rc; -/// -/// let five = Rc::new(5); -/// ``` -# fn foo() {} -``` - -This will end up testing: - -``` -fn main() { - use std::rc::Rc; - let five = Rc::new(5); -} -``` - -Here's the full algorithm: - -1. Given a code block, if it does not contain `fn main`, it is wrapped in `fn main() { your_code }` -2. Given that result, if it contains no `extern crate` directives but it also - contains the name of the crate being tested, then `extern crate <name>` is - injected at the top. -3. Some common `allow` attributes are added for documentation examples at the top. - -## Running tests (advanced) - -Running tests often requires some special configuration to filter tests, find -libraries, or try running ignored examples. The testing framework that rustdoc -uses is built on crate `test`, which is also used when you compile crates with -rustc's `--test` flag. Extra arguments can be passed to rustdoc's test harness -with the `--test-args` flag. - -~~~console -# Only run tests containing 'foo' in their name -$ rustdoc --test lib.rs --test-args 'foo' - -# See what's possible when running tests -$ rustdoc --test lib.rs --test-args '--help' -~~~ - -When testing a library, code examples will often show how functions are used, -and this code often requires `use`-ing paths from the crate. To accommodate this, -rustdoc will implicitly add `extern crate <crate>;` where `<crate>` is the name of -the crate being tested to the top of each code example. This means that rustdoc -must be able to find a compiled version of the library crate being tested. Extra -search paths may be added via the `-L` flag to `rustdoc`. - -# Standalone Markdown files - -As well as Rust crates, rustdoc supports rendering pure Markdown files -into HTML and testing the code snippets from them. A Markdown file is -detected by a `.md` or `.markdown` extension. - -There are 4 options to modify the output that Rustdoc creates. - -- `--markdown-css PATH`: adds a `<link rel="stylesheet">` tag pointing to `PATH`. -- `--html-in-header FILE`: includes the contents of `FILE` at the - end of the `<head>...</head>` section. -- `--html-before-content FILE`: includes the contents of `FILE` - directly after `<body>`, before the rendered content (including the - title). -- `--html-after-content FILE`: includes the contents of `FILE` - directly before `</body>`, after all the rendered content. - -All of these can be specified multiple times, and they are output in -the order in which they are specified. The first line of the file being rendered must -be the title, prefixed with `%` (e.g. this page has `% Rust -Documentation` on the first line). - -Like with a Rust crate, the `--test` argument will run the code -examples to check they compile, and obeys any `--test-args` flags. The -tests are named after the last `#` heading. +This has been moved [into the book](book/documentation.html). diff --git a/src/doc/trpl/SUMMARY.md b/src/doc/trpl/SUMMARY.md index aab03add905..6131e1b8a70 100644 --- a/src/doc/trpl/SUMMARY.md +++ b/src/doc/trpl/SUMMARY.md @@ -16,6 +16,7 @@ * [Standard Input](standard-input.md) * [Guessing Game](guessing-game.md) * [II: Intermediate Rust](intermediate.md) + * [More Strings](more-strings.md) * [Crates and Modules](crates-and-modules.md) * [Testing](testing.md) * [Pointers](pointers.md) @@ -28,6 +29,7 @@ * [Traits](traits.md) * [Threads](threads.md) * [Error Handling](error-handling.md) + * [Documentation](documentation.md) * [III: Advanced Topics](advanced.md) * [FFI](ffi.md) * [Unsafe Code](unsafe.md) diff --git a/src/doc/trpl/crates-and-modules.md b/src/doc/trpl/crates-and-modules.md index 79bb5c182f4..efeb201efe8 100644 --- a/src/doc/trpl/crates-and-modules.md +++ b/src/doc/trpl/crates-and-modules.md @@ -287,8 +287,7 @@ mentioned earlier, you can use double colons to refer to sub-modules and the functions inside of them. Also, Cargo assumes that `src/main.rs` is the crate root of a binary crate, -rather than a library crate. Once we compile `src/main.rs`, we'll get an -executable that we can run. Our package now has two crates: `src/lib.rs` and +rather than a library crate. Our package now has two crates: `src/lib.rs` and `src/main.rs`. This pattern is quite common for executable crates: most functionality is in a library crate, and the executable crate uses that library. This way, other programs can also use the library crate, and it's also diff --git a/src/doc/trpl/documentation.md b/src/doc/trpl/documentation.md new file mode 100644 index 00000000000..0b686eb76db --- /dev/null +++ b/src/doc/trpl/documentation.md @@ -0,0 +1,296 @@ +% Rust Documentation + +`rustdoc` is the built-in tool for generating documentation. It integrates +with the compiler to provide accurate hyperlinking between usage of types and +their documentation. Furthermore, by not using a separate parser, it will +never reject your valid Rust code. + +# Creating Documentation + +Documenting Rust APIs is quite simple. To document a given item, we have "doc +comments": + +~~~ +# #![allow(unused_attribute)] +// the "link" crate attribute is currently required for rustdoc, but normally +// isn't needed. +#![crate_id = "universe"] +#![crate_type="lib"] + +//! Tools for dealing with universes (this is a doc comment, and is shown on +//! the crate index page. The ! makes it apply to the parent of the comment, +//! rather than what follows). + +# mod workaround_the_outer_function_rustdoc_inserts { +/// Widgets are very common (this is a doc comment, and will show up on +/// Widget's documentation). +pub struct Widget { + /// All widgets have a purpose (this is a doc comment, and will show up + /// the field's documentation). + purpose: String, + /// Humans are not allowed to understand some widgets + understandable: bool +} + +pub fn recalibrate() { + //! Recalibrate a pesky universe (this is also a doc comment, like above, + //! the documentation will be applied to the *parent* item, so + //! `recalibrate`). + /* ... */ +} +# } +~~~ + +Documentation can also be controlled via the `doc` attribute on items. This is +implicitly done by the compiler when using the above form of doc comments +(converting the slash-based comments to `#[doc]` attributes). + +~~~ +#[doc = " +Calculates the factorial of a number. + +Given the input integer `n`, this function will calculate `n!` and return it. +"] +pub fn factorial(n: int) -> int { if n < 2 {1} else {n * factorial(n - 1)} } +# fn main() {} +~~~ + +The `doc` attribute can also be used to control how rustdoc emits documentation +in some cases. + +``` +// Rustdoc will inline documentation of a `pub use` into this crate when the +// `pub use` reaches across crates, but this behavior can also be disabled. +#[doc(no_inline)] +pub use std::option::Option; +# fn main() {} +``` + +Doc comments are markdown, and are currently parsed with the +[hoedown][hoedown] library. rustdoc does not yet do any fanciness such as +referencing other items inline, like javadoc's `@see`. One exception to this +is that the first paragraph will be used as the "summary" of an item in the +generated documentation: + +~~~ +/// A whizbang. Does stuff. (this line is the summary) +/// +/// Whizbangs are ... +struct Whizbang; +~~~ + +To generate the docs, run `rustdoc universe.rs`. By default, it generates a +directory called `doc`, with the documentation for `universe` being in +`doc/universe/index.html`. If you are using other crates with `extern crate`, +rustdoc will even link to them when you use their types, as long as their +documentation has already been generated by a previous run of rustdoc, or the +crate advertises that its documentation is hosted at a given URL. + +The generated output can be controlled with the `doc` crate attribute, which +is how the above advertisement works. An example from the `libstd` +documentation: + +~~~ +#[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_root_url = "http://doc.rust-lang.org/")]; +~~~ + +The `html_root_url` is the prefix that rustdoc will apply to any references to +that crate's types etc. + +rustdoc can also generate JSON, for consumption by other tools, with +`rustdoc --output-format json`, and also consume already-generated JSON with +`rustdoc --input-format json`. + +rustdoc also supports personalizing the output from crates' documentation, +similar to markdown options. + +- `--html-in-header FILE`: includes the contents of `FILE` at the + end of the `<head>...</head>` section. +- `--html-before-content FILE`: includes the contents of `FILE` + directly after `<body>`, before the rendered content (including the + search bar). +- `--html-after-content FILE`: includes the contents of `FILE` + after all the rendered content. + +# Using the Documentation + +The web pages generated by rustdoc present the same logical hierarchy that one +writes a library with. Every kind of item (function, struct, etc) has its own +color, and one can always click on a colored type to jump to its +documentation. There is a search bar at the top, which is powered by some +JavaScript and a statically-generated search index. No special web server is +required for the search. + +[hoedown]: https://github.com/hoedown/hoedown + +# Testing the Documentation + +`rustdoc` has support for testing code examples which appear in the +documentation. This is helpful for keeping code examples up to date with the +source code. + +To test documentation, the `--test` argument is passed to rustdoc: + +~~~ {.sh} +rustdoc --test crate.rs +~~~ + +## Defining tests + +Rust documentation currently uses the markdown format, and rustdoc treats all +code blocks as testable-by-default unless they carry a language tag of another +language. In order to not run a test over a block of code, the `ignore` string +can be added to the three-backtick form of markdown code block. + +~~~md +``` +// This is a testable code block +``` + +```rust{.example} +// This is rust and also testable +``` + +```ignore +// This is not a testable code block +``` + + // This is a testable code block (4-space indent) + +```sh +# this is shell code and not tested +``` +~~~ + +You can specify that the test's execution should fail with the `should_fail` +directive. + +~~~md +```should_fail +// This code block is expected to generate a panic when run +``` +~~~ + +You can specify that the code block should be compiled but not run with the +`no_run` directive. + +~~~md +```no_run +// This code will be compiled but not executed +``` +~~~ + +Lastly, you can specify that a code block be compiled as if `--test` +were passed to the compiler using the `test_harness` directive. + +~~~md +```test_harness +#[test] +fn foo() { + panic!("oops! (will run & register as a failed test)") +} +``` +~~~ + +Rustdoc also supplies some extra sugar for helping with some tedious +documentation examples. If a line is prefixed with `# `, then the line +will not show up in the HTML documentation, but it will be used when +testing the code block (NB. the space after the `#` is required, so +that one can still write things like `#[derive(Eq)]`). + +~~~md +``` +# /!\ The three following lines are comments, which are usually stripped off by +# the doc-generating tool. In order to display them anyway in this particular +# case, the character following the leading '#' is not a usual space like in +# these first five lines but a non breakable one. +# // showing 'fib' in this documentation would just be tedious and detracts from +# // what's actually being documented. +# fn fib(n: int) { n + 2 } + +spawn(move || { fib(200); }) +``` +~~~ + +The documentation online would look like `spawn(move || { fib(200); })`, but when +testing this code, the `fib` function will be included (so it can compile). + +Rustdoc will automatically add a `main()` wrapper around your code, and in the right +place. For example: + +``` +/// ``` +/// use std::rc::Rc; +/// +/// let five = Rc::new(5); +/// ``` +# fn foo() {} +``` + +This will end up testing: + +``` +fn main() { + use std::rc::Rc; + let five = Rc::new(5); +} +``` + +Here's the full algorithm: + +1. Given a code block, if it does not contain `fn main`, it is wrapped in `fn main() { your_code }` +2. Given that result, if it contains no `extern crate` directives but it also + contains the name of the crate being tested, then `extern crate <name>` is + injected at the top. +3. Some common `allow` attributes are added for documentation examples at the top. + +## Running tests (advanced) + +Running tests often requires some special configuration to filter tests, find +libraries, or try running ignored examples. The testing framework that rustdoc +uses is built on crate `test`, which is also used when you compile crates with +rustc's `--test` flag. Extra arguments can be passed to rustdoc's test harness +with the `--test-args` flag. + +~~~console +# Only run tests containing 'foo' in their name +$ rustdoc --test lib.rs --test-args 'foo' + +# See what's possible when running tests +$ rustdoc --test lib.rs --test-args '--help' +~~~ + +When testing a library, code examples will often show how functions are used, +and this code often requires `use`-ing paths from the crate. To accommodate this, +rustdoc will implicitly add `extern crate <crate>;` where `<crate>` is the name of +the crate being tested to the top of each code example. This means that rustdoc +must be able to find a compiled version of the library crate being tested. Extra +search paths may be added via the `-L` flag to `rustdoc`. + +# Standalone Markdown files + +As well as Rust crates, rustdoc supports rendering pure Markdown files +into HTML and testing the code snippets from them. A Markdown file is +detected by a `.md` or `.markdown` extension. + +There are 4 options to modify the output that Rustdoc creates. + +- `--markdown-css PATH`: adds a `<link rel="stylesheet">` tag pointing to `PATH`. +- `--html-in-header FILE`: includes the contents of `FILE` at the + end of the `<head>...</head>` section. +- `--html-before-content FILE`: includes the contents of `FILE` + directly after `<body>`, before the rendered content (including the + title). +- `--html-after-content FILE`: includes the contents of `FILE` + directly before `</body>`, after all the rendered content. + +All of these can be specified multiple times, and they are output in +the order in which they are specified. The first line of the file being rendered must +be the title, prefixed with `%` (e.g. this page has `% Rust +Documentation` on the first line). + +Like with a Rust crate, the `--test` argument will run the code +examples to check they compile, and obeys any `--test-args` flags. The +tests are named after the last `#` heading. diff --git a/src/doc/trpl/more-strings.md b/src/doc/trpl/more-strings.md new file mode 100644 index 00000000000..07b49751b10 --- /dev/null +++ b/src/doc/trpl/more-strings.md @@ -0,0 +1,283 @@ +% More Strings + +Strings are an important concept to master in any programming language. If you +come from a managed language background, you may be surprised at the complexity +of string handling in a systems programming language. Efficient access and +allocation of memory for a dynamically sized structure involves a lot of +details. Luckily, Rust has lots of tools to help us here. + +A **string** is a sequence of unicode scalar values encoded as a stream of +UTF-8 bytes. All strings are guaranteed to be validly-encoded UTF-8 sequences. +Additionally, strings are not null-terminated and can contain null bytes. + +Rust has two main types of strings: `&str` and `String`. + +# &str + +The first kind is a `&str`. This is pronounced a 'string slice'. +String literals are of the type `&str`: + +``` +let string = "Hello there."; +``` + +Like any Rust reference, string slices have an associated lifetime. A string +literal is a `&'static str`. A string slice can be written without an explicit +lifetime in many cases, such as in function arguments. In these cases the +lifetime will be inferred: + +``` +fn takes_slice(slice: &str) { + println!("Got: {}", slice); +} +``` + +Like vector slices, string slices are simply a pointer plus a length. This +means that they're a 'view' into an already-allocated string, such as a +string literal or a `String`. + +# String + +A `String` is a heap-allocated string. This string is growable, and is also +guaranteed to be UTF-8. + +``` +let mut s = "Hello".to_string(); +println!("{}", s); + +s.push_str(", world."); +println!("{}", s); +``` + +You can coerce a `String` into a `&str` by dereferencing it: + +``` +fn takes_slice(slice: &str) { + println!("Got: {}", slice); +} + +fn main() { + let s = "Hello".to_string(); + takes_slice(&*s); +} +``` + +You can also get a `&str` from a stack-allocated array of bytes: + +``` +use std::str; + +let x: &[u8] = &[b'a', b'b']; +let stack_str: &str = str::from_utf8(x).unwrap(); +``` + +# Best Practices + +## `String` vs. `&str` + +In general, you should prefer `String` when you need ownership, and `&str` when +you just need to borrow a string. This is very similar to using `Vec<T>` vs. `&[T]`, +and `T` vs `&T` in general. + +This means starting off with this: + +```{rust,ignore} +fn foo(s: &str) { +``` + +and only moving to this: + +```{rust,ignore} +fn foo(s: String) { +``` + +If you have good reason. It's not polite to hold on to ownership you don't +need, and it can make your lifetimes more complex. + +## Generic functions + +To write a function that's generic over types of strings, use `&str`. + +``` +fn some_string_length(x: &str) -> uint { + x.len() +} + +fn main() { + let s = "Hello, world"; + + println!("{}", some_string_length(s)); + + let s = "Hello, world".to_string(); + + println!("{}", some_string_length(s.as_slice())); +} +``` + +Both of these lines will print `12`. + +## Indexing strings + +You may be tempted to try to access a certain character of a `String`, like +this: + +```{rust,ignore} +let s = "hello".to_string(); + +println!("{}", s[0]); +``` + +This does not compile. This is on purpose. In the world of UTF-8, direct +indexing is basically never what you want to do. The reason is that each +character can be a variable number of bytes. This means that you have to iterate +through the characters anyway, which is an O(n) operation. + +There's 3 basic levels of unicode (and its encodings): + +- code units, the underlying data type used to store everything +- code points/unicode scalar values (char) +- graphemes (visible characters) + +Rust provides iterators for each of these situations: + +- `.bytes()` will iterate over the underlying bytes +- `.chars()` will iterate over the code points +- `.graphemes()` will iterate over each grapheme + +Usually, the `graphemes()` method on `&str` is what you want: + +``` +let s = "u͔n͈̰̎i̙̮͚̦c͚̉o̼̩̰͗d͔̆̓ͥé"; + +for l in s.graphemes(true) { + println!("{}", l); +} +``` + +This prints: + +```text +u͔ +n͈̰̎ +i̙̮͚̦ +c͚̉ +o̼̩̰͗ +d͔̆̓ͥ +é +``` + +Note that `l` has the type `&str` here, since a single grapheme can consist of +multiple codepoints, so a `char` wouldn't be appropriate. + +This will print out each visible character in turn, as you'd expect: first "u͔", then +"n͈̰̎", etc. If you wanted each individual codepoint of each grapheme, you can use `.chars()`: + +``` +let s = "u͔n͈̰̎i̙̮͚̦c͚̉o̼̩̰͗d͔̆̓ͥé"; + +for l in s.chars() { + println!("{}", l); +} +``` + +This prints: + +```text +u +͔ +n +̎ +͈ +̰ +i +̙ +̮ +͚ +̦ +c +̉ +͚ +o +͗ +̼ +̩ +̰ +d +̆ +̓ +ͥ +͔ +e +́ +``` + +You can see how some of them are combining characters, and therefore the output +looks a bit odd. + +If you want the individual byte representation of each codepoint, you can use +`.bytes()`: + +``` +let s = "u͔n͈̰̎i̙̮͚̦c͚̉o̼̩̰͗d͔̆̓ͥé"; + +for l in s.bytes() { + println!("{}", l); +} +``` + +This will print: + +```text +117 +205 +148 +110 +204 +142 +205 +136 +204 +176 +105 +204 +153 +204 +174 +205 +154 +204 +166 +99 +204 +137 +205 +154 +111 +205 +151 +204 +188 +204 +169 +204 +176 +100 +204 +134 +205 +131 +205 +165 +205 +148 +101 +204 +129 +``` + +Many more bytes than graphemes! + +# Other Documentation + +* [the `&str` API documentation](std/str/index.html) +* [the `String` API documentation](std/string/index.html) diff --git a/src/doc/trpl/ownership.md b/src/doc/trpl/ownership.md index 8b7e37dd4c2..56cb5b1de69 100644 --- a/src/doc/trpl/ownership.md +++ b/src/doc/trpl/ownership.md @@ -244,8 +244,8 @@ three. The ownership system in Rust does this through a concept called Remember the function that borrowed an `i32`? Let's look at it again. ```rust -fn add_one(num: &i32) -> i32 { - *num + 1 +fn add_one(num: &mut i32) { + *num += 1; } ``` @@ -255,8 +255,8 @@ cover the others later. Without eliding the lifetimes, `add_one` looks like this: ```rust -fn add_one<'a>(num: &'a i32) -> i32 { - *num + 1 +fn add_one<'a>(num: &'a mut i32) { + *num += 1; } ``` @@ -278,12 +278,12 @@ fn add_two<'a, 'b>(...) Then in our parameter list, we use the lifetimes we've named: ```{rust,ignore} -...(num: &'a i32) -> ... +...(num: &'a mut i32) ``` -If you compare `&i32` to `&'a i32`, they're the same, it's just that the -lifetime `'a` has snuck in between the `&` and the `i32`. We read `&i32` as "a -reference to an i32" and `&'a i32` as "a reference to an i32 with the lifetime 'a.'" +If you compare `&mut i32` to `&'a mut i32`, they're the same, it's just that the +lifetime `'a` has snuck in between the `&` and the `mut i32`. We read `&mut i32` as "a +mutable reference to an i32" and `&'a mut i32` as "a mutable reference to an i32 with the lifetime 'a.'" Why do lifetimes matter? Well, for example, here's some code: diff --git a/src/doc/trpl/pointers.md b/src/doc/trpl/pointers.md index d74c10b8145..29986d7f235 100644 --- a/src/doc/trpl/pointers.md +++ b/src/doc/trpl/pointers.md @@ -87,7 +87,7 @@ println!("{}", x + z); This gives us an error: ```text -hello.rs:6:24: 6:25 error: mismatched types: expected `i32` but found `&i32` (expected i32 but found &-ptr) +hello.rs:6:24: 6:25 error: mismatched types: expected `_`, found `&_` (expected integral variable, found &-ptr) hello.rs:6 println!("{}", x + z); ^ ``` @@ -305,7 +305,7 @@ References are immutable by default: let x = 5; let y = &x; -*y = 5; // error: cannot assign to immutable dereference of `&`-pointer `*y` +*y = 5; // error: cannot assign to immutable borrowed content `*y` ``` They can be made mutable with `mut`, but only if its referent is also mutable. @@ -668,7 +668,7 @@ struct BigStruct { } fn foo(x: Box<BigStruct>) -> Box<BigStruct> { - return Box::new(*x); + Box::new(*x) } fn main() { @@ -696,7 +696,7 @@ struct BigStruct { } fn foo(x: Box<BigStruct>) -> BigStruct { - return *x; + *x } fn main() { diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 5ec08a1f254..c4abedf3fe8 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -8,7 +8,40 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! A unique pointer type. +//! A pointer type for heap allocation. +//! +//! `Box<T>`, casually referred to as a 'box', provides the simplest form of heap allocation in +//! Rust. Boxes provide ownership for this allocation, and drop their contents when they go out of +//! scope. +//! +//! Boxes are useful in two situations: recursive data structures, and occasionally when returning +//! data. [The Pointer chapter of the Book](../../../book/pointers.html#best-practices-1) explains +//! these cases in detail. +//! +//! # Examples +//! +//! Creating a box: +//! +//! ``` +//! let x = Box::new(5); +//! ``` +//! +//! Creating a recursive data structure: +//! +//! ``` +//! #[derive(Show)] +//! enum List<T> { +//! Cons(T, Box<List<T>>), +//! Nil, +//! } +//! +//! fn main() { +//! let list: List<i32> = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil)))); +//! println!("{:?}", list); +//! } +//! ``` +//! +//! This will print `Cons(1i32, Box(Cons(2i32, Box(Nil))))`. #![stable] @@ -29,8 +62,8 @@ use core::raw::TraitObject; use core::result::Result::{Ok, Err}; use core::result::Result; -/// A value that represents the global exchange heap. This is the default -/// place that the `box` keyword allocates into when no place is supplied. +/// A value that represents the heap. This is the default place that the `box` keyword allocates +/// into when no place is supplied. /// /// The following two examples are equivalent: /// @@ -39,23 +72,29 @@ use core::result::Result; /// use std::boxed::HEAP; /// /// fn main() { -/// # struct Bar; -/// # impl Bar { fn new(_a: int) { } } -/// let foo = box(HEAP) Bar::new(2); -/// let foo = box Bar::new(2); +/// let foo = box(HEAP) 5; +/// let foo = box 5; /// } /// ``` #[lang = "exchange_heap"] #[unstable = "may be renamed; uncertain about custom allocator design"] pub static HEAP: () = (); -/// A type that represents a uniquely-owned value. +/// A pointer type for heap allocation. +/// +/// See the [module-level documentation](../../std/boxed/index.html) for more. #[lang = "owned_box"] #[stable] pub struct Box<T>(Unique<T>); impl<T> Box<T> { - /// Moves `x` into a freshly allocated box on the global exchange heap. + /// Allocates memory on the heap and then moves `x` into it. + /// + /// # Examples + /// + /// ``` + /// let x = Box::new(5); + /// ``` #[stable] pub fn new(x: T) -> Box<T> { box x @@ -76,11 +115,29 @@ impl<T> Default for Box<[T]> { #[stable] impl<T: Clone> Clone for Box<T> { - /// Returns a copy of the owned box. + /// Returns a new box with a `clone()` of this box's contents. + /// + /// # Examples + /// + /// ``` + /// let x = Box::new(5); + /// let y = x.clone(); + /// ``` #[inline] fn clone(&self) -> Box<T> { box {(**self).clone()} } - /// Performs copy-assignment from `source` by reusing the existing allocation. + /// Copies `source`'s contents into `self` without creating a new allocation. + /// + /// # Examples + /// + /// ``` + /// let x = Box::new(5); + /// let mut y = Box::new(10); + /// + /// y.clone_from(&x); + /// + /// assert_eq!(*y, 5); + /// ``` #[inline] fn clone_from(&mut self, source: &Box<T>) { (**self).clone_from(&(**source)); diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 8c7f79d4d78..f65802de5ac 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -967,11 +967,30 @@ impl<T> SliceExt for [T] { /// An extension trait for concatenating slices pub trait SliceConcatExt<T: ?Sized, U> { /// Flattens a slice of `T` into a single value `U`. + /// + /// # Examples + /// + /// ``` + /// let v = vec!["hello", "world"]; + /// + /// let s: String = v.concat(); + /// + /// println!("{}", s); // prints "helloworld" + /// ``` #[stable] fn concat(&self) -> U; - /// Flattens a slice of `T` into a single value `U`, placing a - /// given separator between each. + /// Flattens a slice of `T` into a single value `U`, placing a given separator between each. + /// + /// # Examples + /// + /// ``` + /// let v = vec!["hello", "world"]; + /// + /// let s: String = v.connect(" "); + /// + /// println!("{}", s); // prints "hello world" + /// ``` #[stable] fn connect(&self, sep: &T) -> U; } diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 963cb48db07..7f73be9eb5f 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -74,6 +74,10 @@ //! } //! ``` //! +//! Note that this example uses `Rc<T>` and not `Arc<T>`. `RefCell<T>`s are for single-threaded +//! scenarios. Consider using `Mutex<T>` if you need shared mutability in a multi-threaded +//! situation. +//! //! ## Implementation details of logically-immutable methods //! //! Occasionally it may be desirable not to expose in an API that diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 677a5f37a1b..a07fd61cd8c 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -555,7 +555,8 @@ pub mod types { pub type mode_t = u16; pub type ssize_t = i32; } - #[cfg(target_arch = "x86")] + #[cfg(any(target_arch = "x86", + target_arch = "powerpc"))] pub mod posix01 { use types::os::arch::c95::{c_short, c_long, time_t}; use types::os::arch::posix88::{dev_t, gid_t, ino_t}; @@ -646,8 +647,7 @@ pub mod types { } } #[cfg(any(target_arch = "mips", - target_arch = "mipsel", - target_arch = "powerpc"))] + target_arch = "mipsel"))] pub mod posix01 { use types::os::arch::c95::{c_long, c_ulong, time_t}; use types::os::arch::posix88::{gid_t, ino_t}; @@ -2491,7 +2491,8 @@ pub mod consts { #[cfg(any(target_arch = "x86", target_arch = "x86_64", target_arch = "arm", - target_arch = "aarch64"))] + target_arch = "aarch64", + target_arch = "powerpc"))] pub mod posix88 { use types::os::arch::c95::c_int; use types::common::c95::c_void; @@ -2704,8 +2705,7 @@ pub mod consts { } #[cfg(any(target_arch = "mips", - target_arch = "mipsel", - target_arch = "powerpc"))] + target_arch = "mipsel"))] pub mod posix88 { use types::os::arch::c95::c_int; use types::common::c95::c_void; @@ -3002,7 +3002,8 @@ pub mod consts { #[cfg(any(target_arch = "arm", target_arch = "aarch64", target_arch = "x86", - target_arch = "x86_64"))] + target_arch = "x86_64", + target_arch = "powerpc"))] pub mod bsd44 { use types::os::arch::c95::c_int; @@ -3050,8 +3051,7 @@ pub mod consts { pub const SHUT_RDWR: c_int = 2; } #[cfg(any(target_arch = "mips", - target_arch = "mipsel", - target_arch = "powerpc"))] + target_arch = "mipsel"))] pub mod bsd44 { use types::os::arch::c95::c_int; @@ -3099,7 +3099,8 @@ pub mod consts { #[cfg(any(target_arch = "x86", target_arch = "x86_64", target_arch = "arm", - target_arch = "aarch64"))] + target_arch = "aarch64", + target_arch = "powerpc"))] pub mod extra { use types::os::arch::c95::c_int; @@ -3127,8 +3128,7 @@ pub mod consts { pub const MAP_STACK : c_int = 0x020000; } #[cfg(any(target_arch = "mips", - target_arch = "mipsel", - target_arch = "powerpc"))] + target_arch = "mipsel"))] pub mod extra { use types::os::arch::c95::c_int; diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 9df1b236fe8..39413d63482 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -2088,7 +2088,13 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, unique_type_id, containing_scope); - let fields = ty::struct_fields(cx.tcx(), def_id, substs); + let mut fields = ty::struct_fields(cx.tcx(), def_id, substs); + + // The `Ty` values returned by `ty::struct_fields` can still contain + // `ty_projection` variants, so normalize those away. + for field in fields.iter_mut() { + field.mt.ty = monomorphize::normalize_associated_type(cx.tcx(), &field.mt.ty); + } create_and_register_recursive_type_forward_declaration( cx, diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index f085fd259de..21bea5dcdcb 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -49,8 +49,8 @@ //! * You want a double-ended queue (deque). //! //! ### Use a `DList` when: -//! * You want a `Vec` or `RingBuf` of unknown size, and can't tolerate inconsistent -//! performance during insertions. +//! * You want a `Vec` or `RingBuf` of unknown size, and can't tolerate amortization. +//! * You want to efficiently split and append lists. //! * You are *absolutely* certain you *really*, *truly*, want a doubly linked list. //! //! ### Use a `HashMap` when: @@ -85,6 +85,56 @@ //! or "most important" one at any given time. //! * You want a priority queue. //! +//! # Performance +//! +//! Choosing the right collection for the job requires an understanding of what each collection +//! is good at. Here we briefly summarize the performance of different collections for certain +//! important operations. For further details, see each type's documentation. +//! +//! Throughout the documentation, we will follow a few conventions. For all operations, +//! the collection's size is denoted by n. If another collection is involved in the operation, it +//! contains m elements. Operations which have an *amortized* cost are suffixed with a `*`. +//! Operations with an *expected* cost are suffixed with a `~`. +//! +//! All amortized costs are for the potential need to resize when capacity is exhausted. +//! If a resize occurs it will take O(n) time. Our collections never automatically shrink, +//! so removal operations aren't amortized. Over a sufficiently large series of +//! operations, the average cost per operation will deterministically equal the given cost. +//! +//! Only HashMap has expected costs, due to the probabilistic nature of hashing. It is +//! theoretically possible, though very unlikely, for HashMap to experience worse performance. +//! +//! ## Sequences +//! +//! | | get(i) | insert(i) | remove(i) | append | split_off(i) | +//! |---------|----------------|-----------------|----------------|--------|----------------| +//! | Vec | O(1) | O(n-i)* | O(n-i) | O(m)* | O(n-i) | +//! | RingBuf | O(1) | O(min(i, n-i))* | O(min(i, n-i)) | O(m)* | O(min(i, n-i)) | +//! | DList | O(min(i, n-i)) | O(min(i, n-i)) | O(min(i, n-i)) | O(1) | O(min(i, n-i)) | +//! | Bitv | O(1) | O(n-i)* | O(n-i) | O(m)* | O(n-i) | +//! +//! Note that where ties occur, Vec is generally going to be faster than RingBuf, and RingBuf +//! is generally going to be faster than DList. Bitv is not a general purpose collection, and +//! therefore cannot reasonably be compared. +//! +//! ## Maps +//! +//! For Sets, all operations have the cost of the equivalent Map operation. For BitvSet, +//! refer to VecMap. +//! +//! | | get | insert | remove | predecessor | +//! |----------|-----------|----------|----------|-------------| +//! | HashMap | O(1)~ | O(1)~* | O(1)~ | N/A | +//! | BTreeMap | O(log n) | O(log n) | O(log n) | O(log n) | +//! | VecMap | O(1) | O(1)? | O(1) | O(n) | +//! +//! Note that VecMap is *incredibly* inefficient in terms of space. The O(1) insertion time +//! assumes space for the element is already allocated. Otherwise, a large key may require a +//! massive reallocation, with no direct relation to the number of elements in the collection. +//! VecMap should only be seriously considered for small keys. +//! +//! Note also that BTreeMap's precise preformance depends on the value of B. +//! //! # Correct and Efficient Usage of Collections //! //! Of course, knowing which collection is the right one for the job doesn't instantly diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs index 73b8f104c23..b313a5312bc 100644 --- a/src/libstd/rt/unwind.rs +++ b/src/libstd/rt/unwind.rs @@ -152,7 +152,7 @@ pub unsafe fn try<F: FnOnce()>(f: F) -> Result<(), Box<Any + Send>> { } } -/// Test if the current thread is currently panicking. +/// Determines whether the current thread is unwinding because of panic. pub fn panicking() -> bool { PANICKING.with(|s| s.get()) } diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs index 35d305466b5..8cc2cac33ec 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -130,7 +130,15 @@ pub struct RwLockWriteGuard<'a, T: 'a> { impl<'a, T> !marker::Send for RwLockWriteGuard<'a, T> {} impl<T: Send + Sync> RwLock<T> { - /// Creates a new instance of an RwLock which is unlocked and read to go. + /// Creates a new instance of an `RwLock<T>` which is unlocked. + /// + /// # Examples + /// + /// ``` + /// use std::sync::RwLock; + /// + /// let lock = RwLock::new(5); + /// ``` #[stable] pub fn new(t: T) -> RwLock<T> { RwLock { inner: box RW_LOCK_INIT, data: UnsafeCell::new(t) } diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs index 1f181e1fa2a..a86b82b8c62 100644 --- a/src/libstd/thread.rs +++ b/src/libstd/thread.rs @@ -382,7 +382,7 @@ impl Thread { unsafe { imp::yield_now() } } - /// Determines whether the current thread is panicking. + /// Determines whether the current thread is unwinding because of panic. #[inline] #[stable] pub fn panicking() -> bool { diff --git a/src/test/debuginfo/associated-types.rs b/src/test/debuginfo/associated-types.rs new file mode 100644 index 00000000000..6a624e39e32 --- /dev/null +++ b/src/test/debuginfo/associated-types.rs @@ -0,0 +1,152 @@ +// Copyright 2013-2014 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. + +// ignore-android: FIXME(#10381) +// min-lldb-version: 310 + +// compile-flags:-g + +// === GDB TESTS =================================================================================== +// gdb-command:run + +// gdb-command:print arg +// gdb-check:$1 = {b = -1, b1 = 0} +// gdb-command:continue + +// gdb-command:print inferred +// gdb-check:$2 = 1 +// gdb-command:print explicitly +// gdb-check:$3 = 1 +// gdb-command:continue + +// gdb-command:print arg +// gdb-check:$4 = 2 +// gdb-command:continue + +// gdb-command:print arg +// gdb-check:$5 = {4, 5} +// gdb-command:continue + +// gdb-command:print a +// gdb-check:$6 = 6 +// gdb-command:print b +// gdb-check:$7 = 7 +// gdb-command:continue + +// gdb-command:print a +// gdb-check:$8 = 8 +// gdb-command:print b +// gdb-check:$9 = 9 +// gdb-command:continue + +// === LLDB TESTS ================================================================================== +// lldb-command:run + +// lldb-command:print arg +// lldb-check:[...]$0 = Struct<i32> { b: -1, b1: 0 } +// lldb-command:continue + +// lldb-command:print inferred +// lldb-check:[...]$1 = 1 +// lldb-command:print explicitly +// lldb-check:[...]$2 = 1 +// lldb-command:continue + +// lldb-command:print arg +// lldb-check:[...]$3 = 2 +// lldb-command:continue + +// lldb-command:print arg +// lldb-check:[...]$4 = (4, 5) +// lldb-command:continue + +// lldb-command:print a +// lldb-check:[...]$5 = 6 +// lldb-command:print b +// lldb-check:[...]$6 = 7 +// lldb-command:continue + +// lldb-command:print a +// lldb-check:[...]$7 = 8 +// lldb-command:print b +// lldb-check:[...]$8 = 9 +// lldb-command:continue + +#![allow(unused_variables)] +#![allow(dead_code)] +#![omit_gdb_pretty_printer_section] + +trait TraitWithAssocType { + type Type; + + fn get_value(&self) -> Self::Type; +} +impl TraitWithAssocType for i32 { + type Type = i64; + + fn get_value(&self) -> i64 { *self as i64 } +} + +struct Struct<T: TraitWithAssocType> { + b: T, + b1: T::Type, +} + +enum Enum<T: TraitWithAssocType> { + Variant1(T, T::Type), + Variant2(T::Type, T) +} + +fn assoc_struct<T: TraitWithAssocType>(arg: Struct<T>) { + zzz(); // #break +} + +fn assoc_local<T: TraitWithAssocType>(x: T) { + let inferred = x.get_value(); + let explicitly: T::Type = x.get_value(); + + zzz(); // #break +} + +fn assoc_arg<T: TraitWithAssocType>(arg: T::Type) { + zzz(); // #break +} + +fn assoc_return_value<T: TraitWithAssocType>(arg: T) -> T::Type { + return arg.get_value(); +} + +fn assoc_tuple<T: TraitWithAssocType>(arg: (T, T::Type)) { + zzz(); // #break +} + +fn assoc_enum<T: TraitWithAssocType>(arg: Enum<T>) { + + match arg { + Enum::Variant1(a, b) => { + zzz(); // #break + } + Enum::Variant2(a, b) => { + zzz(); // #break + } + } +} + +fn main() { + assoc_struct(Struct { b: -1i32, b1: 0i64 }); + assoc_local(1i32); + assoc_arg::<i32>(2i64); + assoc_return_value(3i32); + assoc_tuple((4i32, 5i64)); + assoc_enum(Enum::Variant1(6i32, 7i64)); + assoc_enum(Enum::Variant2(8i64, 9i32)); +} + +fn zzz() { () } \ No newline at end of file |
