Auto merge of #60888 - Manishearth:rollup-oihtoyq, r=Manishearth
Rollup of 5 pull requests Successful merges: - #60207 (Outdent example, preserving nested fence) - #60278 (Document the `html_root_url` doc attribute value.) - #60597 (Do some simple constant propagation in the ConstProp pass) - #60837 (Update release notes for 1.35.0) - #60887 (Update clippy) Failed merges: r? @ghost
This commit is contained in:
commit
4f53b5c42b
100
RELEASES.md
100
RELEASES.md
@ -1,10 +1,108 @@
|
||||
Version 1.35.0 (2019-05-23)
|
||||
==========================
|
||||
|
||||
Language
|
||||
--------
|
||||
- [`FnOnce`, `FnMut`, and the `Fn` traits are now implemented for `Box<FnOnce>`,
|
||||
`Box<FnMut>`, and `Box<Fn>` respectively.][59500]
|
||||
- [You can now coerce closures into unsafe function pointers.][59580] e.g.
|
||||
```rust
|
||||
unsafe fn call_unsafe(func: unsafe fn()) {
|
||||
func()
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
unsafe { call_unsafe(|| {}); }
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Compiler
|
||||
--------
|
||||
- [Added the `armv6-unknown-freebsd-gnueabihf` and
|
||||
`armv7-unknown-freebsd-gnueabihf` targets.][58080]
|
||||
- [Added the `wasm32-unknown-wasi` target.][59464]
|
||||
|
||||
|
||||
Libraries
|
||||
---------
|
||||
- [`Thread` will now show its ID in `Debug` output.][59460]
|
||||
- [`StdinLock`, `StdoutLock`, and `StderrLock` now implement `AsRawFd`.][59512]
|
||||
- [`alloc::System` now implements `Default`.][59451]
|
||||
- [Expanded `Debug` output (`{:#?}`) for structs now has a trailing comma on the
|
||||
last field.][59076]
|
||||
- [`char::{ToLowercase, ToUppercase}` now
|
||||
implement `ExactSizeIterator`.][58778]
|
||||
- [All `NonZero` numeric types now implement `FromStr`.][58717]
|
||||
- [Removed the `Read` trait bounds
|
||||
on the `BufReader::{get_ref, get_mut, into_inner}` methods.][58423]
|
||||
- [You can now call the `dbg!` macro without any parameters to print the file
|
||||
and line where it is called.][57847]
|
||||
- [In place ASCII case conversions are now up to 4× faster.][59283]
|
||||
e.g. `str::make_ascii_lowercase`
|
||||
- [`hash_map::{OccupiedEntry, VacantEntry}` now implement `Sync`
|
||||
and `Send`.][58369]
|
||||
|
||||
Stabilized APIs
|
||||
---------------
|
||||
- [`f32::copysign`]
|
||||
- [`f64::copysign`]
|
||||
- [`RefCell::replace_with`]
|
||||
- [`RefCell::map_split`]
|
||||
- [`ptr::hash`]
|
||||
- [`Range::contains`]
|
||||
- [`RangeFrom::contains`]
|
||||
- [`RangeTo::contains`]
|
||||
- [`RangeInclusive::contains`]
|
||||
- [`RangeToInclusive::contains`]
|
||||
- [`Option::copied`]
|
||||
|
||||
Cargo
|
||||
-----
|
||||
- [You can now set `cargo:rustc-cdylib-link-arg` at build time to pass custom
|
||||
linker arguments when building a `cdylib`.][cargo/6298] Its usage is highly
|
||||
platform specific.
|
||||
|
||||
Misc
|
||||
----
|
||||
- [The Rust toolchain is now available natively for musl based distros.][58575]
|
||||
|
||||
[59460]: https://github.com/rust-lang/rust/pull/59460/
|
||||
[59464]: https://github.com/rust-lang/rust/pull/59464/
|
||||
[59500]: https://github.com/rust-lang/rust/pull/59500/
|
||||
[59512]: https://github.com/rust-lang/rust/pull/59512/
|
||||
[59580]: https://github.com/rust-lang/rust/pull/59580/
|
||||
[59283]: https://github.com/rust-lang/rust/pull/59283/
|
||||
[59451]: https://github.com/rust-lang/rust/pull/59451/
|
||||
[59076]: https://github.com/rust-lang/rust/pull/59076/
|
||||
[58778]: https://github.com/rust-lang/rust/pull/58778/
|
||||
[58717]: https://github.com/rust-lang/rust/pull/58717/
|
||||
[58369]: https://github.com/rust-lang/rust/pull/58369/
|
||||
[58423]: https://github.com/rust-lang/rust/pull/58423/
|
||||
[58080]: https://github.com/rust-lang/rust/pull/58080/
|
||||
[57847]: https://github.com/rust-lang/rust/pull/57847/
|
||||
[58575]: https://github.com/rust-lang/rust/pull/58575
|
||||
[cargo/6298]: https://github.com/rust-lang/cargo/pull/6298/
|
||||
[`f32::copysign`]: https://doc.rust-lang.org/stable/std/primitive.f32.html#method.copysign
|
||||
[`f64::copysign`]: https://doc.rust-lang.org/stable/std/primitive.f64.html#method.copysign
|
||||
[`RefCell::replace_with`]: https://doc.rust-lang.org/stable/std/cell/struct.RefCell.html#method.replace_with
|
||||
[`RefCell::map_split`]: https://doc.rust-lang.org/stable/std/cell/struct.RefCell.html#method.map_split
|
||||
[`ptr::hash`]: https://doc.rust-lang.org/stable/std/ptr/fn.hash.html
|
||||
[`Range::contains`]: https://doc.rust-lang.org/std/ops/struct.Range.html#method.contains
|
||||
[`RangeFrom::contains`]: https://doc.rust-lang.org/std/ops/struct.RangeFrom.html#method.contains
|
||||
[`RangeTo::contains`]: https://doc.rust-lang.org/std/ops/struct.RangeTo.html#method.contains
|
||||
[`RangeInclusive::contains`]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html#method.contains
|
||||
[`RangeToInclusive::contains`]: https://doc.rust-lang.org/std/ops/struct.RangeToInclusive.html#method.contains
|
||||
[`Option::copied`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.copied
|
||||
|
||||
Version 1.34.2 (2019-05-14)
|
||||
===========================
|
||||
|
||||
* [Destabilize the `Error::type_id` function due to a security
|
||||
vulnerability][60785]
|
||||
vulnerability][60785] ([CVE-2019-12083])
|
||||
|
||||
[60785]: https://github.com/rust-lang/rust/pull/60785
|
||||
[CVE-2019-12083]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12083
|
||||
|
||||
Version 1.34.1 (2019-04-25)
|
||||
===========================
|
||||
|
@ -92,6 +92,21 @@ the tracking issue.
|
||||
#![doc(issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")]
|
||||
```
|
||||
|
||||
### `html_root_url`
|
||||
|
||||
The `#[doc(html_root_url = "…")]` attribute value indicates the URL for
|
||||
generating links to external crates. When rustdoc needs to generate a link to
|
||||
an item in an external crate, it will first check if the extern crate has been
|
||||
documented locally on-disk, and if so link directly to it. Failing that, it
|
||||
will use the URL given by the `--extern-html-root-url` command-line flag if
|
||||
available. If that is not available, then it will use the `html_root_url`
|
||||
value in the extern crate if it is available. If that is not available, then
|
||||
the extern items will not be linked.
|
||||
|
||||
```rust,ignore
|
||||
#![doc(html_root_url = "https://docs.rs/serde/1.0")]
|
||||
```
|
||||
|
||||
### `html_no_source`
|
||||
|
||||
By default, `rustdoc` will include the source code of your program, with links
|
||||
|
@ -98,21 +98,21 @@ documentation for them as well!
|
||||
`rustdoc` can also generate HTML from standalone Markdown files. Let's
|
||||
give it a try: create a `README.md` file with these contents:
|
||||
|
||||
```text
|
||||
# Docs
|
||||
````text
|
||||
# Docs
|
||||
|
||||
This is a project to test out `rustdoc`.
|
||||
This is a project to test out `rustdoc`.
|
||||
|
||||
[Here is a link!](https://www.rust-lang.org)
|
||||
[Here is a link!](https://www.rust-lang.org)
|
||||
|
||||
## Subheading
|
||||
## Subheading
|
||||
|
||||
```rust
|
||||
fn foo() -> i32 {
|
||||
1 + 1
|
||||
}
|
||||
```
|
||||
```rust
|
||||
fn foo() -> i32 {
|
||||
1 + 1
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
And call `rustdoc` on it:
|
||||
|
||||
|
@ -3,15 +3,17 @@
|
||||
|
||||
use rustc::hir::def::DefKind;
|
||||
use rustc::mir::{
|
||||
Constant, Location, Place, PlaceBase, Mir, Operand, Rvalue, Local,
|
||||
AggregateKind, Constant, Location, Place, PlaceBase, Mir, Operand, Rvalue, Local,
|
||||
NullOp, UnOp, StatementKind, Statement, LocalKind, Static, StaticKind,
|
||||
TerminatorKind, Terminator, ClearCrossCrate, SourceInfo, BinOp, ProjectionElem,
|
||||
SourceScope, SourceScopeLocalData, LocalDecl, Promoted,
|
||||
};
|
||||
use rustc::mir::visit::{Visitor, PlaceContext, MutatingUseContext, NonMutatingUseContext};
|
||||
use rustc::mir::visit::{
|
||||
Visitor, PlaceContext, MutatingUseContext, MutVisitor, NonMutatingUseContext,
|
||||
};
|
||||
use rustc::mir::interpret::{InterpError, Scalar, GlobalId, EvalResult};
|
||||
use rustc::ty::{self, Instance, ParamEnv, Ty, TyCtxt};
|
||||
use syntax::source_map::DUMMY_SP;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
use rustc::ty::subst::InternalSubsts;
|
||||
use rustc_data_structures::indexed_vec::IndexVec;
|
||||
use rustc::ty::layout::{
|
||||
@ -19,7 +21,7 @@ use rustc::ty::layout::{
|
||||
HasTyCtxt, TargetDataLayout, HasDataLayout,
|
||||
};
|
||||
|
||||
use crate::interpret::{InterpretCx, ScalarMaybeUndef, Immediate, OpTy, ImmTy, MemoryKind};
|
||||
use crate::interpret::{self, InterpretCx, ScalarMaybeUndef, Immediate, OpTy, ImmTy, MemoryKind};
|
||||
use crate::const_eval::{
|
||||
CompileTimeInterpreter, error_to_const_error, eval_promoted, mk_eval_cx,
|
||||
};
|
||||
@ -497,6 +499,53 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn operand_from_scalar(&self, scalar: Scalar, ty: Ty<'tcx>, span: Span) -> Operand<'tcx> {
|
||||
Operand::Constant(Box::new(
|
||||
Constant {
|
||||
span,
|
||||
ty,
|
||||
user_ty: None,
|
||||
literal: self.tcx.mk_const(ty::Const::from_scalar(
|
||||
scalar,
|
||||
ty,
|
||||
))
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
fn replace_with_const(&self, rval: &mut Rvalue<'tcx>, value: Const<'tcx>, span: Span) {
|
||||
self.ecx.validate_operand(
|
||||
value,
|
||||
vec![],
|
||||
None,
|
||||
true,
|
||||
).expect("value should already be a valid const");
|
||||
|
||||
if let interpret::Operand::Immediate(im) = *value {
|
||||
match im {
|
||||
interpret::Immediate::Scalar(ScalarMaybeUndef::Scalar(scalar)) => {
|
||||
*rval = Rvalue::Use(self.operand_from_scalar(scalar, value.layout.ty, span));
|
||||
},
|
||||
Immediate::ScalarPair(
|
||||
ScalarMaybeUndef::Scalar(one),
|
||||
ScalarMaybeUndef::Scalar(two)
|
||||
) => {
|
||||
let ty = &value.layout.ty.sty;
|
||||
if let ty::Tuple(substs) = ty {
|
||||
*rval = Rvalue::Aggregate(
|
||||
Box::new(AggregateKind::Tuple),
|
||||
vec![
|
||||
self.operand_from_scalar(one, substs[0].expect_ty(), span),
|
||||
self.operand_from_scalar(two, substs[1].expect_ty(), span),
|
||||
],
|
||||
);
|
||||
}
|
||||
},
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn type_size_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
@ -560,10 +609,10 @@ impl<'tcx> Visitor<'tcx> for CanConstProp {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
|
||||
impl<'b, 'a, 'tcx> MutVisitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
|
||||
fn visit_constant(
|
||||
&mut self,
|
||||
constant: &Constant<'tcx>,
|
||||
constant: &mut Constant<'tcx>,
|
||||
location: Location,
|
||||
) {
|
||||
trace!("visit_constant: {:?}", constant);
|
||||
@ -573,11 +622,11 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
|
||||
|
||||
fn visit_statement(
|
||||
&mut self,
|
||||
statement: &Statement<'tcx>,
|
||||
statement: &mut Statement<'tcx>,
|
||||
location: Location,
|
||||
) {
|
||||
trace!("visit_statement: {:?}", statement);
|
||||
if let StatementKind::Assign(ref place, ref rval) = statement.kind {
|
||||
if let StatementKind::Assign(ref place, ref mut rval) = statement.kind {
|
||||
let place_ty: Ty<'tcx> = place
|
||||
.ty(&self.local_decls, self.tcx)
|
||||
.ty;
|
||||
@ -589,6 +638,10 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
|
||||
trace!("storing {:?} to {:?}", value, local);
|
||||
assert!(self.places[local].is_none());
|
||||
self.places[local] = Some(value);
|
||||
|
||||
if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2 {
|
||||
self.replace_with_const(rval, value, statement.source_info.span);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -599,7 +652,7 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
|
||||
|
||||
fn visit_terminator(
|
||||
&mut self,
|
||||
terminator: &Terminator<'tcx>,
|
||||
terminator: &mut Terminator<'tcx>,
|
||||
location: Location,
|
||||
) {
|
||||
self.super_terminator(terminator, location);
|
||||
|
33
src/test/mir-opt/const_prop/array_index.rs
Normal file
33
src/test/mir-opt/const_prop/array_index.rs
Normal file
@ -0,0 +1,33 @@
|
||||
fn main() {
|
||||
let x: u32 = [0, 1, 2, 3][2];
|
||||
}
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.main.ConstProp.before.mir
|
||||
// bb0: {
|
||||
// ...
|
||||
// _2 = [const 0u32, const 1u32, const 2u32, const 3u32];
|
||||
// ...
|
||||
// _3 = const 2usize;
|
||||
// _4 = const 4usize;
|
||||
// _5 = Lt(_3, _4);
|
||||
// assert(move _5, "index out of bounds: the len is move _4 but the index is _3") -> bb1;
|
||||
// }
|
||||
// bb1: {
|
||||
// _1 = _2[_3];
|
||||
// ...
|
||||
// return;
|
||||
// }
|
||||
// END rustc.main.ConstProp.before.mir
|
||||
// START rustc.main.ConstProp.after.mir
|
||||
// bb0: {
|
||||
// ...
|
||||
// _5 = const true;
|
||||
// assert(move _5, "index out of bounds: the len is move _4 but the index is _3") -> bb1;
|
||||
// }
|
||||
// bb1: {
|
||||
// _1 = _2[_3];
|
||||
// ...
|
||||
// return;
|
||||
// }
|
||||
// END rustc.main.ConstProp.after.mir
|
21
src/test/mir-opt/const_prop/checked_add.rs
Normal file
21
src/test/mir-opt/const_prop/checked_add.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// compile-flags: -C overflow-checks=on
|
||||
|
||||
fn main() {
|
||||
let x: u32 = 1 + 1;
|
||||
}
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.main.ConstProp.before.mir
|
||||
// bb0: {
|
||||
// ...
|
||||
// _2 = CheckedAdd(const 1u32, const 1u32);
|
||||
// assert(!move (_2.1: bool), "attempt to add with overflow") -> bb1;
|
||||
// }
|
||||
// END rustc.main.ConstProp.before.mir
|
||||
// START rustc.main.ConstProp.after.mir
|
||||
// bb0: {
|
||||
// ...
|
||||
// _2 = (const 2u32, const false);
|
||||
// assert(!move (_2.1: bool), "attempt to add with overflow") -> bb1;
|
||||
// }
|
||||
// END rustc.main.ConstProp.after.mir
|
34
src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs
Normal file
34
src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs
Normal file
@ -0,0 +1,34 @@
|
||||
#[inline(never)]
|
||||
fn read(_: usize) { }
|
||||
|
||||
fn main() {
|
||||
const FOO: &i32 = &1;
|
||||
let x = FOO as *const i32 as usize;
|
||||
read(x);
|
||||
}
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.main.ConstProp.before.mir
|
||||
// bb0: {
|
||||
// ...
|
||||
// _3 = _4;
|
||||
// _2 = move _3 as *const i32 (Misc);
|
||||
// ...
|
||||
// _1 = move _2 as usize (Misc);
|
||||
// ...
|
||||
// _6 = _1;
|
||||
// _5 = const read(move _6) -> bb1;
|
||||
// }
|
||||
// END rustc.main.ConstProp.before.mir
|
||||
// START rustc.main.ConstProp.after.mir
|
||||
// bb0: {
|
||||
// ...
|
||||
// _3 = _4;
|
||||
// _2 = move _3 as *const i32 (Misc);
|
||||
// ...
|
||||
// _1 = move _2 as usize (Misc);
|
||||
// ...
|
||||
// _6 = _1;
|
||||
// _5 = const read(move _6) -> bb1;
|
||||
// }
|
||||
// END rustc.main.ConstProp.after.mir
|
37
src/test/mir-opt/const_prop/slice_len.rs
Normal file
37
src/test/mir-opt/const_prop/slice_len.rs
Normal file
@ -0,0 +1,37 @@
|
||||
fn test() -> &'static [u32] {
|
||||
&[1, 2]
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = test()[0];
|
||||
}
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.main.ConstProp.before.mir
|
||||
// bb1: {
|
||||
// ...
|
||||
// _3 = const 0usize;
|
||||
// _4 = Len((*_2));
|
||||
// _5 = Lt(_3, _4);
|
||||
// assert(move _5, "index out of bounds: the len is move _4 but the index is _3") -> bb2;
|
||||
// }
|
||||
// bb2: {
|
||||
// _1 = (*_2)[_3];
|
||||
// ...
|
||||
// return;
|
||||
// }
|
||||
// END rustc.main.ConstProp.before.mir
|
||||
// START rustc.main.ConstProp.after.mir
|
||||
// bb0: {
|
||||
// ...
|
||||
// _3 = const 0usize;
|
||||
// _4 = Len((*_2));
|
||||
// _5 = Lt(_3, _4);
|
||||
// assert(move _5, "index out of bounds: the len is move _4 but the index is _3") -> bb2;
|
||||
// }
|
||||
// bb2: {
|
||||
// _1 = (*_2)[_3];
|
||||
// ...
|
||||
// return;
|
||||
// }
|
||||
// END rustc.main.ConstProp.after.mir
|
@ -1 +1 @@
|
||||
Subproject commit ad3269c4b510b94b7c0082f4bb341bee6ed1eca4
|
||||
Subproject commit 11194e3d050f45ff002a775f451ff6222fcd5b2c
|
Loading…
Reference in New Issue
Block a user