From 4a15a256626d3a9e017a18bb60bf98b1a6358bd5 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Thu, 22 Oct 2020 10:32:41 +0200 Subject: [PATCH 01/22] 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/22] 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 df59a44feadad386a8b69cfafaf50605c6af2689 Mon Sep 17 00:00:00 2001 From: Tyson Nottingham Date: Sun, 20 Sep 2020 17:40:40 -0700 Subject: [PATCH 03/22] rustc_span: improve bounds checks in byte_pos_to_line_and_col The effect of this change is to consider edge-case spans that start or end at the position one past the end of a file to be valid during span hashing and encoding. This change means that these spans will be preserved across incremental compilation sessions when they are part of a serialized query result, instead of causing the dummy span to be used. --- .../rustc_span/src/caching_source_map_view.rs | 32 +++++++++++++++++-- compiler/rustc_span/src/lib.rs | 11 ++++++- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_span/src/caching_source_map_view.rs b/compiler/rustc_span/src/caching_source_map_view.rs index 68b0bd1a57418..2393ae2161371 100644 --- a/compiler/rustc_span/src/caching_source_map_view.rs +++ b/compiler/rustc_span/src/caching_source_map_view.rs @@ -47,7 +47,7 @@ impl<'sm> CachingSourceMapView<'sm> { // Check if the position is in one of the cached lines for cache_entry in self.line_cache.iter_mut() { - if pos >= cache_entry.line_start && pos < cache_entry.line_end { + if line_contains((cache_entry.line_start, cache_entry.line_end), pos) { cache_entry.time_stamp = self.time_stamp; return Some(( @@ -69,13 +69,13 @@ impl<'sm> CachingSourceMapView<'sm> { let cache_entry = &mut self.line_cache[oldest]; // If the entry doesn't point to the correct file, fix it up - if pos < cache_entry.file.start_pos || pos >= cache_entry.file.end_pos { + if !file_contains(&cache_entry.file, pos) { let file_valid; if self.source_map.files().len() > 0 { let file_index = self.source_map.lookup_source_file_idx(pos); let file = self.source_map.files()[file_index].clone(); - if pos >= file.start_pos && pos < file.end_pos { + if file_contains(&file, pos) { cache_entry.file = file; cache_entry.file_index = file_index; file_valid = true; @@ -102,3 +102,29 @@ impl<'sm> CachingSourceMapView<'sm> { Some((cache_entry.file.clone(), cache_entry.line_number, pos - cache_entry.line_start)) } } + +#[inline] +fn line_contains(line_bounds: (BytePos, BytePos), pos: BytePos) -> bool { + // This condition will be false in one case where we'd rather it wasn't. Spans often start/end + // one past something, and when that something is the last character of a file (this can happen + // when a file doesn't end in a newline, for example), we'd still like for the position to be + // considered within the last line. However, it isn't according to the exclusive upper bound + // below. We cannot change the upper bound to be inclusive, because for most lines, the upper + // bound is the same as the lower bound of the next line, so there would be an ambiguity. + // + // Supposing we only use this function to check whether or not the line cache entry contains + // a position, the only ramification of the above is that we will get cache misses for these + // rare positions. A line lookup for the position via `SourceMap::lookup_line` after a cache + // miss will produce the last line number, as desired. + line_bounds.0 <= pos && pos < line_bounds.1 +} + +#[inline] +fn file_contains(file: &SourceFile, pos: BytePos) -> bool { + // `SourceMap::lookup_source_file_idx` and `SourceFile::contains` both consider the position + // one past the end of a file to belong to it. Normally, that's what we want. But for the + // purposes of converting a byte position to a line and column number, we can't come up with a + // line and column number if the file is empty, because an empty file doesn't contain any + // lines. So for our purposes, we don't consider empty files to contain any byte position. + file.contains(pos) && !file.is_empty() +} diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index d036c07804990..21a38283f45e6 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1427,7 +1427,7 @@ impl SourceFile { } pub fn line_bounds(&self, line_index: usize) -> (BytePos, BytePos) { - if self.start_pos == self.end_pos { + if self.is_empty() { return (self.start_pos, self.end_pos); } @@ -1439,11 +1439,20 @@ impl SourceFile { } } + /// Returns whether or not the file contains the given `SourceMap` byte + /// position. The position one past the end of the file is considered to be + /// contained by the file. This implies that files for which `is_empty` + /// returns true still contain one byte position according to this function. #[inline] pub fn contains(&self, byte_pos: BytePos) -> bool { byte_pos >= self.start_pos && byte_pos <= self.end_pos } + #[inline] + pub fn is_empty(&self) -> bool { + self.start_pos == self.end_pos + } + /// Calculates the original byte position relative to the start of the file /// based on the given byte position. pub fn original_relative_byte_pos(&self, pos: BytePos) -> BytePos { From 650e3cb1769d3732c2047c41a234221d8ed6dcf6 Mon Sep 17 00:00:00 2001 From: Rustin-Liu Date: Tue, 27 Oct 2020 14:14:08 +0800 Subject: [PATCH 04/22] Prefer new associated numeric consts in float error messages --- compiler/rustc_lint/src/types.rs | 2 +- src/test/ui/lint/lint-type-overflow2.stderr | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index b502bd7f7a1bd..bd0250305671e 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -439,7 +439,7 @@ fn lint_literal<'tcx>( cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, |lint| { lint.build(&format!("literal out of range for `{}`", t.name_str())) .note(&format!( - "the literal `{}` does not fit into the type `{}` and will be converted to `std::{}::INFINITY`", + "the literal `{}` does not fit into the type `{}` and will be converted to `{}::INFINITY`", cx.sess() .source_map() .span_to_snippet(lit.span) diff --git a/src/test/ui/lint/lint-type-overflow2.stderr b/src/test/ui/lint/lint-type-overflow2.stderr index 61e33b7a260c9..0f16229a29178 100644 --- a/src/test/ui/lint/lint-type-overflow2.stderr +++ b/src/test/ui/lint/lint-type-overflow2.stderr @@ -17,7 +17,7 @@ error: literal out of range for `f32` LL | let x = -3.40282357e+38_f32; | ^^^^^^^^^^^^^^^^^^ | - = note: the literal `3.40282357e+38_f32` does not fit into the type `f32` and will be converted to `std::f32::INFINITY` + = note: the literal `3.40282357e+38_f32` does not fit into the type `f32` and will be converted to `f32::INFINITY` error: literal out of range for `f32` --> $DIR/lint-type-overflow2.rs:10:14 @@ -25,7 +25,7 @@ error: literal out of range for `f32` LL | let x = 3.40282357e+38_f32; | ^^^^^^^^^^^^^^^^^^ | - = note: the literal `3.40282357e+38_f32` does not fit into the type `f32` and will be converted to `std::f32::INFINITY` + = note: the literal `3.40282357e+38_f32` does not fit into the type `f32` and will be converted to `f32::INFINITY` error: literal out of range for `f64` --> $DIR/lint-type-overflow2.rs:11:14 @@ -33,7 +33,7 @@ error: literal out of range for `f64` LL | let x = -1.7976931348623159e+308_f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: the literal `1.7976931348623159e+308_f64` does not fit into the type `f64` and will be converted to `std::f64::INFINITY` + = note: the literal `1.7976931348623159e+308_f64` does not fit into the type `f64` and will be converted to `f64::INFINITY` error: literal out of range for `f64` --> $DIR/lint-type-overflow2.rs:12:14 @@ -41,7 +41,7 @@ error: literal out of range for `f64` LL | let x = 1.7976931348623159e+308_f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: the literal `1.7976931348623159e+308_f64` does not fit into the type `f64` and will be converted to `std::f64::INFINITY` + = note: the literal `1.7976931348623159e+308_f64` does not fit into the type `f64` and will be converted to `f64::INFINITY` error: aborting due to 5 previous errors From f0ae24e100392dd9958f2717df364552d34d7914 Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Tue, 27 Oct 2020 03:10:41 -0400 Subject: [PATCH 05/22] Handle type errors in closure/generator upvar_tys Co-authored-by: Roxane Fruytier --- Cargo.lock | 1 + compiler/rustc_middle/Cargo.toml | 1 + compiler/rustc_middle/src/ty/sty.rs | 34 ++++++++++++++++++++----- src/test/ui/issues/issue-77993-1.rs | 12 +++++++++ src/test/ui/issues/issue-77993-1.stderr | 16 ++++++++++++ src/test/ui/issues/issue-77993-2.rs | 9 +++++++ src/test/ui/issues/issue-77993-2.stderr | 8 ++++++ 7 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 src/test/ui/issues/issue-77993-1.rs create mode 100644 src/test/ui/issues/issue-77993-1.stderr create mode 100644 src/test/ui/issues/issue-77993-2.rs create mode 100644 src/test/ui/issues/issue-77993-2.stderr diff --git a/Cargo.lock b/Cargo.lock index 65d20190c0db5..6f925b505334f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3883,6 +3883,7 @@ version = "0.0.0" dependencies = [ "bitflags", "chalk-ir", + "either", "measureme 9.0.0", "polonius-engine", "rustc-rayon-core", diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 66532ea02f368..0d5fbf16a5810 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -8,6 +8,7 @@ edition = "2018" doctest = false [dependencies] +either = "1.5.0" rustc_arena = { path = "../rustc_arena" } bitflags = "1.2.1" tracing = "0.1" diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 0fd48d0928257..96a8902a76c99 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -5,6 +5,8 @@ use self::InferTy::*; use self::TyKind::*; +use either::Either; + use crate::infer::canonical::Canonical; use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef}; use crate::ty::{ @@ -388,9 +390,17 @@ impl<'tcx> ClosureSubsts<'tcx> { self.split().parent_substs } + /// Returns an iterator over the list of types of captured paths by the closure. + /// In case there was a type error in figuring out the types of the captured path, an + /// empty iterator is returned. #[inline] pub fn upvar_tys(self) -> impl Iterator> + 'tcx { - self.tupled_upvars_ty().tuple_fields() + match self.tupled_upvars_ty().kind() { + TyKind::Error(_) => Either::Left(std::iter::empty()), + TyKind::Tuple(..) => Either::Right(self.tupled_upvars_ty().tuple_fields()), + TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"), + ty => bug!("Unexpected representation of upvar types tuple {:?}", ty), + } } /// Returns the tuple type representing the upvars for this closure. @@ -515,9 +525,17 @@ impl<'tcx> GeneratorSubsts<'tcx> { self.split().witness.expect_ty() } + /// Returns an iterator over the list of types of captured paths by the generator. + /// In case there was a type error in figuring out the types of the captured path, an + /// empty iterator is returned. #[inline] pub fn upvar_tys(self) -> impl Iterator> + 'tcx { - self.tupled_upvars_ty().tuple_fields() + match self.tupled_upvars_ty().kind() { + TyKind::Error(_) => Either::Left(std::iter::empty()), + TyKind::Tuple(..) => Either::Right(self.tupled_upvars_ty().tuple_fields()), + TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"), + ty => bug!("Unexpected representation of upvar types tuple {:?}", ty), + } } /// Returns the tuple type representing the upvars for this generator. @@ -660,13 +678,15 @@ pub enum UpvarSubsts<'tcx> { } impl<'tcx> UpvarSubsts<'tcx> { + /// Returns an iterator over the list of types of captured paths by the closure/generator. + /// In case there was a type error in figuring out the types of the captured path, an + /// empty iterator is returned. #[inline] pub fn upvar_tys(self) -> impl Iterator> + 'tcx { - let tupled_upvars_ty = match self { - UpvarSubsts::Closure(substs) => substs.as_closure().split().tupled_upvars_ty, - UpvarSubsts::Generator(substs) => substs.as_generator().split().tupled_upvars_ty, - }; - tupled_upvars_ty.expect_ty().tuple_fields() + match self { + UpvarSubsts::Closure(substs) => Either::Left(substs.as_closure().upvar_tys()), + UpvarSubsts::Generator(substs) => Either::Right(substs.as_generator().upvar_tys()), + } } #[inline] diff --git a/src/test/ui/issues/issue-77993-1.rs b/src/test/ui/issues/issue-77993-1.rs new file mode 100644 index 0000000000000..515b3bc09f076 --- /dev/null +++ b/src/test/ui/issues/issue-77993-1.rs @@ -0,0 +1,12 @@ +#[derive(Clone)] +struct InGroup { + it: It, + //~^ ERROR cannot find type `It` in this scope + f: F, +} +fn dates_in_year() -> impl Clone { + InGroup { f: |d| d } + //~^ ERROR missing field `it` in initializer of `InGroup<_>` +} + +fn main() {} diff --git a/src/test/ui/issues/issue-77993-1.stderr b/src/test/ui/issues/issue-77993-1.stderr new file mode 100644 index 0000000000000..3dc78ba6f8563 --- /dev/null +++ b/src/test/ui/issues/issue-77993-1.stderr @@ -0,0 +1,16 @@ +error[E0412]: cannot find type `It` in this scope + --> $DIR/issue-77993-1.rs:3:9 + | +LL | it: It, + | ^^ not found in this scope + +error[E0063]: missing field `it` in initializer of `InGroup<_>` + --> $DIR/issue-77993-1.rs:8:5 + | +LL | InGroup { f: |d| d } + | ^^^^^^^ missing `it` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0063, E0412. +For more information about an error, try `rustc --explain E0063`. diff --git a/src/test/ui/issues/issue-77993-2.rs b/src/test/ui/issues/issue-77993-2.rs new file mode 100644 index 0000000000000..4d554a0a1d0e1 --- /dev/null +++ b/src/test/ui/issues/issue-77993-2.rs @@ -0,0 +1,9 @@ +// edition:2018 + +async fn test() -> Result<(), Box> { + macro!(); + //~^ ERROR expected identifier, found `!` + Ok(()) +} + +fn main() {} diff --git a/src/test/ui/issues/issue-77993-2.stderr b/src/test/ui/issues/issue-77993-2.stderr new file mode 100644 index 0000000000000..64b378f83fc03 --- /dev/null +++ b/src/test/ui/issues/issue-77993-2.stderr @@ -0,0 +1,8 @@ +error: expected identifier, found `!` + --> $DIR/issue-77993-2.rs:4:10 + | +LL | macro!(); + | ^ expected identifier + +error: aborting due to previous error + From 47dad31a04724b969d260c32f136bda47fcba63f Mon Sep 17 00:00:00 2001 From: Tyson Nottingham Date: Tue, 27 Oct 2020 15:47:29 -0700 Subject: [PATCH 06/22] rustc_span: represent line bounds with Range --- .../rustc_span/src/caching_source_map_view.rs | 44 ++++++++----------- compiler/rustc_span/src/lib.rs | 10 ++--- 2 files changed, 24 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_span/src/caching_source_map_view.rs b/compiler/rustc_span/src/caching_source_map_view.rs index 2393ae2161371..15dd00fb483e7 100644 --- a/compiler/rustc_span/src/caching_source_map_view.rs +++ b/compiler/rustc_span/src/caching_source_map_view.rs @@ -1,13 +1,25 @@ use crate::source_map::SourceMap; use crate::{BytePos, SourceFile}; use rustc_data_structures::sync::Lrc; +use std::ops::Range; #[derive(Clone)] struct CacheEntry { time_stamp: usize, line_number: usize, - line_start: BytePos, - line_end: BytePos, + // The line's byte position range in the `SourceMap`. This range will fail to contain a valid + // position in certain edge cases. Spans often start/end one past something, and when that + // something is the last character of a file (this can happen when a file doesn't end in a + // newline, for example), we'd still like for the position to be considered within the last + // line. However, it isn't according to the exclusive upper bound of this range. We cannot + // change the upper bound to be inclusive, because for most lines, the upper bound is the same + // as the lower bound of the next line, so there would be an ambiguity. + // + // Since the containment aspect of this range is only used to see whether or not the cache + // entry contains a position, the only ramification of the above is that we will get cache + // misses for these rare positions. A line lookup for the position via `SourceMap::lookup_line` + // after a cache miss will produce the last line number, as desired. + line: Range, file: Lrc, file_index: usize, } @@ -26,8 +38,7 @@ impl<'sm> CachingSourceMapView<'sm> { let entry = CacheEntry { time_stamp: 0, line_number: 0, - line_start: BytePos(0), - line_end: BytePos(0), + line: BytePos(0)..BytePos(0), file: first_file, file_index: 0, }; @@ -47,13 +58,13 @@ impl<'sm> CachingSourceMapView<'sm> { // Check if the position is in one of the cached lines for cache_entry in self.line_cache.iter_mut() { - if line_contains((cache_entry.line_start, cache_entry.line_end), pos) { + if cache_entry.line.contains(&pos) { cache_entry.time_stamp = self.time_stamp; return Some(( cache_entry.file.clone(), cache_entry.line_number, - pos - cache_entry.line_start, + pos - cache_entry.line.start, )); } } @@ -95,30 +106,13 @@ impl<'sm> CachingSourceMapView<'sm> { let line_bounds = cache_entry.file.line_bounds(line_index); cache_entry.line_number = line_index + 1; - cache_entry.line_start = line_bounds.0; - cache_entry.line_end = line_bounds.1; + cache_entry.line = line_bounds; cache_entry.time_stamp = self.time_stamp; - Some((cache_entry.file.clone(), cache_entry.line_number, pos - cache_entry.line_start)) + Some((cache_entry.file.clone(), cache_entry.line_number, pos - cache_entry.line.start)) } } -#[inline] -fn line_contains(line_bounds: (BytePos, BytePos), pos: BytePos) -> bool { - // This condition will be false in one case where we'd rather it wasn't. Spans often start/end - // one past something, and when that something is the last character of a file (this can happen - // when a file doesn't end in a newline, for example), we'd still like for the position to be - // considered within the last line. However, it isn't according to the exclusive upper bound - // below. We cannot change the upper bound to be inclusive, because for most lines, the upper - // bound is the same as the lower bound of the next line, so there would be an ambiguity. - // - // Supposing we only use this function to check whether or not the line cache entry contains - // a position, the only ramification of the above is that we will get cache misses for these - // rare positions. A line lookup for the position via `SourceMap::lookup_line` after a cache - // miss will produce the last line number, as desired. - line_bounds.0 <= pos && pos < line_bounds.1 -} - #[inline] fn file_contains(file: &SourceFile, pos: BytePos) -> bool { // `SourceMap::lookup_source_file_idx` and `SourceFile::contains` both consider the position diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 21a38283f45e6..54b0040dc09cd 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -52,7 +52,7 @@ use std::cell::RefCell; use std::cmp::{self, Ordering}; use std::fmt; use std::hash::Hash; -use std::ops::{Add, Sub}; +use std::ops::{Add, Range, Sub}; use std::path::{Path, PathBuf}; use std::str::FromStr; @@ -1426,16 +1426,16 @@ impl SourceFile { if line_index >= 0 { Some(line_index as usize) } else { None } } - pub fn line_bounds(&self, line_index: usize) -> (BytePos, BytePos) { + pub fn line_bounds(&self, line_index: usize) -> Range { if self.is_empty() { - return (self.start_pos, self.end_pos); + return self.start_pos..self.end_pos; } assert!(line_index < self.lines.len()); if line_index == (self.lines.len() - 1) { - (self.lines[line_index], self.end_pos) + self.lines[line_index]..self.end_pos } else { - (self.lines[line_index], self.lines[line_index + 1]) + self.lines[line_index]..self.lines[line_index + 1] } } From eb8e8bd8bfe492f154ab0438b0067b7a302d2fc1 Mon Sep 17 00:00:00 2001 From: kadmin Date: Mon, 26 Oct 2020 23:25:12 +0000 Subject: [PATCH 07/22] 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 5229571a059a21be2f4a1d87a6641ca855e31143 Mon Sep 17 00:00:00 2001 From: Roxane Date: Tue, 27 Oct 2020 18:32:50 -0400 Subject: [PATCH 08/22] Address comments --- Cargo.lock | 1 - compiler/rustc_middle/Cargo.toml | 1 - compiler/rustc_middle/src/ty/sty.rs | 29 ++++++++++++++++++++--------- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6f925b505334f..65d20190c0db5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3883,7 +3883,6 @@ version = "0.0.0" dependencies = [ "bitflags", "chalk-ir", - "either", "measureme 9.0.0", "polonius-engine", "rustc-rayon-core", diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 0d5fbf16a5810..66532ea02f368 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -8,7 +8,6 @@ edition = "2018" doctest = false [dependencies] -either = "1.5.0" rustc_arena = { path = "../rustc_arena" } bitflags = "1.2.1" tracing = "0.1" diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 96a8902a76c99..564028c33b172 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -5,8 +5,6 @@ use self::InferTy::*; use self::TyKind::*; -use either::Either; - use crate::infer::canonical::Canonical; use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef}; use crate::ty::{ @@ -396,11 +394,13 @@ impl<'tcx> ClosureSubsts<'tcx> { #[inline] pub fn upvar_tys(self) -> impl Iterator> + 'tcx { match self.tupled_upvars_ty().kind() { - TyKind::Error(_) => Either::Left(std::iter::empty()), - TyKind::Tuple(..) => Either::Right(self.tupled_upvars_ty().tuple_fields()), + TyKind::Error(_) => None, + TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()), TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"), ty => bug!("Unexpected representation of upvar types tuple {:?}", ty), } + .into_iter() + .flatten() } /// Returns the tuple type representing the upvars for this closure. @@ -531,11 +531,13 @@ impl<'tcx> GeneratorSubsts<'tcx> { #[inline] pub fn upvar_tys(self) -> impl Iterator> + 'tcx { match self.tupled_upvars_ty().kind() { - TyKind::Error(_) => Either::Left(std::iter::empty()), - TyKind::Tuple(..) => Either::Right(self.tupled_upvars_ty().tuple_fields()), + TyKind::Error(_) => None, + TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()), TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"), ty => bug!("Unexpected representation of upvar types tuple {:?}", ty), } + .into_iter() + .flatten() } /// Returns the tuple type representing the upvars for this generator. @@ -683,10 +685,19 @@ impl<'tcx> UpvarSubsts<'tcx> { /// empty iterator is returned. #[inline] pub fn upvar_tys(self) -> impl Iterator> + 'tcx { - match self { - UpvarSubsts::Closure(substs) => Either::Left(substs.as_closure().upvar_tys()), - UpvarSubsts::Generator(substs) => Either::Right(substs.as_generator().upvar_tys()), + let tupled_tys = match self { + UpvarSubsts::Closure(substs) => substs.as_closure().tupled_upvars_ty(), + UpvarSubsts::Generator(substs) => substs.as_generator().tupled_upvars_ty(), + }; + + match tupled_tys.kind() { + TyKind::Error(_) => None, + TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()), + TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"), + ty => bug!("Unexpected representation of upvar types tuple {:?}", ty), } + .into_iter() + .flatten() } #[inline] From a3bff691344ed94ca5ebab8a043141a0e56931d2 Mon Sep 17 00:00:00 2001 From: Daniel Frampton Date: Tue, 27 Oct 2020 18:05:16 -0700 Subject: [PATCH 09/22] Use unwrapDIPtr because the Scope may be passed as None --- compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 9f8ea7f43d84b..45b9723c4ae71 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -765,7 +765,7 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTypedef( LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Scope) { return wrap(Builder->createTypedef( unwrap(Type), StringRef(Name, NameLen), unwrap(File), - LineNo, unwrap(Scope))); + LineNo, unwrapDIPtr(Scope))); } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType( From 86d6920b9879451b6849756734bd60bc1d3bc39f Mon Sep 17 00:00:00 2001 From: est31 Date: Wed, 28 Oct 2020 01:55:17 +0100 Subject: [PATCH 10/22] =?UTF-8?q?Change=20as=5Fstr=20=E2=86=92=20to=5Fstri?= =?UTF-8?q?ng=20in=20proc=5Fmacro::Ident::span()=20docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no `as_str` function on Ident any more. Also change it to an intra doc link while we're at it. --- library/proc_macro/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 139b3591206e7..b14f4eb16e6bd 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -881,7 +881,7 @@ impl Ident { } /// Returns the span of this `Ident`, encompassing the entire string returned - /// by `as_str`. + /// by [to_string](Self::to_string). #[stable(feature = "proc_macro_lib2", since = "1.29.0")] pub fn span(&self) -> Span { Span(self.0.span()) From 0217edbd292eeb9d5febfda6e33c574ab88cf916 Mon Sep 17 00:00:00 2001 From: Camelid Date: Tue, 27 Oct 2020 20:54:30 -0700 Subject: [PATCH 11/22] 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 12/22] 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 13/22] 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 14/22] 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 15/22] 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 16/22] 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 17/22] 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 18/22] 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 061715604aa1374a087c25721133ef2d18f5091f Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Wed, 28 Oct 2020 13:26:44 -0400 Subject: [PATCH 19/22] 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 20/22] 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 72016f4cebdde11fbb779ffbd5f9066ab54f0816 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 28 Oct 2020 11:14:47 -0700 Subject: [PATCH 21/22] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index dd83ae55c871d..becb4c282b8f3 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit dd83ae55c871d94f060524656abab62ec40b4c40 +Subproject commit becb4c282b8f37469efb8f5beda45a5501f9d367 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 22/22] 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,