diff options
Diffstat (limited to 'compiler')
59 files changed, 307 insertions, 257 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index c27ab810a4c..e2424e7d7ad 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1211,6 +1211,8 @@ impl Expr { } } + ExprKind::Underscore => TyKind::Infer, + // This expression doesn't look like a type syntactically. _ => return None, }; diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 3a65ffe41ae..db066d7c6a5 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -295,6 +295,7 @@ impl TokenKind { match *self { Comma => Some(vec![Dot, Lt, Semi]), Semi => Some(vec![Colon, Comma]), + FatArrow => Some(vec![Eq, RArrow]), _ => None, } } diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 24108f779c8..968e9fa3e24 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -590,7 +590,7 @@ impl<'a> AstValidator<'a> { ) .span_label(self.current_extern_span(), "in this `extern` block") .note(&format!( - "This limitation may be lifted in the future; see issue #{} <https://github.com/rust-lang/rust/issues/{}> for more information", + "this limitation may be lifted in the future; see issue #{} <https://github.com/rust-lang/rust/issues/{}> for more information", n, n, )) .emit(); @@ -683,31 +683,53 @@ impl<'a> AstValidator<'a> { } } + fn emit_e0568(&self, span: Span, ident_span: Span) { + struct_span_err!( + self.session, + span, + E0568, + "auto traits cannot have super traits or lifetime bounds" + ) + .span_label(ident_span, "auto trait cannot have super traits or lifetime bounds") + .span_suggestion( + span, + "remove the super traits or lifetime bounds", + String::new(), + Applicability::MachineApplicable, + ) + .emit(); + } + fn deny_super_traits(&self, bounds: &GenericBounds, ident_span: Span) { - if let [first @ last] | [first, .., last] = &bounds[..] { - let span = first.span().to(last.span()); - struct_span_err!(self.session, span, E0568, "auto traits cannot have super traits") - .span_label(ident_span, "auto trait cannot have super traits") - .span_suggestion( - span, - "remove the super traits", - String::new(), - Applicability::MachineApplicable, - ) - .emit(); + if let [.., last] = &bounds[..] { + let span = ident_span.shrink_to_hi().to(last.span()); + self.emit_e0568(span, ident_span); + } + } + + fn deny_where_clause(&self, where_clause: &WhereClause, ident_span: Span) { + if !where_clause.predicates.is_empty() { + self.emit_e0568(where_clause.span, ident_span); } } fn deny_items(&self, trait_items: &[P<AssocItem>], ident_span: Span) { if !trait_items.is_empty() { let spans: Vec<_> = trait_items.iter().map(|i| i.ident.span).collect(); + let total_span = trait_items.first().unwrap().span.to(trait_items.last().unwrap().span); struct_span_err!( self.session, spans, E0380, - "auto traits cannot have methods or associated items" + "auto traits cannot have associated items" + ) + .span_suggestion( + total_span, + "remove these associated items", + String::new(), + Applicability::MachineApplicable, ) - .span_label(ident_span, "auto trait cannot have items") + .span_label(ident_span, "auto trait cannot have associated items") .emit(); } } @@ -1184,6 +1206,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { // Auto traits cannot have generics, super traits nor contain items. self.deny_generic_params(generics, item.ident.span); self.deny_super_traits(bounds, item.ident.span); + self.deny_where_clause(&generics.where_clause, item.ident.span); self.deny_items(trait_items, item.ident.span); } self.no_questions_in_bounds(bounds, "supertraits", true); diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 43032ae81cb..e6260157d11 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -2,7 +2,7 @@ #![feature(bool_to_option)] #![feature(box_patterns)] -#![feature(const_panic)] +#![cfg_attr(bootstrap, feature(const_panic))] #![feature(crate_visibility_modifier)] #![feature(format_args_capture)] #![feature(in_band_lifetimes)] diff --git a/compiler/rustc_borrowck/src/member_constraints.rs b/compiler/rustc_borrowck/src/member_constraints.rs index 2e2578df011..f22d355e613 100644 --- a/compiler/rustc_borrowck/src/member_constraints.rs +++ b/compiler/rustc_borrowck/src/member_constraints.rs @@ -144,7 +144,7 @@ impl<R> MemberConstraintSet<'tcx, R> where R: Copy + Hash + Eq, { - crate fn all_indices(&self) -> impl Iterator<Item = NllMemberConstraintIndex> { + crate fn all_indices(&self) -> impl Iterator<Item = NllMemberConstraintIndex> + '_ { self.constraints.indices() } diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 65d6e3a4ae5..734a5b4972b 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -497,7 +497,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } /// Returns an iterator over all the region indices. - pub fn regions(&self) -> impl Iterator<Item = RegionVid> { + pub fn regions(&self) -> impl Iterator<Item = RegionVid> + '_ { self.definitions.indices() } diff --git a/compiler/rustc_builtin_macros/src/concat_idents.rs b/compiler/rustc_builtin_macros/src/concat_idents.rs index 209158ce392..53a456b69ac 100644 --- a/compiler/rustc_builtin_macros/src/concat_idents.rs +++ b/compiler/rustc_builtin_macros/src/concat_idents.rs @@ -12,7 +12,7 @@ pub fn expand_concat_idents<'cx>( tts: TokenStream, ) -> Box<dyn base::MacResult + 'cx> { if tts.is_empty() { - cx.span_err(sp, "concat_idents! takes 1 or more arguments."); + cx.span_err(sp, "concat_idents! takes 1 or more arguments"); return DummyResult::any(sp); } @@ -22,7 +22,7 @@ pub fn expand_concat_idents<'cx>( match e { TokenTree::Token(Token { kind: token::Comma, .. }) => {} _ => { - cx.span_err(sp, "concat_idents! expecting comma."); + cx.span_err(sp, "concat_idents! expecting comma"); return DummyResult::any(sp); } } @@ -34,7 +34,7 @@ pub fn expand_concat_idents<'cx>( } } - cx.span_err(sp, "concat_idents! requires ident args."); + cx.span_err(sp, "concat_idents! requires ident args"); return DummyResult::any(sp); } } diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index 99544ddb66e..bbca07085ea 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -382,7 +382,7 @@ fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic { .note( "errors in this attribute were erroneously \ allowed and will become a hard error in a \ - future release.", + future release", ) .emit(); ShouldPanic::Yes(None) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index c5deb11edd0..b15efcd0dc2 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -416,6 +416,11 @@ pub fn llvm_global_features(sess: &Session) -> Vec<String> { // -Ctarget-features features.extend(sess.opts.cg.target_feature.split(',').flat_map(&filter)); + // FIXME: Move outline-atomics to target definition when earliest supported LLVM is 12. + if get_version() >= (12, 0, 0) && sess.target.llvm_target.contains("aarch64-unknown-linux") { + features.push("+outline-atomics".to_string()); + } + features } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 57d92005a56..fd5cd269a3a 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -887,8 +887,6 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> { // At this point, we are calling a function, `callee`, whose `DefId` is known... if is_lang_panic_fn(tcx, callee) { - self.check_op(ops::Panic); - // `begin_panic` and `panic_display` are generic functions that accept // types other than str. Check to enforce that only str can be used in // const-eval. diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index 1d0ee949a22..f08f51ec627 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -368,23 +368,6 @@ impl NonConstOp for MutDeref { } } -#[derive(Debug)] -pub struct Panic; -impl NonConstOp for Panic { - fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status { - Status::Unstable(sym::const_panic) - } - - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { - feature_err( - &ccx.tcx.sess.parse_sess, - sym::const_panic, - span, - &format!("panicking in {}s is unstable", ccx.const_kind()), - ) - } -} - /// A call to a `panic()` lang item where the first argument is _not_ a `&str`. #[derive(Debug)] pub struct PanicNonStr; @@ -407,7 +390,7 @@ impl NonConstOp for RawPtrComparison { let mut err = ccx .tcx .sess - .struct_span_err(span, "pointers cannot be reliably compared during const eval."); + .struct_span_err(span, "pointers cannot be reliably compared during const eval"); err.note( "see issue #53020 <https://github.com/rust-lang/rust/issues/53020> \ for more information", @@ -443,7 +426,7 @@ impl NonConstOp for RawPtrToIntCast { let mut err = ccx .tcx .sess - .struct_span_err(span, "pointers cannot be cast to integers during const eval."); + .struct_span_err(span, "pointers cannot be cast to integers during const eval"); err.note("at compile-time, pointers do not have an integer value"); err.note( "avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior", diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index b1f04bfbf0a..94e115ed498 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -7,12 +7,11 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![feature(allow_internal_unstable)] #![feature(array_windows)] #![feature(associated_type_bounds)] #![feature(auto_traits)] #![feature(bool_to_option)] -#![feature(const_panic)] +#![cfg_attr(bootstrap, feature(const_panic))] #![feature(control_flow_enum)] #![feature(core_intrinsics)] #![feature(extend_one)] diff --git a/compiler/rustc_data_structures/src/sso/map.rs b/compiler/rustc_data_structures/src/sso/map.rs index e249886e9bc..2de05cd4e56 100644 --- a/compiler/rustc_data_structures/src/sso/map.rs +++ b/compiler/rustc_data_structures/src/sso/map.rs @@ -31,7 +31,7 @@ const SSO_ARRAY_SIZE: usize = 8; // // Missing HashMap API: // all hasher-related -// try_reserve (unstable) +// try_reserve // shrink_to (unstable) // drain_filter (unstable) // into_keys/into_values (unstable) diff --git a/compiler/rustc_data_structures/src/sso/set.rs b/compiler/rustc_data_structures/src/sso/set.rs index 23cff0206c5..29baf4e1ddb 100644 --- a/compiler/rustc_data_structures/src/sso/set.rs +++ b/compiler/rustc_data_structures/src/sso/set.rs @@ -13,7 +13,7 @@ use super::map::SsoHashMap; // // Missing HashSet API: // all hasher-related -// try_reserve (unstable) +// try_reserve // shrink_to (unstable) // drain_filter (unstable) // replace diff --git a/compiler/rustc_driver/src/pretty.rs b/compiler/rustc_driver/src/pretty.rs index e52eef0fcbd..8e8bea9525d 100644 --- a/compiler/rustc_driver/src/pretty.rs +++ b/compiler/rustc_driver/src/pretty.rs @@ -88,7 +88,7 @@ trait PrinterSupport: pprust::PpAnn { /// Produces the pretty-print annotation object. /// /// (Rust does not yet support upcasting from a trait object to - /// an object for one of its super-traits.) + /// an object for one of its supertraits.) fn pp_ann(&self) -> &dyn pprust::PpAnn; } @@ -104,7 +104,7 @@ trait HirPrinterSupport<'hir>: pprust_hir::PpAnn { /// Produces the pretty-print annotation object. /// /// (Rust does not yet support upcasting from a trait object to - /// an object for one of its super-traits.) + /// an object for one of its supertraits.) fn pp_ann(&self) -> &dyn pprust_hir::PpAnn; } diff --git a/compiler/rustc_error_codes/src/error_codes/E0222.md b/compiler/rustc_error_codes/src/error_codes/E0222.md index fbf1b8d7033..f929f219af4 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0222.md +++ b/compiler/rustc_error_codes/src/error_codes/E0222.md @@ -16,9 +16,9 @@ pub trait BoxCar : Box + Vehicle {} fn dent_object<COLOR>(c: dyn BoxCar<Color=COLOR>) {} // Invalid constraint ``` -In this example, `BoxCar` has two super-traits: `Vehicle` and `Box`. Both of +In this example, `BoxCar` has two supertraits: `Vehicle` and `Box`. Both of these traits define an associated type `Color`. `BoxCar` inherits two types -with that name from both super-traits. Because of this, we need to use the +with that name from both supertraits. Because of this, we need to use the fully qualified path syntax to refer to the appropriate `Color` associated type, either `<BoxCar as Vehicle>::Color` or `<BoxCar as Box>::Color`, but this syntax is not allowed to be used in a function signature. diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 69e0e3a0136..2ef0e0f6b1e 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -297,6 +297,8 @@ declare_features! ( (accepted, arbitrary_enum_discriminant, "1.56.0", Some(60553), None), /// Allows macro attributes to observe output of `#[derive]`. (accepted, macro_attributes_in_derive_output, "1.57.0", Some(81119), None), + /// Allows panicking during const eval (producing compile-time errors). + (accepted, const_panic, "1.57.0", Some(51999), None), // ------------------------------------------------------------------------- // feature-group-end: accepted features diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index f8b865e615c..eae7f7854ec 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -425,9 +425,6 @@ declare_features! ( /// Allows using the `amdgpu-kernel` ABI. (active, abi_amdgpu_kernel, "1.29.0", Some(51575), None), - /// Allows panicking during const eval (producing compile-time errors). - (active, const_panic, "1.30.0", Some(51999), None), - /// Allows `#[marker]` on certain traits allowing overlapping implementations. (active, marker_trait_attr, "1.30.0", Some(29864), None), diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index 0093fa5e562..a72a27e07bd 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -2,9 +2,8 @@ #![feature(bench_black_box)] #![feature(extend_one)] #![feature(iter_zip)] -#![feature(unboxed_closures)] +#![feature(min_specialization)] #![feature(test)] -#![feature(fn_traits)] pub mod bit_set; pub mod vec; diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 8535a7c866d..88315246834 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -3,9 +3,9 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use std::fmt; use std::fmt::Debug; use std::hash::Hash; -use std::iter::{self, FromIterator}; +use std::iter::FromIterator; use std::marker::PhantomData; -use std::ops::{Index, IndexMut, Range, RangeBounds}; +use std::ops::{Index, IndexMut, RangeBounds}; use std::slice; use std::vec; @@ -124,7 +124,9 @@ macro_rules! newtype_index { #[inline] $v const fn from_usize(value: usize) -> Self { - // FIXME: replace with `assert!(value <= ($max as usize));` once `const_panic` is stable + #[cfg(not(bootstrap))] + assert!(value <= ($max as usize)); + #[cfg(bootstrap)] [()][(value > ($max as usize)) as usize]; unsafe { Self::from_u32_unchecked(value as u32) @@ -133,7 +135,9 @@ macro_rules! newtype_index { #[inline] $v const fn from_u32(value: u32) -> Self { - // FIXME: replace with `assert!(value <= $max);` once `const_panic` is stable + #[cfg(not(bootstrap))] + assert!(value <= $max); + #[cfg(bootstrap)] [()][(value > $max) as usize]; unsafe { Self::from_u32_unchecked(value) @@ -518,8 +522,6 @@ impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexVec<I, T> { } } -pub type Enumerated<I, J> = iter::Map<iter::Enumerate<J>, IntoIdx<I>>; - impl<I: Idx, T> IndexVec<I, T> { #[inline] pub fn new() -> Self { @@ -596,8 +598,10 @@ impl<I: Idx, T> IndexVec<I, T> { } #[inline] - pub fn into_iter_enumerated(self) -> Enumerated<I, vec::IntoIter<T>> { - self.raw.into_iter().enumerate().map(IntoIdx { _marker: PhantomData }) + pub fn into_iter_enumerated( + self, + ) -> impl DoubleEndedIterator<Item = (I, T)> + ExactSizeIterator { + self.raw.into_iter().enumerate().map(|(n, t)| (I::new(n), t)) } #[inline] @@ -606,13 +610,15 @@ impl<I: Idx, T> IndexVec<I, T> { } #[inline] - pub fn iter_enumerated(&self) -> Enumerated<I, slice::Iter<'_, T>> { - self.raw.iter().enumerate().map(IntoIdx { _marker: PhantomData }) + pub fn iter_enumerated( + &self, + ) -> impl DoubleEndedIterator<Item = (I, &T)> + ExactSizeIterator + '_ { + self.raw.iter().enumerate().map(|(n, t)| (I::new(n), t)) } #[inline] - pub fn indices(&self) -> iter::Map<Range<usize>, IntoIdx<I>> { - (0..self.len()).map(IntoIdx { _marker: PhantomData }) + pub fn indices(&self) -> impl DoubleEndedIterator<Item = I> + ExactSizeIterator + 'static { + (0..self.len()).map(|n| I::new(n)) } #[inline] @@ -621,8 +627,10 @@ impl<I: Idx, T> IndexVec<I, T> { } #[inline] - pub fn iter_enumerated_mut(&mut self) -> Enumerated<I, slice::IterMut<'_, T>> { - self.raw.iter_mut().enumerate().map(IntoIdx { _marker: PhantomData }) + pub fn iter_enumerated_mut( + &mut self, + ) -> impl DoubleEndedIterator<Item = (I, &mut T)> + ExactSizeIterator + '_ { + self.raw.iter_mut().enumerate().map(|(n, t)| (I::new(n), t)) } #[inline] @@ -638,7 +646,7 @@ impl<I: Idx, T> IndexVec<I, T> { &'a mut self, range: R, ) -> impl Iterator<Item = (I, T)> + 'a { - self.raw.drain(range).enumerate().map(IntoIdx { _marker: PhantomData }) + self.raw.drain(range).enumerate().map(|(n, t)| (I::new(n), t)) } #[inline] @@ -832,36 +840,5 @@ impl<'a, I: Idx, T> IntoIterator for &'a mut IndexVec<I, T> { } } -pub struct IntoIdx<I: Idx> { - _marker: PhantomData<fn(&I)>, -} -impl<I: Idx, T> FnOnce<((usize, T),)> for IntoIdx<I> { - type Output = (I, T); - - extern "rust-call" fn call_once(self, ((n, t),): ((usize, T),)) -> Self::Output { - (I::new(n), t) - } -} - -impl<I: Idx, T> FnMut<((usize, T),)> for IntoIdx<I> { - extern "rust-call" fn call_mut(&mut self, ((n, t),): ((usize, T),)) -> Self::Output { - (I::new(n), t) - } -} - -impl<I: Idx> FnOnce<(usize,)> for IntoIdx<I> { - type Output = I; - - extern "rust-call" fn call_once(self, (n,): (usize,)) -> Self::Output { - I::new(n) - } -} - -impl<I: Idx> FnMut<(usize,)> for IntoIdx<I> { - extern "rust-call" fn call_mut(&mut self, (n,): (usize,)) -> Self::Output { - I::new(n) - } -} - #[cfg(test)] mod tests; diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index a221746f975..2d12ea94a0b 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -437,12 +437,18 @@ pub fn configure_and_expand( }); // Add all buffered lints from the `ParseSess` to the `Session`. - sess.parse_sess.buffered_lints.with_lock(|buffered_lints| { - info!("{} parse sess buffered_lints", buffered_lints.len()); - for early_lint in buffered_lints.drain(..) { - resolver.lint_buffer().add_early_lint(early_lint); - } - }); + // The ReplaceBodyWithLoop pass may have deleted some AST nodes, potentially + // causing a delay_span_bug later if a buffered lint refers to such a deleted + // AST node (issue #87308). Since everybody_loops is for pretty-printing only, + // anyway, we simply skip all buffered lints here. + if !matches!(sess.opts.pretty, Some(PpMode::Source(PpSourceMode::EveryBodyLoops))) { + sess.parse_sess.buffered_lints.with_lock(|buffered_lints| { + info!("{} parse sess buffered_lints", buffered_lints.len()); + for early_lint in buffered_lints.drain(..) { + resolver.lint_buffer().add_early_lint(early_lint); + } + }); + } Ok(krate) } diff --git a/compiler/rustc_lint/src/array_into_iter.rs b/compiler/rustc_lint/src/array_into_iter.rs index 1facd973754..d147148ac71 100644 --- a/compiler/rustc_lint/src/array_into_iter.rs +++ b/compiler/rustc_lint/src/array_into_iter.rs @@ -124,7 +124,7 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter { let mut diag = lint.build(&format!( "this method call resolves to `<&{} as IntoIterator>::into_iter` \ (due to backwards compatibility), \ - but will resolve to <{} as IntoIterator>::into_iter in Rust 2021.", + but will resolve to <{} as IntoIterator>::into_iter in Rust 2021", target, target, )); diag.span_suggestion( diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 9b6493222e6..5656fff2fcb 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -918,7 +918,7 @@ impl EarlyLintPass for AnonymousParameters { lint.build( "anonymous parameters are deprecated and will be \ - removed in the next edition.", + removed in the next edition", ) .span_suggestion( arg.pat.span, @@ -1629,9 +1629,9 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { let predicates = cx.tcx.predicates_of(item.def_id); for &(predicate, span) in predicates.predicates { let predicate_kind_name = match predicate.kind().skip_binder() { - Trait(..) => "Trait", + Trait(..) => "trait", TypeOutlives(..) | - RegionOutlives(..) => "Lifetime", + RegionOutlives(..) => "lifetime", // Ignore projections, as they can only be global // if the trait bound is global diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 10285272130..17eb0054584 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -26,7 +26,6 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![cfg_attr(test, feature(test))] #![feature(array_windows)] #![feature(bool_to_option)] #![feature(box_patterns)] diff --git a/compiler/rustc_lint/src/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs index 301e607fc58..9b4ee148df4 100644 --- a/compiler/rustc_lint/src/non_ascii_idents.rs +++ b/compiler/rustc_lint/src/non_ascii_idents.rs @@ -331,9 +331,9 @@ impl EarlyLintPass for NonAsciiIdents { for ((sp, ch_list), script_set) in lint_reports { cx.struct_span_lint(MIXED_SCRIPT_CONFUSABLES, sp, |lint| { let message = format!( - "The usage of Script Group `{}` in this crate consists solely of mixed script confusables", + "the usage of Script Group `{}` in this crate consists solely of mixed script confusables", script_set); - let mut note = "The usage includes ".to_string(); + let mut note = "the usage includes ".to_string(); for (idx, ch) in ch_list.into_iter().enumerate() { if idx != 0 { note += ", "; @@ -341,8 +341,7 @@ impl EarlyLintPass for NonAsciiIdents { let char_info = format!("'{}' (U+{:04X})", ch, ch as u32); note += &char_info; } - note += "."; - lint.build(&message).note(¬e).note("Please recheck to make sure their usages are indeed what you want.").emit() + lint.build(&message).note(¬e).note("please recheck to make sure their usages are indeed what you want").emit() }); } } diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 03344973bb3..bcddc4f3d76 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -437,12 +437,13 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { if let hir::Node::Pat(parent_pat) = cx.tcx.hir().get(cx.tcx.hir().get_parent_node(hid)) { if let PatKind::Struct(_, field_pats, _) = &parent_pat.kind { - for field in field_pats.iter() { - if field.ident != ident { - // Only check if a new name has been introduced, to avoid warning - // on both the struct definition and this pattern. - self.check_snake_case(cx, "variable", &ident); - } + if field_pats + .iter() + .any(|field| !field.is_shorthand && field.pat.hir_id == p.hir_id) + { + // Only check if a new name has been introduced, to avoid warning + // on both the struct definition and this pattern. + self.check_snake_case(cx, "variable", &ident); } return; } diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index 7ad36973f46..005017185c1 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -455,28 +455,28 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { // Pass on the fatal_cycle modifier if let Some(fatal_cycle) = &modifiers.fatal_cycle { - attributes.push(quote! { #fatal_cycle }); + attributes.push(quote! { (#fatal_cycle) }); }; // Pass on the storage modifier if let Some(ref ty) = modifiers.storage { let span = ty.span(); - attributes.push(quote_spanned! {span=> storage(#ty) }); + attributes.push(quote_spanned! {span=> (storage #ty) }); }; // Pass on the cycle_delay_bug modifier if let Some(cycle_delay_bug) = &modifiers.cycle_delay_bug { - attributes.push(quote! { #cycle_delay_bug }); + attributes.push(quote! { (#cycle_delay_bug) }); }; // Pass on the no_hash modifier if let Some(no_hash) = &modifiers.no_hash { - attributes.push(quote! { #no_hash }); + attributes.push(quote! { (#no_hash) }); }; // Pass on the anon modifier if let Some(anon) = &modifiers.anon { - attributes.push(quote! { #anon }); + attributes.push(quote! { (#anon) }); }; // Pass on the eval_always modifier if let Some(eval_always) = &modifiers.eval_always { - attributes.push(quote! { #eval_always }); + attributes.push(quote! { (#eval_always) }); }; // This uses the span of the query definition for the commas, diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 48d8cdf57dc..3a05020c0b5 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -878,7 +878,7 @@ impl<'a> CrateLoader<'a> { "no global memory allocator found but one is \ required; link to std or \ add `#[global_allocator]` to a static item \ - that implements the GlobalAlloc trait.", + that implements the GlobalAlloc trait", ); } self.cstore.allocator_kind = Some(AllocatorKind::Default); diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index b6922e0d72a..80963c9658e 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -1030,7 +1030,8 @@ impl CrateError { add, ); err.help(&format!( - "please recompile that crate using this compiler ({})", + "please recompile that crate using this compiler ({}) \ + (consider running `cargo clean` first)", rustc_version(), )); let mismatches = locator.crate_rejections.via_version.iter(); diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 39709e1bd07..93226b6a2f2 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -319,13 +319,13 @@ impl Collector<'tcx> { self.tcx.sess.err(&format!( "renaming of the library `{}` was specified, \ however this crate contains no `#[link(...)]` \ - attributes referencing this library.", + attributes referencing this library", lib.name )); } else if !renames.insert(&lib.name) { self.tcx.sess.err(&format!( "multiple renamings were \ - specified for library `{}` .", + specified for library `{}`", lib.name )); } diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index e788dd4be85..07d42902be5 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -140,11 +140,11 @@ macro_rules! is_eval_always_attr { } macro_rules! contains_anon_attr { - ($($attr:ident $(($($attr_args:tt)*))* ),*) => ({$(is_anon_attr!($attr) | )* false}); + ($(($attr:ident $($attr_args:tt)* )),*) => ({$(is_anon_attr!($attr) | )* false}); } macro_rules! contains_eval_always_attr { - ($($attr:ident $(($($attr_args:tt)*))* ),*) => ({$(is_eval_always_attr!($attr) | )* false}); + ($(($attr:ident $($attr_args:tt)* )),*) => ({$(is_eval_always_attr!($attr) | )* false}); } #[allow(non_upper_case_globals)] diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 02f0294c8ad..594ac899f15 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -41,20 +41,17 @@ #![feature(once_cell)] #![feature(min_specialization)] #![feature(trusted_len)] -#![feature(test)] #![feature(in_band_lifetimes)] #![feature(crate_visibility_modifier)] #![feature(associated_type_bounds)] #![feature(rustc_attrs)] #![feature(half_open_range_patterns)] -#![feature(exclusive_range_pattern)] #![feature(control_flow_enum)] #![feature(associated_type_defaults)] #![feature(iter_zip)] #![feature(thread_local_const_init)] #![feature(trusted_step)] #![feature(try_blocks)] -#![feature(try_reserve)] #![feature(try_reserve_kind)] #![feature(nonzero_ops)] #![recursion_limit = "512"] diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 8b70692960d..434008ecb1f 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -1,10 +1,10 @@ -// This module contains some shared code for encoding and decoding various -// things from the `ty` module, and in particular implements support for -// "shorthands" which allow to have pointers back into the already encoded -// stream instead of re-encoding the same thing twice. -// -// The functionality in here is shared between persisting to crate metadata and -// persisting to incr. comp. caches. +//! This module contains some shared code for encoding and decoding various +//! things from the `ty` module, and in particular implements support for +//! "shorthands" which allow to have pointers back into the already encoded +//! stream instead of re-encoding the same thing twice. +//! +//! The functionality in here is shared between persisting to crate metadata and +//! persisting to incr. comp. caches. use crate::arena::ArenaAllocatable; use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos}; diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index a2adecd9636..01847d352c3 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2117,7 +2117,7 @@ impl<'tcx> TyCtxt<'tcx> { }) } - /// Computes the def-ids of the transitive super-traits of `trait_def_id`. This (intentionally) + /// Computes the def-ids of the transitive supertraits of `trait_def_id`. This (intentionally) /// does not compute the full elaborated super-predicates but just the set of def-ids. It is used /// to identify which traits may define a given associated type to help avoid cycle errors. /// Returns a `DefId` iterator. diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 8991ad32ae8..8983fda6ced 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -599,7 +599,7 @@ impl<'tcx> Predicate<'tcx> { // where both `'x` and `'b` would have a DB index of 1. // The substitution from the input trait-ref is therefore going to be // `'a => 'x` (where `'x` has a DB index of 1). - // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an + // - The supertrait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an // early-bound parameter and `'b' is a late-bound parameter with a // DB index of 1. // - If we replace `'a` with `'x` from the input, it too will have diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index 154b26464a8..e5fd38252da 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -111,11 +111,11 @@ macro_rules! query_storage { ([][$K:ty, $V:ty]) => { <DefaultCacheSelector as CacheSelector<$K, $V>>::Cache }; - ([storage($ty:ty) $($rest:tt)*][$K:ty, $V:ty]) => { + ([(storage $ty:ty) $($rest:tt)*][$K:ty, $V:ty]) => { <$ty as CacheSelector<$K, $V>>::Cache }; - ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => { - query_storage!([$($($modifiers)*)*][$($args)*]) + ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => { + query_storage!([$($modifiers)*][$($args)*]) }; } diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index 72c4e27cbea..402391b87ea 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -2,7 +2,7 @@ #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(box_syntax)] -#![feature(const_panic)] +#![cfg_attr(bootstrap, feature(const_panic))] #![feature(exact_size_is_empty)] #![feature(in_band_lifetimes)] #![feature(iter_zip)] diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs index 699ec4bbff8..f2b34159382 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs @@ -1,6 +1,5 @@ -use core::slice::Iter; use rustc_data_structures::fx::FxHashMap; -use rustc_index::vec::{Enumerated, IndexVec}; +use rustc_index::vec::IndexVec; use rustc_middle::mir::*; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; use rustc_span::Span; @@ -337,7 +336,9 @@ impl MovePathLookup { /// An enumerated iterator of `local`s and their associated /// `MovePathIndex`es. - pub fn iter_locals_enumerated(&self) -> Enumerated<Local, Iter<'_, MovePathIndex>> { + pub fn iter_locals_enumerated( + &self, + ) -> impl DoubleEndedIterator<Item = (Local, &MovePathIndex)> + ExactSizeIterator { self.locals.iter_enumerated() } } diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index b1b31e0784c..0ca640cd7b1 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -1,7 +1,7 @@ #![feature(box_patterns)] #![feature(box_syntax)] #![feature(crate_visibility_modifier)] -#![feature(const_panic)] +#![cfg_attr(bootstrap, feature(const_panic))] #![feature(in_band_lifetimes)] #![feature(iter_zip)] #![feature(map_try_insert)] diff --git a/compiler/rustc_mir_transform/src/simplify_try.rs b/compiler/rustc_mir_transform/src/simplify_try.rs index fd36671b36f..e436d73226a 100644 --- a/compiler/rustc_mir_transform/src/simplify_try.rs +++ b/compiler/rustc_mir_transform/src/simplify_try.rs @@ -544,6 +544,12 @@ pub struct SimplifyBranchSame; impl<'tcx> MirPass<'tcx> for SimplifyBranchSame { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + // This optimization is disabled by default for now due to + // soundness concerns; see issue #89485 and PR #89489. + if !tcx.sess.opts.debugging_opts.unsound_mir_opts { + return; + } + trace!("Running SimplifyBranchSame on {:?}", body.source); let finder = SimplifyBranchSameOptimizationFinder { body, tcx }; let opts = finder.find(); @@ -706,12 +712,24 @@ impl<'a, 'tcx> SimplifyBranchSameOptimizationFinder<'a, 'tcx> { let helper = |rhs: &Rvalue<'tcx>, place: &Place<'tcx>, variant_index: &VariantIdx, + switch_value: u128, side_to_choose| { let place_type = place.ty(self.body, self.tcx).ty; let adt = match *place_type.kind() { ty::Adt(adt, _) if adt.is_enum() => adt, _ => return StatementEquality::NotEqual, }; + // We need to make sure that the switch value that targets the bb with + // SetDiscriminant is the same as the variant discriminant. + let variant_discr = adt.discriminant_for_variant(self.tcx, *variant_index).val; + if variant_discr != switch_value { + trace!( + "NO: variant discriminant {} does not equal switch value {}", + variant_discr, + switch_value + ); + return StatementEquality::NotEqual; + } let variant_is_fieldless = adt.variants[*variant_index].fields.is_empty(); if !variant_is_fieldless { trace!("NO: variant {:?} was not fieldless", variant_index); @@ -740,20 +758,28 @@ impl<'a, 'tcx> SimplifyBranchSameOptimizationFinder<'a, 'tcx> { ( StatementKind::Assign(box (_, rhs)), StatementKind::SetDiscriminant { place, variant_index }, - ) - // we need to make sure that the switch value that targets the bb with SetDiscriminant (y), is the same as the variant index - if Some(variant_index.index() as u128) == y_target_and_value.value => { + ) if y_target_and_value.value.is_some() => { // choose basic block of x, as that has the assign - helper(rhs, place, variant_index, x_target_and_value.target) + helper( + rhs, + place, + variant_index, + y_target_and_value.value.unwrap(), + x_target_and_value.target, + ) } ( StatementKind::SetDiscriminant { place, variant_index }, StatementKind::Assign(box (_, rhs)), - ) - // we need to make sure that the switch value that targets the bb with SetDiscriminant (x), is the same as the variant index - if Some(variant_index.index() as u128) == x_target_and_value.value => { + ) if x_target_and_value.value.is_some() => { // choose basic block of y, as that has the assign - helper(rhs, place, variant_index, y_target_and_value.target) + helper( + rhs, + place, + variant_index, + x_target_and_value.value.unwrap(), + y_target_and_value.target, + ) } _ => { trace!("NO: statements `{:?}` and `{:?}` not considered equal", x, y); diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index c5417ea23f2..79f46be73f6 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2322,7 +2322,24 @@ impl<'a> Parser<'a> { None }; let arrow_span = this.token.span; - this.expect(&token::FatArrow)?; + if let Err(mut err) = this.expect(&token::FatArrow) { + // We might have a `=>` -> `=` or `->` typo (issue #89396). + if TokenKind::FatArrow + .similar_tokens() + .map_or(false, |similar_tokens| similar_tokens.contains(&this.token.kind)) + { + err.span_suggestion( + this.token.span, + "try using a fat arrow here", + "=>".to_string(), + Applicability::MaybeIncorrect, + ); + err.emit(); + this.bump(); + } else { + return Err(err); + } + } let arm_start_span = this.token.span; let expr = this.parse_expr_res(Restrictions::STMT_EXPR, None).map_err(|mut err| { diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs index bb5be90cd40..c6c32e69aab 100644 --- a/compiler/rustc_passes/src/weak_lang_items.rs +++ b/compiler/rustc_passes/src/weak_lang_items.rs @@ -66,8 +66,8 @@ fn verify<'tcx>(tcx: TyCtxt<'tcx>, items: &lang_items::LanguageItems) { tcx.sess.err("`#[panic_handler]` function required, but not found"); } else if item == LangItem::Oom { if !tcx.features().default_alloc_error_handler { - tcx.sess.err("`#[alloc_error_handler]` function required, but not found."); - tcx.sess.note_without_error("Use `#![feature(default_alloc_error_handler)]` for a default error handler."); + tcx.sess.err("`#[alloc_error_handler]` function required, but not found"); + tcx.sess.note_without_error("Use `#![feature(default_alloc_error_handler)]` for a default error handler"); } } else { tcx.sess.err(&format!("language item required, but not found: `{}`", name)); diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index bb686b5ef3f..818b798ab55 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -253,17 +253,17 @@ macro_rules! handle_cycle_error { $error.emit(); Value::from_cycle_error($tcx) }}; - ([fatal_cycle $($rest:tt)*][$tcx:expr, $error:expr]) => {{ + ([(fatal_cycle) $($rest:tt)*][$tcx:expr, $error:expr]) => {{ $error.emit(); $tcx.sess.abort_if_errors(); unreachable!() }}; - ([cycle_delay_bug $($rest:tt)*][$tcx:expr, $error:expr]) => {{ + ([(cycle_delay_bug) $($rest:tt)*][$tcx:expr, $error:expr]) => {{ $error.delay_as_bug(); Value::from_cycle_error($tcx) }}; - ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => { - handle_cycle_error!([$($($modifiers)*)*][$($args)*]) + ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => { + handle_cycle_error!([$($modifiers)*][$($args)*]) }; } @@ -271,11 +271,11 @@ macro_rules! is_anon { ([]) => {{ false }}; - ([anon $($rest:tt)*]) => {{ + ([(anon) $($rest:tt)*]) => {{ true }}; - ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*]) => { - is_anon!([$($($modifiers)*)*]) + ([$other:tt $($modifiers:tt)*]) => { + is_anon!([$($modifiers)*]) }; } @@ -283,11 +283,11 @@ macro_rules! is_eval_always { ([]) => {{ false }}; - ([eval_always $($rest:tt)*]) => {{ + ([(eval_always) $($rest:tt)*]) => {{ true }}; - ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*]) => { - is_eval_always!([$($($modifiers)*)*]) + ([$other:tt $($modifiers:tt)*]) => { + is_eval_always!([$($modifiers)*]) }; } @@ -295,11 +295,11 @@ macro_rules! hash_result { ([][$hcx:expr, $result:expr]) => {{ dep_graph::hash_result($hcx, &$result) }}; - ([no_hash $($rest:tt)*][$hcx:expr, $result:expr]) => {{ + ([(no_hash) $($rest:tt)*][$hcx:expr, $result:expr]) => {{ None }}; - ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => { - hash_result!([$($($modifiers)*)*][$($args)*]) + ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => { + hash_result!([$($modifiers)*][$($args)*]) }; } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index bb34776f0b0..9be568b2cf1 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -1339,7 +1339,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { }; if module.is_trait() { - self.r.session.span_err(import.span, "items in traits are not importable."); + self.r.session.span_err(import.span, "items in traits are not importable"); return; } else if ptr::eq(module, import.parent_scope.module) { return; diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs index c47d8b934cf..f4567b33483 100644 --- a/compiler/rustc_save_analysis/src/dump_visitor.rs +++ b/compiler/rustc_save_analysis/src/dump_visitor.rs @@ -682,7 +682,7 @@ impl<'tcx> DumpVisitor<'tcx> { ); } - // super-traits + // supertraits for super_bound in trait_refs.iter() { let (def_id, sub_span) = match *super_bound { hir::GenericBound::Trait(ref trait_ref, _) => ( diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index fbcc3bf2c48..bf04154a3da 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1384,7 +1384,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) { // Cannot enable crt-static with sanitizers on Linux if sess.crt_static(None) && !sess.opts.debugging_opts.sanitizer.is_empty() { sess.err( - "Sanitizer is incompatible with statically linked libc, \ + "sanitizer is incompatible with statically linked libc, \ disable it using `-C target-feature=-crt-static`", ); } diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index e75c52555b9..23d5d575d94 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -15,7 +15,6 @@ #![feature(exhaustive_patterns)] #![feature(min_specialization)] #![feature(step_trait)] -#![feature(unchecked_math)] use std::path::{Path, PathBuf}; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 93ddec61dc4..6447e4cbf2b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -516,7 +516,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { }); let unit_obligation = obligation.with(predicate.to_predicate(tcx)); if self.predicate_may_hold(&unit_obligation) { - err.note("this trait is implemented for `()`."); + err.note("this trait is implemented for `()`"); err.note( "this error might have been caused by changes to \ Rust's type-inference algorithm (see issue #48950 \ diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index b7f1f64cbfd..cd678b96446 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -10,7 +10,9 @@ use crate::traits::normalize_projection_type; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::sync::Lrc; -use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder, Style}; +use rustc_errors::{ + error_code, pluralize, struct_span_err, Applicability, DiagnosticBuilder, Style, +}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; @@ -2273,7 +2275,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { parent_trait_ref = child_trait_ref; } if count > 0 { - err.note(&format!("{} redundant requirements hidden", count)); + err.note(&format!( + "{} redundant requirement{} hidden", + count, + pluralize!(count) + )); err.note(&format!( "required because of the requirements on the impl of `{}` for `{}`", parent_trait_ref.print_only_trait_path(), diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index b3c9cf4c173..b31d6d68b0a 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -64,7 +64,9 @@ pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind; pub use self::specialize::{specialization_graph, translate_substs, OverlapError}; pub use self::structural_match::search_for_structural_match_violation; pub use self::structural_match::NonStructuralMatchTy; -pub use self::util::{elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs}; +pub use self::util::{ + elaborate_obligations, elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs, +}; pub use self::util::{expand_trait_aliases, TraitAliasExpander}; pub use self::util::{ get_vtable_index_of_object_method, impl_item_is_final, predicate_for_trait_def, upcast_choices, @@ -623,7 +625,7 @@ fn dump_vtable_entries<'tcx>( trait_ref: ty::PolyTraitRef<'tcx>, entries: &[VtblEntry<'tcx>], ) { - let msg = format!("Vtable entries for `{}`: {:#?}", trait_ref, entries); + let msg = format!("vtable entries for `{}`: {:#?}", trait_ref, entries); tcx.sess.struct_span_err(sp, &msg).emit(); } diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 313571274c3..60f8e196bcb 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -6,8 +6,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(control_flow_enum)] -#![feature(half_open_range_patterns)] -#![feature(exclusive_range_pattern)] #![feature(nll)] #![recursion_limit = "256"] diff --git a/compiler/rustc_typeck/src/astconv/errors.rs b/compiler/rustc_typeck/src/astconv/errors.rs index 695132281c6..ec75e4a55d4 100644 --- a/compiler/rustc_typeck/src/astconv/errors.rs +++ b/compiler/rustc_typeck/src/astconv/errors.rs @@ -199,7 +199,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { /// When there are any missing associated types, emit an E0191 error and attempt to supply a /// reasonable suggestion on how to write it. For the case of multiple associated types in the - /// same trait bound have the same name (as they come from different super-traits), we instead + /// same trait bound have the same name (as they come from different supertraits), we instead /// emit a generic note suggesting using a `where` clause to constraint instead. pub(crate) fn complain_about_missing_associated_types( &self, @@ -340,7 +340,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { using the fully-qualified path to the associated types"; if !where_constraints.is_empty() && suggestions.is_empty() { // If there are duplicates associated type names and a single trait bound do not - // use structured suggestion, it means that there are multiple super-traits with + // use structured suggestion, it means that there are multiple supertraits with // the same associated type name. err.help(where_msg); } diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index e492fd44185..889b68773c2 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1319,7 +1319,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ); first_trait.label_with_exp_info(&mut err, "first non-auto trait", "first use"); err.help(&format!( - "consider creating a new trait with all of these as super-traits and using that \ + "consider creating a new trait with all of these as supertraits and using that \ trait here instead: `trait NewTrait: {} {{}}`", regular_traits .iter() diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index e34b8d998b1..07e542b70b9 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -1484,21 +1484,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { fcx.emit_coerce_suggestions(&mut err, expr, found, expected, None); } - // Error possibly reported in `check_assign` so avoid emitting error again. - let assign_to_bool = expression - // #67273: Use initial expected type as opposed to `expected`. - // Otherwise we end up using prior coercions in e.g. a `match` expression: - // ``` - // match i { - // 0 => true, // Because of this... - // 1 => i = 1, // ...`expected == bool` now, but not when checking `i = 1`. - // _ => (), - // }; - // ``` - .filter(|e| fcx.is_assign_to_bool(e, self.expected_ty())) - .is_some(); - - err.emit_unless(assign_to_bool || unsized_return); + err.emit_unless(unsized_return); self.final_ty = Some(fcx.tcx.ty_error()); } diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs index dcfbaff7ec7..1a2931b9377 100644 --- a/compiler/rustc_typeck/src/check/demand.rs +++ b/compiler/rustc_typeck/src/check/demand.rs @@ -145,12 +145,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let expr_ty = self.resolve_vars_with_obligations(checked_ty); let mut err = self.report_mismatched_types(&cause, expected, expr_ty, e); - if self.is_assign_to_bool(expr, expected) { - // Error reported in `check_assign` so avoid emitting error again. - err.delay_as_bug(); - return (expected, None); - } - self.emit_coerce_suggestions(&mut err, expr, expr_ty, expected, expected_ty_expr); (expected, Some(err)) @@ -172,14 +166,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - /// Returns whether the expected type is `bool` and the expression is `x = y`. - pub fn is_assign_to_bool(&self, expr: &hir::Expr<'_>, expected: Ty<'tcx>) -> bool { - if let hir::ExprKind::Assign(..) = expr.kind { - return expected == self.tcx.types.bool; - } - false - } - /// If the expected type is an enum (Issue #55250) with any variants whose /// sole field is of the found type, suggest such variants. (Issue #42764) fn suggest_compatible_variants( diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 09a55937cc5..676e751376a 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -92,8 +92,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let expr = expr.peel_drop_temps(); self.suggest_deref_ref_or_into(&mut err, expr, expected_ty, ty, None); extend_err(&mut err); - // Error possibly reported in `check_assign` so avoid emitting error again. - err.emit_unless(self.is_assign_to_bool(expr, expected_ty)); + err.emit(); } ty } diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 9d6db32be63..44d6f076f5d 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -964,7 +964,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let trait_ref = ty::TraitRef::new(trait_def_id, trait_substs); if self.tcx.is_trait_alias(trait_def_id) { - // For trait aliases, assume all super-traits are relevant. + // For trait aliases, assume all supertraits are relevant. let bounds = iter::once(ty::Binder::dummy(trait_ref)); self.elaborate_bounds(bounds, |this, new_trait_ref, item| { let new_trait_ref = this.erase_late_bound_regions(new_trait_ref); diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index 0650291bacb..98bec3f6eac 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -449,16 +449,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ti: TopInfo<'tcx>, ) -> Ty<'tcx> { let calc_side = |opt_expr: Option<&'tcx hir::Expr<'tcx>>| match opt_expr { - None => (None, None), + None => None, Some(expr) => { let ty = self.check_expr(expr); - // Check that the end-point is of numeric or char type. - let fail = !(ty.is_numeric() || ty.is_char() || ty.references_error()); - (Some(ty), Some((fail, ty, expr.span))) + // Check that the end-point is possibly of numeric or char type. + // The early check here is not for correctness, but rather better + // diagnostics (e.g. when `&str` is being matched, `expected` will + // be peeled to `str` while ty here is still `&str`, if we don't + // err ealy here, a rather confusing unification error will be + // emitted instead). + let fail = + !(ty.is_numeric() || ty.is_char() || ty.is_ty_var() || ty.references_error()); + Some((fail, ty, expr.span)) } }; - let (lhs_ty, lhs) = calc_side(lhs); - let (rhs_ty, rhs) = calc_side(rhs); + let mut lhs = calc_side(lhs); + let mut rhs = calc_side(rhs); if let (Some((true, ..)), _) | (_, Some((true, ..))) = (lhs, rhs) { // There exists a side that didn't meet our criteria that the end-point @@ -467,25 +473,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return self.tcx.ty_error(); } - // Now that we know the types can be unified we find the unified type - // and use it to type the entire expression. - let common_type = self.resolve_vars_if_possible(lhs_ty.or(rhs_ty).unwrap_or(expected)); - + // Unify each side with `expected`. // Subtyping doesn't matter here, as the value is some kind of scalar. - let demand_eqtype = |x, y| { - if let Some((_, x_ty, x_span)) = x { + let demand_eqtype = |x: &mut _, y| { + if let Some((ref mut fail, x_ty, x_span)) = *x { if let Some(mut err) = self.demand_eqtype_pat_diag(x_span, expected, x_ty, ti) { if let Some((_, y_ty, y_span)) = y { self.endpoint_has_type(&mut err, y_span, y_ty); } err.emit(); + *fail = true; }; } }; - demand_eqtype(lhs, rhs); - demand_eqtype(rhs, lhs); + demand_eqtype(&mut lhs, rhs); + demand_eqtype(&mut rhs, lhs); + + if let (Some((true, ..)), _) | (_, Some((true, ..))) = (lhs, rhs) { + return self.tcx.ty_error(); + } - common_type + // Find the unified type and check if it's of numeric or char type again. + // This check is needed if both sides are inference variables. + // We require types to be resolved here so that we emit inference failure + // rather than "_ is not a char or numeric". + let ty = self.structurally_resolved_type(span, expected); + if !(ty.is_numeric() || ty.is_char() || ty.references_error()) { + if let Some((ref mut fail, _, _)) = lhs { + *fail = true; + } + if let Some((ref mut fail, _, _)) = rhs { + *fail = true; + } + self.emit_err_pat_range(span, lhs, rhs); + return self.tcx.ty_error(); + } + ty } fn endpoint_has_type(&self, err: &mut DiagnosticBuilder<'_>, span: Span, ty: Ty<'_>) { @@ -512,10 +535,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { E0029, "only `char` and numeric types are allowed in range patterns" ); - let msg = |ty| format!("this is of type `{}` but it should be `char` or numeric", ty); + let msg = |ty| { + let ty = self.resolve_vars_if_possible(ty); + format!("this is of type `{}` but it should be `char` or numeric", ty) + }; let mut one_side_err = |first_span, first_ty, second: Option<(bool, Ty<'tcx>, Span)>| { err.span_label(first_span, &msg(first_ty)); if let Some((_, ty, sp)) = second { + let ty = self.resolve_vars_if_possible(ty); self.endpoint_has_type(&mut err, sp, ty); } }; diff --git a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs index 8ecd6034ad6..f4bb5761c19 100644 --- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs @@ -74,7 +74,7 @@ use rustc_infer::infer::{InferCtxt, RegionckMode, TyCtxtInferExt}; use rustc_infer::traits::specialization_graph::Node; use rustc_middle::ty::subst::{GenericArg, InternalSubsts, SubstsRef}; use rustc_middle::ty::trait_def::TraitSpecializationKind; -use rustc_middle::ty::{self, InstantiatedPredicates, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, TyCtxt, TypeFoldable}; use rustc_span::Span; use rustc_trait_selection::traits::{self, translate_substs, wf}; @@ -294,13 +294,27 @@ fn check_predicates<'tcx>( span: Span, ) { let tcx = infcx.tcx; - let impl1_predicates = tcx.predicates_of(impl1_def_id).instantiate(tcx, impl1_substs); + let impl1_predicates: Vec<_> = traits::elaborate_predicates( + tcx, + tcx.predicates_of(impl1_def_id).instantiate(tcx, impl1_substs).predicates.into_iter(), + ) + .map(|obligation| obligation.predicate) + .collect(); + let mut impl2_predicates = if impl2_node.is_from_trait() { // Always applicable traits have to be always applicable without any // assumptions. - InstantiatedPredicates::empty() + Vec::new() } else { - tcx.predicates_of(impl2_node.def_id()).instantiate(tcx, impl2_substs) + traits::elaborate_predicates( + tcx, + tcx.predicates_of(impl2_node.def_id()) + .instantiate(tcx, impl2_substs) + .predicates + .into_iter(), + ) + .map(|obligation| obligation.predicate) + .collect() }; debug!( "check_always_applicable(\nimpl1_predicates={:?},\nimpl2_predicates={:?}\n)", @@ -322,13 +336,12 @@ fn check_predicates<'tcx>( // which is sound because we forbid impls like the following // // impl<D: Debug> AlwaysApplicable for D { } - let always_applicable_traits = - impl1_predicates.predicates.iter().copied().filter(|&predicate| { - matches!( - trait_predicate_kind(tcx, predicate), - Some(TraitSpecializationKind::AlwaysApplicable) - ) - }); + let always_applicable_traits = impl1_predicates.iter().copied().filter(|&predicate| { + matches!( + trait_predicate_kind(tcx, predicate), + Some(TraitSpecializationKind::AlwaysApplicable) + ) + }); // Include the well-formed predicates of the type parameters of the impl. for arg in tcx.impl_trait_ref(impl1_def_id).unwrap().substs { @@ -340,18 +353,19 @@ fn check_predicates<'tcx>( arg, span, ) { - impl2_predicates - .predicates - .extend(obligations.into_iter().map(|obligation| obligation.predicate)) + impl2_predicates.extend( + traits::elaborate_obligations(tcx, obligations) + .map(|obligation| obligation.predicate), + ) } } - impl2_predicates.predicates.extend( + impl2_predicates.extend( traits::elaborate_predicates(tcx, always_applicable_traits) .map(|obligation| obligation.predicate), ); - for predicate in impl1_predicates.predicates { - if !impl2_predicates.predicates.contains(&predicate) { + for predicate in impl1_predicates { + if !impl2_predicates.contains(&predicate) { check_specialization_on(tcx, predicate, span) } } |
