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/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() 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/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 3beb328339e7a..869aaa569ca40 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -766,7 +766,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( diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 0fd48d0928257..564028c33b172 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -388,9 +388,19 @@ 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(_) => 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. @@ -515,9 +525,19 @@ 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(_) => 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. @@ -660,13 +680,24 @@ 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, + let tupled_tys = match self { + UpvarSubsts::Closure(substs) => substs.as_closure().tupled_upvars_ty(), + UpvarSubsts::Generator(substs) => substs.as_generator().tupled_upvars_ty(), }; - tupled_upvars_ty.expect_ty().tuple_fields() + + 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] 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, diff --git a/compiler/rustc_mir/src/interpret/validity.rs b/compiler/rustc_mir/src/interpret/validity.rs index f657c6c453832..2d235d65c4d38 100644 --- a/compiler/rustc_mir/src/interpret/validity.rs +++ b/compiler/rustc_mir/src/interpret/validity.rs @@ -579,9 +579,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(..) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 730c16aba8c0b..f13a4329d3b6f 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/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/compiler/rustc_span/src/caching_source_map_view.rs b/compiler/rustc_span/src/caching_source_map_view.rs index 68b0bd1a57418..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 pos >= cache_entry.line_start && pos < cache_entry.line_end { + 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, )); } } @@ -69,13 +80,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; @@ -95,10 +106,19 @@ 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 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 29c686e5d0853..dc82df8484a72 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,24 +1426,33 @@ impl SourceFile { if line_index >= 0 { Some(line_index as usize) } else { None } } - pub fn line_bounds(&self, line_index: usize) -> (BytePos, BytePos) { - if self.start_pos == self.end_pos { - return (self.start_pos, self.end_pos); + pub fn line_bounds(&self, line_index: usize) -> Range { + if self.is_empty() { + 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] } } + /// 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 { 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 } diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 5a4b69cf6fc1b..da7d2b84635ba 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -882,7 +882,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()) 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 /// 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 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 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..0295255d8099c --- /dev/null +++ b/src/test/ui/const-generics/dyn-supertraits.rs @@ -0,0 +1,85 @@ +// 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 { + fn myfun(&self) -> usize; +} +trait Bar : Foo {} +trait Baz: Foo<3> {} + +struct FooType; +struct BarType; +struct BazType; + +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 { + 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; + +impl Foz for FozType {} + +impl Foz for BozType {} +impl Foo<3> for BozType { + fn myfun(&self) -> usize { 9999 } +} +impl Boz for BozType {} + +impl Foz for BokType {} +impl Foo for BokType { + fn myfun(&self) -> usize { N + 2 } +} +impl Bok for BokType {} + +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> {}; + assert!(a(&foo) == 3); + assert!(b(&foo) == 3); + assert!(d(&foo) == 3); + + let bar = BarType::<3> {}; + assert!(a(&bar) == 4); + assert!(b(&bar) == 4); + assert!(d(&bar) == 4); + assert!(e(&bar) == 4); + + let baz = BazType {}; + assert!(a(&baz) == 999); + assert!(b(&baz) == 999); + assert!(d(&baz) == 999); + + let boz = BozType {}; + assert!(a(&boz) == 9999); + assert!(b(&boz) == 9999); + assert!(d(&boz) == 9999); + + let bok = BokType::<3> {}; + assert!(a(&bok) == 5); + assert!(b(&bok) == 5); + assert!(d(&bok) == 5); + assert!(c(BokType::<3> {}) == 5); +} 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..dd82be33a8e80 --- /dev/null +++ b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs @@ -0,0 +1,35 @@ +// check-pass +#![feature(min_const_generics)] +#![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() { + 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 + } +} + +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..4d0cab012f99e --- /dev/null +++ b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr @@ -0,0 +1,30 @@ +warning: cannot use constants which depend on generic parameters in types + --> $DIR/const-evaluatable-unchecked.rs:6: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:17: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: 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 + 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/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`. 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/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 + 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 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 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