From 4a15a256626d3a9e017a18bb60bf98b1a6358bd5 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Thu, 22 Oct 2020 10:32:41 +0200 Subject: [PATCH 01/21] min_const_generics: allow ty param in repeat expr --- compiler/rustc_resolve/src/late.rs | 88 +++++++++++++++---- .../issues/issue-62504.min.stderr | 20 +++-- .../ui/const-generics/issues/issue-62504.rs | 4 +- .../issues/issue-67739.min.stderr | 8 +- .../ui/const-generics/issues/issue-67739.rs | 3 +- .../min_const_generics/complex-expression.rs | 20 +++++ .../complex-expression.stderr | 44 ++++++++-- .../const-evaluatable-unchecked.rs | 22 +++++ .../const-evaluatable-unchecked.stderr | 21 +++++ 9 files changed, 192 insertions(+), 38 deletions(-) create mode 100644 src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs create mode 100644 src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 7517ab66170a2..d323aebe59798 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -57,6 +57,12 @@ enum PatternSource { FnParam, } +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +enum IsRepeatExpr { + No, + Yes, +} + impl PatternSource { fn descr(self) -> &'static str { match self { @@ -437,10 +443,8 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { self.resolve_block(block); } fn visit_anon_const(&mut self, constant: &'ast AnonConst) { - debug!("visit_anon_const {:?}", constant); - self.with_constant_rib(constant.value.is_potential_trivial_const_param(), |this| { - visit::walk_anon_const(this, constant); - }); + // We deal with repeat expressions explicitly in `resolve_expr`. + self.resolve_anon_const(constant, IsRepeatExpr::No); } fn visit_expr(&mut self, expr: &'ast Expr) { self.resolve_expr(expr, None); @@ -647,7 +651,11 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { if !check_ns(TypeNS) && check_ns(ValueNS) { // This must be equivalent to `visit_anon_const`, but we cannot call it // directly due to visitor lifetimes so we have to copy-paste some code. - self.with_constant_rib(true, |this| { + // + // Note that we might not be inside of an repeat expression here, + // but considering that `IsRepeatExpr` is only relevant for + // non-trivial constants this is doesn't matter. + self.with_constant_rib(IsRepeatExpr::No, true, |this| { this.smart_resolve_path( ty.id, qself.as_ref(), @@ -980,9 +988,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // // Type parameters can already be used and as associated consts are // not used as part of the type system, this is far less surprising. - this.with_constant_rib(true, |this| { - this.visit_expr(expr) - }); + this.with_constant_rib( + IsRepeatExpr::No, + true, + |this| this.visit_expr(expr), + ); } } AssocItemKind::Fn(_, _, generics, _) => { @@ -1023,7 +1033,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { self.with_item_rib(HasGenericParams::No, |this| { this.visit_ty(ty); if let Some(expr) = expr { - this.with_constant_rib(expr.is_potential_trivial_const_param(), |this| { + // We already forbid generic params because of the above item rib, + // so it doesn't matter whether this is a trivial constant. + this.with_constant_rib(IsRepeatExpr::No, true, |this| { this.visit_expr(expr) }); } @@ -1122,12 +1134,29 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { self.with_rib(ValueNS, kind, |this| this.with_rib(TypeNS, kind, f)) } - fn with_constant_rib(&mut self, trivial: bool, f: impl FnOnce(&mut Self)) { - debug!("with_constant_rib"); - self.with_rib(ValueNS, ConstantItemRibKind(trivial), |this| { - this.with_rib(TypeNS, ConstantItemRibKind(trivial), |this| { - this.with_label_rib(ConstantItemRibKind(trivial), f); - }) + // HACK(min_const_generics,const_evaluatable_unchecked): We + // want to keep allowing `[0; std::mem::size_of::<*mut T>()]` + // with a future compat lint for now. We do this by adding an + // additional special case for repeat expressions. + // + // Note that we intentionally still forbid `[0; N + 1]` during + // name resolution so that we don't extend the future + // compat lint to new cases. + fn with_constant_rib( + &mut self, + is_repeat: IsRepeatExpr, + is_trivial: bool, + f: impl FnOnce(&mut Self), + ) { + debug!("with_constant_rib: is_repeat={:?} is_trivial={}", is_repeat, is_trivial); + self.with_rib(ValueNS, ConstantItemRibKind(is_trivial), |this| { + this.with_rib( + TypeNS, + ConstantItemRibKind(is_repeat == IsRepeatExpr::Yes || is_trivial), + |this| { + this.with_label_rib(ConstantItemRibKind(is_trivial), f); + }, + ) }); } @@ -1272,9 +1301,17 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // // Type parameters can already be used and as associated consts are // not used as part of the type system, this is far less surprising. - this.with_constant_rib(true, |this| { - visit::walk_assoc_item(this, item, AssocCtxt::Impl) - }); + this.with_constant_rib( + IsRepeatExpr::No, + true, + |this| { + visit::walk_assoc_item( + this, + item, + AssocCtxt::Impl, + ) + }, + ); } AssocItemKind::Fn(_, _, generics, _) => { // We also need a new scope for the impl item type parameters. @@ -2199,6 +2236,17 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { debug!("(resolving block) leaving block"); } + fn resolve_anon_const(&mut self, constant: &'ast AnonConst, is_repeat: IsRepeatExpr) { + debug!("resolve_anon_const {:?} is_repeat: {:?}", constant, is_repeat); + self.with_constant_rib( + is_repeat, + constant.value.is_potential_trivial_const_param(), + |this| { + visit::walk_anon_const(this, constant); + }, + ); + } + fn resolve_expr(&mut self, expr: &'ast Expr, parent: Option<&'ast Expr>) { // First, record candidate traits for this expression if it could // result in the invocation of a method call. @@ -2322,6 +2370,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ExprKind::Async(..) | ExprKind::Closure(..) => { self.with_label_rib(ClosureOrAsyncRibKind, |this| visit::walk_expr(this, expr)); } + ExprKind::Repeat(ref elem, ref ct) => { + self.visit_expr(elem); + self.resolve_anon_const(ct, IsRepeatExpr::Yes); + } _ => { visit::walk_expr(self, expr); } diff --git a/src/test/ui/const-generics/issues/issue-62504.min.stderr b/src/test/ui/const-generics/issues/issue-62504.min.stderr index 8f794312834b2..865eaf7493267 100644 --- a/src/test/ui/const-generics/issues/issue-62504.min.stderr +++ b/src/test/ui/const-generics/issues/issue-62504.min.stderr @@ -1,14 +1,20 @@ -error: generic `Self` types are currently not permitted in anonymous constants +error[E0308]: mismatched types + --> $DIR/issue-62504.rs:19:21 + | +LL | ArrayHolder([0; Self::SIZE]) + | ^^^^^^^^^^^^^^^ expected `X`, found `Self::SIZE` + | + = note: expected array `[u32; X]` + found array `[u32; _]` + +error: constant expression depends on a generic parameter --> $DIR/issue-62504.rs:19:25 | LL | ArrayHolder([0; Self::SIZE]) | ^^^^^^^^^^ | -note: not a concrete type - --> $DIR/issue-62504.rs:17:22 - | -LL | impl ArrayHolder { - | ^^^^^^^^^^^^^^ + = note: this may fail depending on what value the parameter takes -error: aborting due to previous error +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/issues/issue-62504.rs b/src/test/ui/const-generics/issues/issue-62504.rs index 015f170f00d1c..5630962ff5376 100644 --- a/src/test/ui/const-generics/issues/issue-62504.rs +++ b/src/test/ui/const-generics/issues/issue-62504.rs @@ -17,8 +17,8 @@ struct ArrayHolder([u32; X]); impl ArrayHolder { pub const fn new() -> Self { ArrayHolder([0; Self::SIZE]) - //[full]~^ ERROR constant expression depends on a generic parameter - //[min]~^^ ERROR generic `Self` types are currently + //~^ ERROR constant expression depends on a generic parameter + //[min]~| ERROR mismatched types } } diff --git a/src/test/ui/const-generics/issues/issue-67739.min.stderr b/src/test/ui/const-generics/issues/issue-67739.min.stderr index 35d97c4624811..27a56b8eb02b2 100644 --- a/src/test/ui/const-generics/issues/issue-67739.min.stderr +++ b/src/test/ui/const-generics/issues/issue-67739.min.stderr @@ -1,10 +1,10 @@ -error: generic parameters may not be used in const operations - --> $DIR/issue-67739.rs:12:30 +error: constant expression depends on a generic parameter + --> $DIR/issue-67739.rs:12:15 | LL | [0u8; mem::size_of::()]; - | ^^^^^^^^^^^^^^^^ cannot perform const operation using `Self` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: type parameters may not be used in const expressions + = note: this may fail depending on what value the parameter takes error: aborting due to previous error diff --git a/src/test/ui/const-generics/issues/issue-67739.rs b/src/test/ui/const-generics/issues/issue-67739.rs index 21d13de22ebfc..0f5860f22fdd3 100644 --- a/src/test/ui/const-generics/issues/issue-67739.rs +++ b/src/test/ui/const-generics/issues/issue-67739.rs @@ -10,8 +10,7 @@ pub trait Trait { fn associated_size(&self) -> usize { [0u8; mem::size_of::()]; - //[full]~^ ERROR constant expression depends on a generic parameter - //[min]~^^ ERROR generic parameters may not be used in const operations + //~^ ERROR constant expression depends on a generic parameter 0 } } diff --git a/src/test/ui/const-generics/min_const_generics/complex-expression.rs b/src/test/ui/const-generics/min_const_generics/complex-expression.rs index 8257ffbf4915b..686ce98fcdff3 100644 --- a/src/test/ui/const-generics/min_const_generics/complex-expression.rs +++ b/src/test/ui/const-generics/min_const_generics/complex-expression.rs @@ -1,5 +1,7 @@ #![feature(min_const_generics)] +use std::mem::size_of; + fn test() {} fn ok() -> [u8; M] { @@ -22,6 +24,24 @@ fn break3() { //~^ ERROR generic parameters may not be used in const operations } +struct BreakTy0(T, [u8; { size_of::<*mut T>() }]); +//~^ ERROR generic parameters may not be used in const operations + +struct BreakTy1(T, [u8; { { size_of::<*mut T>() } }]); +//~^ ERROR generic parameters may not be used in const operations + +fn break_ty2() { + let _: [u8; size_of::<*mut T>() + 1]; + //~^ ERROR generic parameters may not be used in const operations +} + +fn break_ty3() { + let _ = [0; size_of::<*mut T>() + 1]; + //~^ WARN cannot use constants which depend on generic parameters in types + //~| WARN this was previously accepted by the compiler but is being phased out +} + + trait Foo { const ASSOC: usize; } diff --git a/src/test/ui/const-generics/min_const_generics/complex-expression.stderr b/src/test/ui/const-generics/min_const_generics/complex-expression.stderr index 73768ac03a4b1..a8de987e1675e 100644 --- a/src/test/ui/const-generics/min_const_generics/complex-expression.stderr +++ b/src/test/ui/const-generics/min_const_generics/complex-expression.stderr @@ -1,5 +1,5 @@ error: generic parameters may not be used in const operations - --> $DIR/complex-expression.rs:9:38 + --> $DIR/complex-expression.rs:11:38 | LL | struct Break0([u8; { N + 1 }]); | ^ cannot perform const operation using `N` @@ -7,7 +7,7 @@ LL | struct Break0([u8; { N + 1 }]); = help: const parameters may only be used as standalone arguments, i.e. `N` error: generic parameters may not be used in const operations - --> $DIR/complex-expression.rs:12:40 + --> $DIR/complex-expression.rs:14:40 | LL | struct Break1([u8; { { N } }]); | ^ cannot perform const operation using `N` @@ -15,7 +15,7 @@ LL | struct Break1([u8; { { N } }]); = help: const parameters may only be used as standalone arguments, i.e. `N` error: generic parameters may not be used in const operations - --> $DIR/complex-expression.rs:16:17 + --> $DIR/complex-expression.rs:18:17 | LL | let _: [u8; N + 1]; | ^ cannot perform const operation using `N` @@ -23,12 +23,46 @@ LL | let _: [u8; N + 1]; = help: const parameters may only be used as standalone arguments, i.e. `N` error: generic parameters may not be used in const operations - --> $DIR/complex-expression.rs:21:17 + --> $DIR/complex-expression.rs:23:17 | LL | let _ = [0; N + 1]; | ^ cannot perform const operation using `N` | = help: const parameters may only be used as standalone arguments, i.e. `N` -error: aborting due to 4 previous errors +error: generic parameters may not be used in const operations + --> $DIR/complex-expression.rs:27:45 + | +LL | struct BreakTy0(T, [u8; { size_of::<*mut T>() }]); + | ^ cannot perform const operation using `T` + | + = note: type parameters may not be used in const expressions + +error: generic parameters may not be used in const operations + --> $DIR/complex-expression.rs:30:47 + | +LL | struct BreakTy1(T, [u8; { { size_of::<*mut T>() } }]); + | ^ cannot perform const operation using `T` + | + = note: type parameters may not be used in const expressions + +error: generic parameters may not be used in const operations + --> $DIR/complex-expression.rs:34:32 + | +LL | let _: [u8; size_of::<*mut T>() + 1]; + | ^ cannot perform const operation using `T` + | + = note: type parameters may not be used in const expressions + +warning: cannot use constants which depend on generic parameters in types + --> $DIR/complex-expression.rs:39:17 + | +LL | let _ = [0; size_of::<*mut T>() + 1]; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(const_evaluatable_unchecked)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #76200 + +error: aborting due to 7 previous errors; 1 warning emitted diff --git a/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs new file mode 100644 index 0000000000000..4e99a098a34fe --- /dev/null +++ b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs @@ -0,0 +1,22 @@ +// check-pass +#![allow(dead_code)] + +fn foo() { + [0; std::mem::size_of::<*mut T>()]; + //~^ WARN cannot use constants which depend on generic parameters in types + //~| WARN this was previously accepted by the compiler but is being phased out +} + +struct Foo(T); + +impl Foo { + const ASSOC: usize = 4; + + fn test() { + [0; Self::ASSOC]; + //~^ WARN cannot use constants which depend on generic parameters in types + //~| WARN this was previously accepted by the compiler but is being phased out + } +} + +fn main() {} diff --git a/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr new file mode 100644 index 0000000000000..f493f0da040b9 --- /dev/null +++ b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr @@ -0,0 +1,21 @@ +warning: cannot use constants which depend on generic parameters in types + --> $DIR/const-evaluatable-unchecked.rs:5:9 + | +LL | [0; std::mem::size_of::<*mut T>()]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(const_evaluatable_unchecked)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #76200 + +warning: cannot use constants which depend on generic parameters in types + --> $DIR/const-evaluatable-unchecked.rs:16:13 + | +LL | [0; Self::ASSOC]; + | ^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #76200 + +warning: 2 warnings emitted + From 83ecbb4a294abca245f8c515e298464e9425b9a2 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Fri, 23 Oct 2020 22:08:21 +0200 Subject: [PATCH 02/21] add tests for self with const params --- compiler/rustc_hir/src/def.rs | 4 +++- .../const-evaluatable-unchecked.rs | 15 ++++++++++++++- .../const-evaluatable-unchecked.stderr | 19 ++++++++++++++----- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 62b1254287724..193247af584bb 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -206,8 +206,10 @@ pub enum Res { /// ```rust /// impl Foo { fn test() -> [u8; std::mem::size_of::()] {} } /// ``` + /// We do however allow `Self` in repeat expression even if it is generic to not break code + /// which already works on stable while causing the `const_evaluatable_unchecked` future compat lint. /// - /// FIXME(lazy_normalization_consts): Remove this bodge once this feature is stable. + /// FIXME(lazy_normalization_consts): Remove this bodge once that feature is stable. SelfTy(Option /* trait */, Option<(DefId, bool)> /* impl */), ToolMod, // e.g., `rustfmt` in `#[rustfmt::skip]` diff --git a/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs index 4e99a098a34fe..dd82be33a8e80 100644 --- a/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs +++ b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs @@ -1,4 +1,5 @@ // check-pass +#![feature(min_const_generics)] #![allow(dead_code)] fn foo() { @@ -13,7 +14,19 @@ impl Foo { const ASSOC: usize = 4; fn test() { - [0; Self::ASSOC]; + let _ = [0; Self::ASSOC]; + //~^ WARN cannot use constants which depend on generic parameters in types + //~| WARN this was previously accepted by the compiler but is being phased out + } +} + +struct Bar; + +impl Bar { + const ASSOC: usize = 4; + + fn test() { + let _ = [0; Self::ASSOC]; //~^ WARN cannot use constants which depend on generic parameters in types //~| WARN this was previously accepted by the compiler but is being phased out } diff --git a/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr index f493f0da040b9..4d0cab012f99e 100644 --- a/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr +++ b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr @@ -1,5 +1,5 @@ warning: cannot use constants which depend on generic parameters in types - --> $DIR/const-evaluatable-unchecked.rs:5:9 + --> $DIR/const-evaluatable-unchecked.rs:6:9 | LL | [0; std::mem::size_of::<*mut T>()]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,13 +9,22 @@ LL | [0; std::mem::size_of::<*mut T>()]; = note: for more information, see issue #76200 warning: cannot use constants which depend on generic parameters in types - --> $DIR/const-evaluatable-unchecked.rs:16:13 + --> $DIR/const-evaluatable-unchecked.rs:17:21 | -LL | [0; Self::ASSOC]; - | ^^^^^^^^^^^ +LL | let _ = [0; Self::ASSOC]; + | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #76200 -warning: 2 warnings emitted +warning: cannot use constants which depend on generic parameters in types + --> $DIR/const-evaluatable-unchecked.rs:29:21 + | +LL | let _ = [0; Self::ASSOC]; + | ^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #76200 + +warning: 3 warnings emitted From eb8e8bd8bfe492f154ab0438b0067b7a302d2fc1 Mon Sep 17 00:00:00 2001 From: kadmin Date: Mon, 26 Oct 2020 23:25:12 +0000 Subject: [PATCH 03/21] Add UI test for invalid values for bool & char --- .../min_const_generics/invalid-patterns.rs | 45 ++++++++++++++ .../invalid-patterns.stderr | 60 +++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 src/test/ui/const-generics/min_const_generics/invalid-patterns.rs create mode 100644 src/test/ui/const-generics/min_const_generics/invalid-patterns.stderr diff --git a/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs b/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs new file mode 100644 index 0000000000000..e59b97922bea1 --- /dev/null +++ b/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs @@ -0,0 +1,45 @@ +#![feature(min_const_generics)] +use std::mem::transmute; + +fn get_flag() -> Option { + if FlagSet { + Some(ShortName) + } else { + None + } +} + +union CharRaw { + byte: u8, + character: char, +} + +union BoolRaw { + byte: u8, + boolean: bool, +} + +const char_raw: CharRaw = CharRaw { byte: 0xFF }; +const bool_raw: BoolRaw = BoolRaw { byte: 0x42 }; + +fn main() { + // Test that basic cases don't work + assert!(get_flag::().is_some()); + assert!(get_flag::().is_none()); + get_flag::(); + //~^ ERROR mismatched types + get_flag::<7, 'c'>(); + //~^ ERROR mismatched types + get_flag::<42, 0x5ad>(); + //~^ ERROR mismatched types + //~| ERROR mismatched types + + + get_flag::(); + //~^ ERROR it is undefined behavior + get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>(); + //~^ ERROR it is undefined behavior + get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); + //~^ ERROR it is undefined behavior + //~| ERROR it is undefined behavior +} diff --git a/src/test/ui/const-generics/min_const_generics/invalid-patterns.stderr b/src/test/ui/const-generics/min_const_generics/invalid-patterns.stderr new file mode 100644 index 0000000000000..a3157c6b5644d --- /dev/null +++ b/src/test/ui/const-generics/min_const_generics/invalid-patterns.stderr @@ -0,0 +1,60 @@ +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:29:21 + | +LL | get_flag::(); + | ^^^^ expected `char`, found `u8` + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:31:14 + | +LL | get_flag::<7, 'c'>(); + | ^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:33:14 + | +LL | get_flag::<42, 0x5ad>(); + | ^^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:33:18 + | +LL | get_flag::<42, 0x5ad>(); + | ^^^^^ expected `char`, found `u8` + +error[E0080]: it is undefined behavior to use this value + --> $DIR/invalid-patterns.rs:38:21 + | +LL | get_flag::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error[E0080]: it is undefined behavior to use this value + --> $DIR/invalid-patterns.rs:40:14 + | +LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x42, but expected a boolean + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error[E0080]: it is undefined behavior to use this value + --> $DIR/invalid-patterns.rs:42:14 + | +LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x42, but expected a boolean + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error[E0080]: it is undefined behavior to use this value + --> $DIR/invalid-patterns.rs:42:47 + | +LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0080, E0308. +For more information about an error, try `rustc --explain E0080`. From 0217edbd292eeb9d5febfda6e33c574ab88cf916 Mon Sep 17 00:00:00 2001 From: Camelid Date: Tue, 27 Oct 2020 20:54:30 -0700 Subject: [PATCH 04/21] Clean up intra-doc links in `std::path` --- library/std/src/path.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 50bd2a03b62b0..8a75c1d6058da 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -446,7 +446,7 @@ impl Hash for PrefixComponent<'_> { /// (`/` or `\`). /// /// This `enum` is created by iterating over [`Components`], which in turn is -/// created by the [`components`][`Path::components`] method on [`Path`]. +/// created by the [`components`](Path::components) method on [`Path`]. /// /// # Examples /// @@ -1319,7 +1319,7 @@ impl PathBuf { self.inner } - /// Converts this `PathBuf` into a [boxed][`Box`] [`Path`]. + /// Converts this `PathBuf` into a [boxed](Box) [`Path`]. #[stable(feature = "into_boxed_path", since = "1.20.0")] pub fn into_boxed_path(self) -> Box { let rw = Box::into_raw(self.inner.into_boxed_os_str()) as *mut Path; @@ -1686,8 +1686,7 @@ pub struct Path { inner: OsStr, } -/// An error returned from [`Path::strip_prefix`][`strip_prefix`] if the prefix -/// was not found. +/// An error returned from [`Path::strip_prefix`] if the prefix was not found. /// /// This `struct` is created by the [`strip_prefix`] method on [`Path`]. /// See its documentation for more. @@ -2470,7 +2469,7 @@ impl Path { fs::metadata(self).map(|m| m.is_dir()).unwrap_or(false) } - /// Converts a [`Box`][`Box`] into a [`PathBuf`] without copying or + /// Converts a [`Box`](Box) into a [`PathBuf`] without copying or /// allocating. #[stable(feature = "into_boxed_path", since = "1.20.0")] pub fn into_path_buf(self: Box) -> PathBuf { @@ -2498,7 +2497,7 @@ impl fmt::Debug for Path { /// /// A [`Path`] might contain non-Unicode data. This `struct` implements the /// [`Display`] trait in a way that mitigates that. It is created by the -/// [`display`][`Path::display`] method on [`Path`]. +/// [`display`](Path::display) method on [`Path`]. /// /// # Examples /// From c90ef979de8cf63b895dfec0c12f1e12c049e1b6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 28 Oct 2020 10:39:21 +0100 Subject: [PATCH 05/21] fix a comment in validity check --- compiler/rustc_mir/src/interpret/validity.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_mir/src/interpret/validity.rs b/compiler/rustc_mir/src/interpret/validity.rs index c38f25564e8dd..3c76f89f30e83 100644 --- a/compiler/rustc_mir/src/interpret/validity.rs +++ b/compiler/rustc_mir/src/interpret/validity.rs @@ -559,9 +559,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' // Nothing to check. Ok(true) } - // The above should be all the (inhabited) primitive types. The rest is compound, we + // The above should be all the primitive types. The rest is compound, we // check them by visiting their fields/variants. - // (`Str` UTF-8 check happens in `visit_aggregate`, too.) ty::Adt(..) | ty::Tuple(..) | ty::Array(..) From 9e60f4511e39d012d5a21c10c55d706ec1e75e53 Mon Sep 17 00:00:00 2001 From: Hameer Abbasi Date: Wed, 28 Oct 2020 10:36:19 +0000 Subject: [PATCH 06/21] Add const generics tests for supertraits + dyn traits. --- src/test/ui/const-generics/dyn-supertraits.rs | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/test/ui/const-generics/dyn-supertraits.rs diff --git a/src/test/ui/const-generics/dyn-supertraits.rs b/src/test/ui/const-generics/dyn-supertraits.rs new file mode 100644 index 0000000000000..b72dd9cc90cd4 --- /dev/null +++ b/src/test/ui/const-generics/dyn-supertraits.rs @@ -0,0 +1,58 @@ +// check-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +trait Foo {} +trait Bar : Foo {} +trait Baz: Foo<3> {} + +struct FooType {} +struct BarType {} +struct BazType {} + +impl Foo for FooType {} +impl Foo for BarType {} +impl Bar for BarType {} +impl Foo<3> for BazType {} +impl Baz for BazType {} + +trait Foz {} +trait Boz: Foo<3> + Foz {} +trait Bok: Foo + Foz {} + +struct FozType {} +struct BozType {} +struct BokType {} + +impl Foz for FozType {} + +impl Foz for BozType {} +impl Foo<3> for BozType {} +impl Boz for BozType {} + +impl Foz for BokType {} +impl Foo for BokType {} +impl Bok for BokType {} + +fn a(x: &dyn Foo) {} +fn b(x: &dyn Foo<3>) {} + +fn main() { + let foo = FooType::<3> {}; + a(&foo); b(&foo); + + let bar = BarType::<3> {}; + a(&bar); b(&bar); + + let baz = BazType {}; + a(&baz); b(&baz); + + let boz = BozType {}; + a(&boz); b(&boz); + + let bok = BokType::<3> {}; + a(&bok); b(&bok); +} From 6c73adf3240261315446582cb57de079bf2b87f9 Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 28 Oct 2020 00:41:40 +0000 Subject: [PATCH 07/21] Adjust turbofish help message for const generics --- .../rustc_parse/src/parser/diagnostics.rs | 9 +++---- ...st-missing-braces-without-turbofish.stderr | 24 +++++++++---------- src/test/ui/did_you_mean/issue-40396.stderr | 14 +++++------ .../require-parens-for-chained-comparison.rs | 6 ++--- ...quire-parens-for-chained-comparison.stderr | 6 ++--- 5 files changed, 30 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 52cbba9d2bf7d..debe6a5c12ca7 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -20,7 +20,8 @@ use rustc_span::{MultiSpan, Span, SpanSnippetError, DUMMY_SP}; use tracing::{debug, trace}; -const TURBOFISH: &str = "use `::<...>` instead of `<...>` to specify type arguments"; +const TURBOFISH_SUGGESTION_STR: &str = + "use `::<...>` instead of `<...>` to specify type or const arguments"; /// Creates a placeholder argument. pub(super) fn dummy_arg(ident: Ident) -> Param { @@ -659,7 +660,7 @@ impl<'a> Parser<'a> { Ok(_) => { e.span_suggestion_verbose( binop.span.shrink_to_lo(), - "use `::<...>` instead of `<...>` to specify type arguments", + TURBOFISH_SUGGESTION_STR, "::".to_string(), Applicability::MaybeIncorrect, ); @@ -814,7 +815,7 @@ impl<'a> Parser<'a> { let suggest = |err: &mut DiagnosticBuilder<'_>| { err.span_suggestion_verbose( op.span.shrink_to_lo(), - TURBOFISH, + TURBOFISH_SUGGESTION_STR, "::".to_string(), Applicability::MaybeIncorrect, ); @@ -888,7 +889,7 @@ impl<'a> Parser<'a> { { // All we know is that this is `foo < bar >` and *nothing* else. Try to // be helpful, but don't attempt to recover. - err.help(TURBOFISH); + err.help(TURBOFISH_SUGGESTION_STR); err.help("or use `(...)` if you meant to specify fn arguments"); } diff --git a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.stderr b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.stderr index 103a295fced51..13742238a201a 100644 --- a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.stderr +++ b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.stderr @@ -4,7 +4,7 @@ error: comparison operators cannot be chained LL | foo(); | ^ ^ | -help: use `::<...>` instead of `<...>` to specify type arguments +help: use `::<...>` instead of `<...>` to specify type or const arguments | LL | foo::(); | ^^ @@ -15,7 +15,7 @@ error: comparison operators cannot be chained LL | foo(); | ^ ^ | -help: use `::<...>` instead of `<...>` to specify type arguments +help: use `::<...>` instead of `<...>` to specify type or const arguments | LL | foo::(); | ^^ @@ -26,7 +26,7 @@ error: comparison operators cannot be chained LL | foo<3 + 3>(); | ^ ^ | -help: use `::<...>` instead of `<...>` to specify type arguments +help: use `::<...>` instead of `<...>` to specify type or const arguments | LL | foo::<3 + 3>(); | ^^ @@ -37,7 +37,7 @@ error: comparison operators cannot be chained LL | foo(); | ^ ^ | -help: use `::<...>` instead of `<...>` to specify type arguments +help: use `::<...>` instead of `<...>` to specify type or const arguments | LL | foo::(); | ^^ @@ -48,7 +48,7 @@ error: comparison operators cannot be chained LL | foo(); | ^ ^ | -help: use `::<...>` instead of `<...>` to specify type arguments +help: use `::<...>` instead of `<...>` to specify type or const arguments | LL | foo::(); | ^^ @@ -59,7 +59,7 @@ error: comparison operators cannot be chained LL | foo<100 - BAR>(); | ^ ^ | -help: use `::<...>` instead of `<...>` to specify type arguments +help: use `::<...>` instead of `<...>` to specify type or const arguments | LL | foo::<100 - BAR>(); | ^^ @@ -70,7 +70,7 @@ error: comparison operators cannot be chained LL | foo()>(); | ^ ^ | -help: use `::<...>` instead of `<...>` to specify type arguments +help: use `::<...>` instead of `<...>` to specify type or const arguments | LL | foo::()>(); | ^^ @@ -87,7 +87,7 @@ error: comparison operators cannot be chained LL | foo()>(); | ^ ^ | -help: use `::<...>` instead of `<...>` to specify type arguments +help: use `::<...>` instead of `<...>` to specify type or const arguments | LL | foo::()>(); | ^^ @@ -98,7 +98,7 @@ error: comparison operators cannot be chained LL | foo() + BAR>(); | ^ ^ | -help: use `::<...>` instead of `<...>` to specify type arguments +help: use `::<...>` instead of `<...>` to specify type or const arguments | LL | foo::() + BAR>(); | ^^ @@ -109,7 +109,7 @@ error: comparison operators cannot be chained LL | foo() - BAR>(); | ^ ^ | -help: use `::<...>` instead of `<...>` to specify type arguments +help: use `::<...>` instead of `<...>` to specify type or const arguments | LL | foo::() - BAR>(); | ^^ @@ -120,7 +120,7 @@ error: comparison operators cannot be chained LL | foo()>(); | ^ ^ | -help: use `::<...>` instead of `<...>` to specify type arguments +help: use `::<...>` instead of `<...>` to specify type or const arguments | LL | foo::()>(); | ^^ @@ -131,7 +131,7 @@ error: comparison operators cannot be chained LL | foo()>(); | ^ ^ | -help: use `::<...>` instead of `<...>` to specify type arguments +help: use `::<...>` instead of `<...>` to specify type or const arguments | LL | foo::()>(); | ^^ diff --git a/src/test/ui/did_you_mean/issue-40396.stderr b/src/test/ui/did_you_mean/issue-40396.stderr index 184bcf0c74b14..2c2978d2bff2d 100644 --- a/src/test/ui/did_you_mean/issue-40396.stderr +++ b/src/test/ui/did_you_mean/issue-40396.stderr @@ -4,7 +4,7 @@ error: comparison operators cannot be chained LL | (0..13).collect>(); | ^ ^ | -help: use `::<...>` instead of `<...>` to specify type arguments +help: use `::<...>` instead of `<...>` to specify type or const arguments | LL | (0..13).collect::>(); | ^^ @@ -15,7 +15,7 @@ error: comparison operators cannot be chained LL | Vec::new(); | ^ ^ | -help: use `::<...>` instead of `<...>` to specify type arguments +help: use `::<...>` instead of `<...>` to specify type or const arguments | LL | Vec::::new(); | ^^ @@ -26,7 +26,7 @@ error: comparison operators cannot be chained LL | (0..13).collect(); | ^ ^ | -help: use `::<...>` instead of `<...>` to specify type arguments +help: use `::<...>` instead of `<...>` to specify type or const arguments | LL | (0..13).collect::(); | ^^ @@ -37,7 +37,7 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, or an operator, found `,` LL | let x = std::collections::HashMap::new(); | ^ expected one of 7 possible tokens | -help: use `::<...>` instead of `<...>` to specify type arguments +help: use `::<...>` instead of `<...>` to specify type or const arguments | LL | let x = std::collections::HashMap::::new(); | ^^ @@ -48,7 +48,7 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found LL | std::collections::HashMap::new() | ^ expected one of 8 possible tokens | -help: use `::<...>` instead of `<...>` to specify type arguments +help: use `::<...>` instead of `<...>` to specify type or const arguments | LL | std::collections::HashMap::::new() | ^^ @@ -59,7 +59,7 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found LL | std::collections::HashMap::new(); | ^ expected one of 8 possible tokens | -help: use `::<...>` instead of `<...>` to specify type arguments +help: use `::<...>` instead of `<...>` to specify type or const arguments | LL | std::collections::HashMap::::new(); | ^^ @@ -70,7 +70,7 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found LL | std::collections::HashMap::new(1, 2); | ^ expected one of 8 possible tokens | -help: use `::<...>` instead of `<...>` to specify type arguments +help: use `::<...>` instead of `<...>` to specify type or const arguments | LL | std::collections::HashMap::::new(1, 2); | ^^ diff --git a/src/test/ui/parser/require-parens-for-chained-comparison.rs b/src/test/ui/parser/require-parens-for-chained-comparison.rs index 4e97904ed6d5f..e3ce6cd39bc24 100644 --- a/src/test/ui/parser/require-parens-for-chained-comparison.rs +++ b/src/test/ui/parser/require-parens-for-chained-comparison.rs @@ -12,15 +12,15 @@ fn main() { f(); //~^ ERROR comparison operators cannot be chained - //~| HELP use `::<...>` instead of `<...>` to specify type arguments + //~| HELP use `::<...>` instead of `<...>` to specify type or const arguments f, Option>>(1, 2); //~^ ERROR comparison operators cannot be chained - //~| HELP use `::<...>` instead of `<...>` to specify type arguments + //~| HELP use `::<...>` instead of `<...>` to specify type or const arguments use std::convert::identity; let _ = identity; //~^ ERROR comparison operators cannot be chained - //~| HELP use `::<...>` instead of `<...>` to specify type arguments + //~| HELP use `::<...>` instead of `<...>` to specify type or const arguments //~| HELP or use `(...)` if you meant to specify fn arguments } diff --git a/src/test/ui/parser/require-parens-for-chained-comparison.stderr b/src/test/ui/parser/require-parens-for-chained-comparison.stderr index 7001aa8e8a1d8..afb964c17e255 100644 --- a/src/test/ui/parser/require-parens-for-chained-comparison.stderr +++ b/src/test/ui/parser/require-parens-for-chained-comparison.stderr @@ -26,7 +26,7 @@ error: comparison operators cannot be chained LL | f(); | ^ ^ | -help: use `::<...>` instead of `<...>` to specify type arguments +help: use `::<...>` instead of `<...>` to specify type or const arguments | LL | f::(); | ^^ @@ -37,7 +37,7 @@ error: comparison operators cannot be chained LL | f, Option>>(1, 2); | ^ ^ | -help: use `::<...>` instead of `<...>` to specify type arguments +help: use `::<...>` instead of `<...>` to specify type or const arguments | LL | f::, Option>>(1, 2); | ^^ @@ -48,7 +48,7 @@ error: comparison operators cannot be chained LL | let _ = identity; | ^ ^ | - = help: use `::<...>` instead of `<...>` to specify type arguments + = help: use `::<...>` instead of `<...>` to specify type or const arguments = help: or use `(...)` if you meant to specify fn arguments error: aborting due to 5 previous errors From a6d01da7165d904d83407c385282803b9cb71dbb Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 28 Oct 2020 00:46:53 +0000 Subject: [PATCH 08/21] Remove irrelevant FIXME --- compiler/rustc_infer/src/infer/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index ff7bbf0562f60..acded5351f80a 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -678,8 +678,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn unsolved_variables(&self) -> Vec> { let mut inner = self.inner.borrow_mut(); - // FIXME(const_generics): should there be an equivalent function for const variables? - let mut vars: Vec> = inner .type_variables() .unsolved_variables() From fab79c27ef184ee3620681bfbdc1fd89ad10b4df Mon Sep 17 00:00:00 2001 From: Hameer Abbasi Date: Wed, 28 Oct 2020 12:29:13 +0000 Subject: [PATCH 09/21] Extend test to cover dyn methods/functions. --- src/test/ui/const-generics/dyn-supertraits.rs | 64 +++++++++++++------ 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/src/test/ui/const-generics/dyn-supertraits.rs b/src/test/ui/const-generics/dyn-supertraits.rs index b72dd9cc90cd4..8b956988c7c46 100644 --- a/src/test/ui/const-generics/dyn-supertraits.rs +++ b/src/test/ui/const-generics/dyn-supertraits.rs @@ -1,58 +1,82 @@ -// check-pass +// run-pass // revisions: full min #![cfg_attr(full, feature(const_generics))] #![cfg_attr(full, allow(incomplete_features))] #![cfg_attr(min, feature(min_const_generics))] -trait Foo {} +trait Foo { + fn myfun(&self) -> usize; +} trait Bar : Foo {} trait Baz: Foo<3> {} -struct FooType {} -struct BarType {} -struct BazType {} +struct FooType; +struct BarType; +struct BazType; -impl Foo for FooType {} -impl Foo for BarType {} +impl Foo for FooType { + fn myfun(&self) -> usize { N } +} +impl Foo for BarType { + fn myfun(&self) -> usize { N + 1 } +} impl Bar for BarType {} -impl Foo<3> for BazType {} +impl Foo<3> for BazType { + fn myfun(&self) -> usize { 999 } +} impl Baz for BazType {} trait Foz {} trait Boz: Foo<3> + Foz {} trait Bok: Foo + Foz {} -struct FozType {} -struct BozType {} -struct BokType {} +struct FozType; +struct BozType; +struct BokType; impl Foz for FozType {} impl Foz for BozType {} -impl Foo<3> for BozType {} +impl Foo<3> for BozType { + fn myfun(&self) -> usize { 9999 } +} impl Boz for BozType {} impl Foz for BokType {} -impl Foo for BokType {} +impl Foo for BokType { + fn myfun(&self) -> usize { N + 2 } +} impl Bok for BokType {} -fn a(x: &dyn Foo) {} -fn b(x: &dyn Foo<3>) {} +fn a(_: &dyn Foo) {} +fn b(_: &dyn Foo<3>) {} +fn c, const N: usize>(x: T) { a::(&x); } +fn d>(_: &T) {} +fn e(x: &dyn Bar<3>) { d(x); } + +fn get_myfun(x: &dyn Foo) -> usize { x.myfun() } fn main() { let foo = FooType::<3> {}; - a(&foo); b(&foo); + a(&foo); b(&foo); d(&foo); + assert!(get_myfun(&foo) == 3); let bar = BarType::<3> {}; - a(&bar); b(&bar); + a(&bar); b(&bar); d(&bar); e(&bar); + assert!(get_myfun(&bar) == 4); let baz = BazType {}; - a(&baz); b(&baz); + a(&baz); b(&baz); d(&baz); + assert!(get_myfun(&baz) == 999); let boz = BozType {}; - a(&boz); b(&boz); + a(&boz); b(&boz); d(&boz); + assert!(get_myfun(&boz) == 9999); let bok = BokType::<3> {}; - a(&bok); b(&bok); + a(&bok); b(&bok); d(&bok); + assert!(get_myfun(&bok) == 5); + + c(BokType::<3> {}); } From 22060fa0dc0f40652da875fd525e2a898c8584c5 Mon Sep 17 00:00:00 2001 From: Hameer Abbasi Date: Wed, 28 Oct 2020 12:51:15 +0000 Subject: [PATCH 10/21] Assert in every case. --- src/test/ui/const-generics/dyn-supertraits.rs | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/test/ui/const-generics/dyn-supertraits.rs b/src/test/ui/const-generics/dyn-supertraits.rs index 8b956988c7c46..0295255d8099c 100644 --- a/src/test/ui/const-generics/dyn-supertraits.rs +++ b/src/test/ui/const-generics/dyn-supertraits.rs @@ -49,34 +49,37 @@ impl Foo for BokType { } impl Bok for BokType {} -fn a(_: &dyn Foo) {} -fn b(_: &dyn Foo<3>) {} -fn c, const N: usize>(x: T) { a::(&x); } -fn d>(_: &T) {} -fn e(x: &dyn Bar<3>) { d(x); } - -fn get_myfun(x: &dyn Foo) -> usize { x.myfun() } +fn a(x: &dyn Foo) -> usize { x.myfun() } +fn b(x: &dyn Foo<3>) -> usize { x.myfun() } +fn c, const N: usize>(x: T) -> usize { a::(&x) } +fn d>(x: &T) -> usize { x.myfun() } +fn e(x: &dyn Bar<3>) -> usize { d(x) } fn main() { let foo = FooType::<3> {}; - a(&foo); b(&foo); d(&foo); - assert!(get_myfun(&foo) == 3); + assert!(a(&foo) == 3); + assert!(b(&foo) == 3); + assert!(d(&foo) == 3); let bar = BarType::<3> {}; - a(&bar); b(&bar); d(&bar); e(&bar); - assert!(get_myfun(&bar) == 4); + assert!(a(&bar) == 4); + assert!(b(&bar) == 4); + assert!(d(&bar) == 4); + assert!(e(&bar) == 4); let baz = BazType {}; - a(&baz); b(&baz); d(&baz); - assert!(get_myfun(&baz) == 999); + assert!(a(&baz) == 999); + assert!(b(&baz) == 999); + assert!(d(&baz) == 999); let boz = BozType {}; - a(&boz); b(&boz); d(&boz); - assert!(get_myfun(&boz) == 9999); + assert!(a(&boz) == 9999); + assert!(b(&boz) == 9999); + assert!(d(&boz) == 9999); let bok = BokType::<3> {}; - a(&bok); b(&bok); d(&bok); - assert!(get_myfun(&bok) == 5); - - c(BokType::<3> {}); + assert!(a(&bok) == 5); + assert!(b(&bok) == 5); + assert!(d(&bok) == 5); + assert!(c(BokType::<3> {}) == 5); } From f553c226c146d7233ce3b65973002643f5488715 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 28 Oct 2020 15:51:26 +0100 Subject: [PATCH 11/21] Fix typo "compiltest" --- src/doc/rustdoc/src/unstable-features.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 16157a4b080f1..b43070510413a 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -348,7 +348,7 @@ Using this flag looks like this: $ rustdoc src/lib.rs -Z unstable-options --enable-per-target-ignores ``` -This flag allows you to tag doctests with compiltest style `ignore-foo` filters that prevent +This flag allows you to tag doctests with compiletest style `ignore-foo` filters that prevent rustdoc from running that test if the target triple string contains foo. For example: ```rust From 2e10475fdd764365255596e4cb0c21b521456823 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 23 Sep 2020 22:14:43 +0100 Subject: [PATCH 12/21] rustdoc: js: Use getSettingValue for all rustdoc-* values Currently, storage.js and main.js have many open-coded calls to getCurrentValue for "rustdoc-" values, but these are settings and should be handled by getSettingValue. So make getSettingValue part of storage.js (where everyone can call it) and use it everywhere. No functional change yet. We are going to make getSettingValue do something more sophisticated in a moment. Signed-off-by: Ian Jackson --- src/librustdoc/html/static/main.js | 22 +++++++++++----------- src/librustdoc/html/static/settings.js | 4 ---- src/librustdoc/html/static/storage.js | 23 ++++++++++++++--------- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index e382e5aa2348a..28bd1ba5247d6 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -89,7 +89,7 @@ function defocusSearchBar() { "derive", "traitalias"]; - var disableShortcuts = getCurrentValue("rustdoc-disable-shortcuts") === "true"; + var disableShortcuts = getSettingValue("disable-shortcuts") === "true"; var search_input = getSearchInput(); var searchTimeout = null; var toggleAllDocsId = "toggle-all-docs"; @@ -1580,7 +1580,7 @@ function defocusSearchBar() { function showResults(results) { var search = getSearchElement(); if (results.others.length === 1 - && getCurrentValue("rustdoc-go-to-only-result") === "true" + && getSettingValue("go-to-only-result") === "true" // By default, the search DOM element is "empty" (meaning it has no children not // text content). Once a search has been run, it won't be empty, even if you press // ESC or empty the search input (which also "cancels" the search). @@ -2296,7 +2296,7 @@ function defocusSearchBar() { function autoCollapse(pageId, collapse) { if (collapse) { toggleAllDocs(pageId, true); - } else if (getCurrentValue("rustdoc-auto-hide-trait-implementations") !== "false") { + } else if (getSettingValue("auto-hide-trait-implementations") !== "false") { var impl_list = document.getElementById("trait-implementations-list"); if (impl_list !== null) { @@ -2370,8 +2370,8 @@ function defocusSearchBar() { } var toggle = createSimpleToggle(false); - var hideMethodDocs = getCurrentValue("rustdoc-auto-hide-method-docs") === "true"; - var hideImplementors = getCurrentValue("rustdoc-auto-collapse-implementors") !== "false"; + var hideMethodDocs = getSettingValue("auto-hide-method-docs") === "true"; + var hideImplementors = getSettingValue("auto-collapse-implementors") !== "false"; var pageId = getPageId(); var func = function(e) { @@ -2487,7 +2487,7 @@ function defocusSearchBar() { }); } } - var showItemDeclarations = getCurrentValue("rustdoc-auto-hide-" + className); + var showItemDeclarations = getSettingValue("auto-hide-" + className); if (showItemDeclarations === null) { if (className === "enum" || className === "macro") { showItemDeclarations = "false"; @@ -2495,7 +2495,7 @@ function defocusSearchBar() { showItemDeclarations = "true"; } else { // In case we found an unknown type, we just use the "parent" value. - showItemDeclarations = getCurrentValue("rustdoc-auto-hide-declarations"); + showItemDeclarations = getSettingValue("auto-hide-declarations"); } } showItemDeclarations = showItemDeclarations === "false"; @@ -2569,7 +2569,7 @@ function defocusSearchBar() { onEachLazy(document.getElementsByClassName("sub-variant"), buildToggleWrapper); var pageId = getPageId(); - autoCollapse(pageId, getCurrentValue("rustdoc-collapse") === "true"); + autoCollapse(pageId, getSettingValue("collapse") === "true"); if (pageId !== null) { expandSection(pageId); @@ -2592,7 +2592,7 @@ function defocusSearchBar() { (function() { // To avoid checking on "rustdoc-item-attributes" value on every loop... var itemAttributesFunc = function() {}; - if (getCurrentValue("rustdoc-auto-hide-attributes") !== "false") { + if (getSettingValue("auto-hide-attributes") !== "false") { itemAttributesFunc = function(x) { collapseDocs(x.previousSibling.childNodes[0], "toggle"); }; @@ -2611,7 +2611,7 @@ function defocusSearchBar() { (function() { // To avoid checking on "rustdoc-line-numbers" value on every loop... var lineNumbersFunc = function() {}; - if (getCurrentValue("rustdoc-line-numbers") === "true") { + if (getSettingValue("line-numbers") === "true") { lineNumbersFunc = function(x) { var count = x.textContent.split("\n").length; var elems = []; @@ -2768,7 +2768,7 @@ function defocusSearchBar() { } return 0; }); - var savedCrate = getCurrentValue("rustdoc-saved-filter-crate"); + var savedCrate = getSettingValue("saved-filter-crate"); for (var i = 0; i < crates_text.length; ++i) { var option = document.createElement("option"); option.value = crates_text[i]; diff --git a/src/librustdoc/html/static/settings.js b/src/librustdoc/html/static/settings.js index 00a01ac30bcfa..da3378ccf0dd0 100644 --- a/src/librustdoc/html/static/settings.js +++ b/src/librustdoc/html/static/settings.js @@ -14,10 +14,6 @@ } } - function getSettingValue(settingName) { - return getCurrentValue("rustdoc-" + settingName); - } - function setEvents() { var elems = { toggles: document.getElementsByClassName("slider"), diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js index ef734f260afd5..179d713205759 100644 --- a/src/librustdoc/html/static/storage.js +++ b/src/librustdoc/html/static/storage.js @@ -1,10 +1,15 @@ // From rust: -/* global resourcesSuffix */ +/* global resourcesSuffix, getSettingValue */ var darkThemes = ["dark", "ayu"]; var currentTheme = document.getElementById("themeStyle"); var mainTheme = document.getElementById("mainThemeStyle"); -var localStoredTheme = getCurrentValue("rustdoc-theme"); + +function getSettingValue(settingName) { + return getCurrentValue('rustdoc-' + settingName); +} + +var localStoredTheme = getSettingValue("theme"); var savedHref = []; @@ -156,9 +161,9 @@ var updateSystemTheme = (function() { function handlePreferenceChange(mql) { // maybe the user has disabled the setting in the meantime! - if (getCurrentValue("rustdoc-use-system-theme") !== "false") { - var lightTheme = getCurrentValue("rustdoc-preferred-light-theme") || "light"; - var darkTheme = getCurrentValue("rustdoc-preferred-dark-theme") || "dark"; + if (getSettingValue("use-system-theme") !== "false") { + var lightTheme = getSettingValue("preferred-light-theme") || "light"; + var darkTheme = getSettingValue("preferred-dark-theme") || "dark"; if (mql.matches) { // prefers a dark theme @@ -181,11 +186,11 @@ var updateSystemTheme = (function() { }; })(); -if (getCurrentValue("rustdoc-use-system-theme") !== "false" && window.matchMedia) { +if (getSettingValue("use-system-theme") !== "false" && window.matchMedia) { // update the preferred dark theme if the user is already using a dark theme // See https://github.com/rust-lang/rust/pull/77809#issuecomment-707875732 - if (getCurrentValue("rustdoc-use-system-theme") === null - && getCurrentValue("rustdoc-preferred-dark-theme") === null + if (getSettingValue("use-system-theme") === null + && getSettingValue("preferred-dark-theme") === null && darkThemes.indexOf(localStoredTheme) >= 0) { updateLocalStorage("rustdoc-preferred-dark-theme", localStoredTheme); } @@ -196,7 +201,7 @@ if (getCurrentValue("rustdoc-use-system-theme") !== "false" && window.matchMedia switchTheme( currentTheme, mainTheme, - getCurrentValue("rustdoc-theme") || "light", + getSettingValue("theme") || "light", false ); } From 061715604aa1374a087c25721133ef2d18f5091f Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Wed, 28 Oct 2020 13:26:44 -0400 Subject: [PATCH 13/21] Inline NonZeroN::from(n) --- library/core/src/num/nonzero.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 382f799bfe5f9..5a9fd902c9ca1 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -92,6 +92,7 @@ assert_eq!(size_of::>(), size_of::<", s doc_comment! { concat!( "Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`"), + #[inline] fn from(nonzero: $Ty) -> Self { nonzero.0 } From 23167cbfe9e52abb36aebc0b85149ed48dcf6e38 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 28 Oct 2020 10:53:15 -0700 Subject: [PATCH 14/21] Update books --- src/doc/book | 2 +- src/doc/edition-guide | 2 +- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/doc/book b/src/doc/book index 451a1e30f2dd1..13e1c05420bca 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 451a1e30f2dd137aa04e142414eafb8d05f87f84 +Subproject commit 13e1c05420bca86ecc79e4ba5b6d02de9bd53c62 diff --git a/src/doc/edition-guide b/src/doc/edition-guide index 81f16863014de..7bc9b7a5e800f 160000 --- a/src/doc/edition-guide +++ b/src/doc/edition-guide @@ -1 +1 @@ -Subproject commit 81f16863014de60b53de401d71ff904d163ee030 +Subproject commit 7bc9b7a5e800f79df62947cb7d566fd2fbaf19fe diff --git a/src/doc/nomicon b/src/doc/nomicon index 6e57e64501f61..69333eddb1de9 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 6e57e64501f61873ab80cb78a07180a22751a5d6 +Subproject commit 69333eddb1de92fd17e272ce4677cc983d3bd71d diff --git a/src/doc/reference b/src/doc/reference index 1b78182e71709..10c16caebe475 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 1b78182e71709169dc0f1c3acdc4541b6860e1c4 +Subproject commit 10c16caebe475d0d11bec0531b95d7697856c13c diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 152475937a8d8..99eafee0cb14e 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 152475937a8d8a1f508d8eeb57db79139bc803d9 +Subproject commit 99eafee0cb14e6ec641bf02a69d7b30f6058349a From 5cd96d638c37dc7f92cb8b2fc84a3f7bfe7b7960 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 23 Sep 2020 22:44:54 +0100 Subject: [PATCH 15/21] rustdoc: Provide a way to set the default settings from Rust code rustdoc has various user-configurable preferences. These are recorded in web Local Storage (where available). But we want to provide a way to configure the default default, including for when web storage is not available. getSettingValue is the function responsible for looking up these settings. Here we make it fall back some in-DOM data, which ultimately comes from RenderOptions.default_settings. Using HTML data atrtributes is fairly convenient here, dsspite the need to transform between snake and kebab case to avoid the DOM converting kebab case to camel case (!) We cache the element and dataset lookup in a global variable, to ensure that getSettingValue remains fast. The DOM representation has to be in an element which precedes the inclusion of storage.js. That means it has to be in the and we should not use an empty
as the container (although most browsers will accept that). An empty \ \ \ {css_extension}\ @@ -172,6 +175,11 @@ pub fn render( after_content = layout.external_html.after_content, sidebar = Buffer::html().to_display(sidebar), krate = layout.krate, + default_settings = layout + .default_settings + .iter() + .map(|(k, v)| format!(r#" data-{}="{}""#, k.replace('-',"_"), Escape(v),)) + .collect::(), style_files = style_files .iter() .filter_map(|t| { diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 2fd06d7e5730f..ca8b811681cc9 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1228,6 +1228,7 @@ fn init_id_map() -> FxHashMap { map.insert("render-detail".to_owned(), 1); map.insert("toggle-all-docs".to_owned(), 1); map.insert("all-types".to_owned(), 1); + map.insert("default-settings".to_owned(), 1); // This is the list of IDs used by rustdoc sections. map.insert("fields".to_owned(), 1); map.insert("variants".to_owned(), 1); diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 1726093c6facb..0621eafd91347 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -392,6 +392,7 @@ impl FormatRenderer for Context { playground_url, sort_modules_alphabetically, themes: style_files, + default_settings, extension_css, resource_suffix, static_root_path, @@ -415,6 +416,7 @@ impl FormatRenderer for Context { logo: String::new(), favicon: String::new(), external_html, + default_settings, krate: krate.name.clone(), css_file_extension: extension_css, generate_search_filter, diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js index 179d713205759..d081781f14be1 100644 --- a/src/librustdoc/html/static/storage.js +++ b/src/librustdoc/html/static/storage.js @@ -5,8 +5,30 @@ var darkThemes = ["dark", "ayu"]; var currentTheme = document.getElementById("themeStyle"); var mainTheme = document.getElementById("mainThemeStyle"); +var settingsDataset = (function () { + var settingsElement = document.getElementById("default-settings"); + if (settingsElement === null) { + return null; + } + var dataset = settingsElement.dataset; + if (dataset === undefined) { + return null; + } + return dataset; +})(); + function getSettingValue(settingName) { - return getCurrentValue('rustdoc-' + settingName); + var current = getCurrentValue('rustdoc-' + settingName); + if (current !== null) { + return current; + } + if (settingsDataset !== null) { + var def = settingsDataset[settingName.replace(/-/g,'_')]; + if (def !== undefined) { + return def; + } + } + return null; } var localStoredTheme = getSettingValue("theme"); From d8a449756172f7be072b87a545bacf91e10d1bb9 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 13 Oct 2020 18:52:43 +0100 Subject: [PATCH 16/21] rustdoc: Provide a general --default-setting SETTING[=VALUE] option We just plumb through what the user tells us. This is flagged as unstable, mostly because I don't understand the compatibility rules that rustdoc obeys for local storage data, and how error handling of invalid data works. We collect() the needed HashMap from Vec of Vecs of (key, value) pairs, so that there is a nice place to add new more-specific options. It would have been possible to use Extend::extend but doing it this way ensures that all the used inputs are (and will stay) right next to each other. Signed-off-by: Ian Jackson --- src/librustdoc/config.rs | 16 +++++++++++++++- src/librustdoc/html/layout.rs | 2 +- src/librustdoc/lib.rs | 10 ++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index baa0a9341267a..45106c5dbf6a1 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -377,6 +377,20 @@ impl Options { } }; + let mut default_settings: Vec> = vec![ + matches + .opt_strs("default-setting") + .iter() + .map(|s| { + let mut kv = s.splitn(2, '='); + let k = kv.next().unwrap().to_string(); + let v = kv.next().unwrap_or("true").to_string(); + (k, v) + }) + .collect(), + ]; + let default_settings = default_settings.drain(..).flatten().collect(); + let test_args = matches.opt_strs("test-args"); let test_args: Vec = test_args.iter().flat_map(|s| s.split_whitespace()).map(|s| s.to_string()).collect(); @@ -599,7 +613,7 @@ impl Options { themes, extension_css, extern_html_root_urls, - default_settings: Default::default(), + default_settings, resource_suffix, enable_minification, enable_index_page, diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 5489113366258..29e44922c76a2 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -178,7 +178,7 @@ pub fn render( default_settings = layout .default_settings .iter() - .map(|(k, v)| format!(r#" data-{}="{}""#, k.replace('-',"_"), Escape(v),)) + .map(|(k, v)| format!(r#" data-{}="{}""#, k.replace('-', "_"), Escape(v),)) .collect::(), style_files = style_files .iter() diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 616f0efcd7567..90c77488ee945 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -269,6 +269,16 @@ fn opts() -> Vec { "sort modules by where they appear in the program, rather than alphabetically", ) }), + unstable("default-setting", |o| { + o.optmulti( + "", + "default-setting", + "Default value for a rustdoc setting (used when \"rustdoc-SETTING\" is absent \ + from web browser Local Storage). If VALUE is not supplied, \"true\" is used. \ + Supported SETTINGs and VALUEs are not documented and not stable.", + "SETTING[=VALUE]", + ) + }), stable("theme", |o| { o.optmulti( "", From 709efd9df6e21ca07c7c0cceea468663f8a52c23 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 28 Oct 2020 17:53:12 +0000 Subject: [PATCH 17/21] rustdoc: Provide a --default-theme THEME option This is a fairly simple special case of --default-eetting. We must set both "theme" and "use-system-theme". Providing it separately enables us to document a way to set the theme without expoosing the individual settings keywords, which are quite complex. Signed-off-by: Ian Jackson --- src/librustdoc/config.rs | 11 +++++++++++ src/librustdoc/lib.rs | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 45106c5dbf6a1..2558f9e0d7897 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -378,6 +378,17 @@ impl Options { }; let mut default_settings: Vec> = vec![ + matches + .opt_str("default-theme") + .iter() + .map(|theme| { + vec![ + ("use-system-theme".to_string(), "false".to_string()), + ("theme".to_string(), theme.to_string()), + ] + }) + .flatten() + .collect(), matches .opt_strs("default-setting") .iter() diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 90c77488ee945..54463d5c3758e 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -269,6 +269,16 @@ fn opts() -> Vec { "sort modules by where they appear in the program, rather than alphabetically", ) }), + unstable("default-theme", |o| { + o.optopt( + "", + "default-theme", + "Set the default theme. THEME should be the theme name, generally lowercase. \ + If an unknown default theme is specified, the builtin default is used. \ + The set of themes, and the rustdoc built-in default is not stable.", + "THEME", + ) + }), unstable("default-setting", |o| { o.optmulti( "", From 0fabbf9713f2b81f47e32f02567952c9407a4b82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Wed, 28 Oct 2020 19:31:16 +0100 Subject: [PATCH 18/21] Fix typos --- compiler/rustc_mir/src/dataflow/impls/borrows.rs | 2 +- compiler/rustc_mir/src/dataflow/impls/liveness.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_mir/src/dataflow/impls/borrows.rs b/compiler/rustc_mir/src/dataflow/impls/borrows.rs index 0be13b6ba81da..6b7889c4d9e8f 100644 --- a/compiler/rustc_mir/src/dataflow/impls/borrows.rs +++ b/compiler/rustc_mir/src/dataflow/impls/borrows.rs @@ -177,7 +177,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { // // We are careful always to call this function *before* we // set up the gen-bits for the statement or - // termanator. That way, if the effect of the statement or + // terminator. That way, if the effect of the statement or // terminator *does* introduce a new loan of the same // region, then setting that gen-bit will override any // potential kill introduced here. diff --git a/compiler/rustc_mir/src/dataflow/impls/liveness.rs b/compiler/rustc_mir/src/dataflow/impls/liveness.rs index b0da28156d1a4..a2b0713cd7d0b 100644 --- a/compiler/rustc_mir/src/dataflow/impls/liveness.rs +++ b/compiler/rustc_mir/src/dataflow/impls/liveness.rs @@ -8,7 +8,7 @@ use crate::dataflow::{AnalysisDomain, Backward, GenKill, GenKillAnalysis}; /// /// This analysis considers references as being used only at the point of the /// borrow. In other words, this analysis does not track uses because of references that already -/// exist. See [this `mir-datalow` test][flow-test] for an example. You almost never want to use +/// exist. See [this `mir-dataflow` test][flow-test] for an example. You almost never want to use /// this analysis without also looking at the results of [`MaybeBorrowedLocals`]. /// /// [`MaybeBorrowedLocals`]: ../struct.MaybeBorrowedLocals.html @@ -134,7 +134,7 @@ impl DefUse { // `MutatingUseContext::Call` and `MutatingUseContext::Yield` indicate that this is the // destination place for a `Call` return or `Yield` resume respectively. Since this is - // only a `Def` when the function returns succesfully, we handle this case separately + // only a `Def` when the function returns successfully, we handle this case separately // in `call_return_effect` above. PlaceContext::MutatingUse(MutatingUseContext::Call | MutatingUseContext::Yield) => None, From 39b80cb7c03ad3991679523b2c64e52d897d6673 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 28 Oct 2020 20:12:15 +0000 Subject: [PATCH 19/21] rustdoc: Fix some nits * Remove a needless comma in the Rust code * Replace double spaces after full stops with single spaces Requested-by: @GuillaumeGomez Signed-off-by: Ian Jackson --- src/librustdoc/config.rs | 2 +- src/librustdoc/html/layout.rs | 2 +- src/librustdoc/lib.rs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 2558f9e0d7897..3b6b3a826e2aa 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -216,7 +216,7 @@ pub struct RenderOptions { pub extension_css: Option, /// A map of crate names to the URL to use instead of querying the crate's `html_root_url`. pub extern_html_root_urls: BTreeMap, - /// A map of the default settings (values are as for DOM storage API). Keys should lack the + /// A map of the default settings (values are as for DOM storage API). Keys should lack the /// `rustdoc-` prefix. pub default_settings: HashMap, /// If present, suffix added to CSS/JavaScript files when referencing them in generated pages. diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 29e44922c76a2..b089bcb0862a5 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -178,7 +178,7 @@ pub fn render( default_settings = layout .default_settings .iter() - .map(|(k, v)| format!(r#" data-{}="{}""#, k.replace('-', "_"), Escape(v),)) + .map(|(k, v)| format!(r#" data-{}="{}""#, k.replace('-', "_"), Escape(v))) .collect::(), style_files = style_files .iter() diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 54463d5c3758e..7efbca5c6c3b7 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -273,7 +273,7 @@ fn opts() -> Vec { o.optopt( "", "default-theme", - "Set the default theme. THEME should be the theme name, generally lowercase. \ + "Set the default theme. THEME should be the theme name, generally lowercase. \ If an unknown default theme is specified, the builtin default is used. \ The set of themes, and the rustdoc built-in default is not stable.", "THEME", @@ -284,7 +284,7 @@ fn opts() -> Vec { "", "default-setting", "Default value for a rustdoc setting (used when \"rustdoc-SETTING\" is absent \ - from web browser Local Storage). If VALUE is not supplied, \"true\" is used. \ + from web browser Local Storage). If VALUE is not supplied, \"true\" is used. \ Supported SETTINGs and VALUEs are not documented and not stable.", "SETTING[=VALUE]", ) From 1d6c8602770675d0c2001e2f8675c8a31a5b5c42 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 28 Oct 2020 21:25:47 +0000 Subject: [PATCH 20/21] Add a comment about non-panicking of splitn().next().unwrap() Co-authored-by: Joshua Nelson --- src/librustdoc/config.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 3b6b3a826e2aa..7c6017b39dff2 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -394,6 +394,7 @@ impl Options { .iter() .map(|s| { let mut kv = s.splitn(2, '='); + // never panics because `splitn` always returns at least one element let k = kv.next().unwrap().to_string(); let v = kv.next().unwrap_or("true").to_string(); (k, v) From 776e204609fe4c664eb64af47703427807627c8e Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 28 Oct 2020 21:29:21 +0000 Subject: [PATCH 21/21] rustdoc: Use Vec::into_iter() rather than drain() This allows removing a `mut` which is nicer. Suggested-by: @jyn514 Signed-off-by: Ian Jackson --- src/librustdoc/config.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 7c6017b39dff2..02885f519363c 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -377,7 +377,7 @@ impl Options { } }; - let mut default_settings: Vec> = vec![ + let default_settings: Vec> = vec![ matches .opt_str("default-theme") .iter() @@ -401,7 +401,7 @@ impl Options { }) .collect(), ]; - let default_settings = default_settings.drain(..).flatten().collect(); + let default_settings = default_settings.into_iter().flatten().collect(); let test_args = matches.opt_strs("test-args"); let test_args: Vec =