diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 03c390b4bd427..91d132eb34350 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -290,6 +290,11 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } attributes::apply_to_callsite(result, llvm::AttributePlace::Function, &{ attrs }); + // Switch to the 'normal' basic block if we did an `invoke` instead of a `call` + if let Some((dest, _, _)) = dest_catch_funclet { + self.switch_to_block(dest); + } + // Write results to outputs for (idx, op) in operands.iter().enumerate() { if let InlineAsmOperandRef::Out { reg, place: Some(place), .. } diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index d93c9a79c6556..07878defa8ccd 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -347,8 +347,7 @@ impl<'tcx> Ty<'tcx> { impl<'tcx> TyCtxt<'tcx> { pub fn note_and_explain_type_err( self, - // FIXME(eddyb) rename this since it's no longer a `DiagnosticBuilder`. - db: &mut Diagnostic, + diag: &mut Diagnostic, err: &TypeError<'tcx>, cause: &ObligationCause<'tcx>, sp: Span, @@ -360,12 +359,12 @@ impl<'tcx> TyCtxt<'tcx> { ArgumentSorts(values, _) | Sorts(values) => { match (values.expected.kind(), values.found.kind()) { (ty::Closure(..), ty::Closure(..)) => { - db.note("no two closures, even if identical, have the same type"); - db.help("consider boxing your closure and/or using it as a trait object"); + diag.note("no two closures, even if identical, have the same type"); + diag.help("consider boxing your closure and/or using it as a trait object"); } (ty::Opaque(..), ty::Opaque(..)) => { // Issue #63167 - db.note("distinct uses of `impl Trait` result in different opaque types"); + diag.note("distinct uses of `impl Trait` result in different opaque types"); } (ty::Float(_), ty::Infer(ty::IntVar(_))) if let Ok( @@ -374,7 +373,7 @@ impl<'tcx> TyCtxt<'tcx> { ) = self.sess.source_map().span_to_snippet(sp) => { if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') { - db.span_suggestion( + diag.span_suggestion( sp, "use a float literal", format!("{}.0", snippet), @@ -386,30 +385,30 @@ impl<'tcx> TyCtxt<'tcx> { let generics = self.generics_of(body_owner_def_id); let e_span = self.def_span(generics.type_param(expected, self).def_id); if !sp.contains(e_span) { - db.span_label(e_span, "expected type parameter"); + diag.span_label(e_span, "expected type parameter"); } let f_span = self.def_span(generics.type_param(found, self).def_id); if !sp.contains(f_span) { - db.span_label(f_span, "found type parameter"); + diag.span_label(f_span, "found type parameter"); } - db.note( + diag.note( "a type parameter was expected, but a different one was found; \ you might be missing a type parameter or trait bound", ); - db.note( + diag.note( "for more information, visit \ https://doc.rust-lang.org/book/ch10-02-traits.html\ #traits-as-parameters", ); } (ty::Projection(_), ty::Projection(_)) => { - db.note("an associated type was expected, but a different one was found"); + diag.note("an associated type was expected, but a different one was found"); } (ty::Param(p), ty::Projection(proj)) | (ty::Projection(proj), ty::Param(p)) => { let generics = self.generics_of(body_owner_def_id); let p_span = self.def_span(generics.type_param(p, self).def_id); if !sp.contains(p_span) { - db.span_label(p_span, "this type parameter"); + diag.span_label(p_span, "this type parameter"); } let hir = self.hir(); let mut note = true; @@ -444,14 +443,14 @@ impl<'tcx> TyCtxt<'tcx> { note = !suggest_constraining_type_param( self, generics, - db, + diag, &format!("{}", proj.self_ty()), &path, None, ); } if note { - db.note("you might be missing a type parameter or trait bound"); + diag.note("you might be missing a type parameter or trait bound"); } } (ty::Param(p), ty::Dynamic(..) | ty::Opaque(..)) @@ -459,11 +458,11 @@ impl<'tcx> TyCtxt<'tcx> { let generics = self.generics_of(body_owner_def_id); let p_span = self.def_span(generics.type_param(p, self).def_id); if !sp.contains(p_span) { - db.span_label(p_span, "this type parameter"); + diag.span_label(p_span, "this type parameter"); } - db.help("type parameters must be constrained to match other types"); - if self.sess.teach(&db.get_code().unwrap()) { - db.help( + diag.help("type parameters must be constrained to match other types"); + if self.sess.teach(&diag.get_code().unwrap()) { + diag.help( "given a type parameter `T` and a method `foo`: ``` trait Trait<T> { fn foo(&self) -> T; } @@ -489,7 +488,7 @@ impl<T> Trait<T> for X { ```", ); } - db.note( + diag.note( "for more information, visit \ https://doc.rust-lang.org/book/ch10-02-traits.html\ #traits-as-parameters", @@ -499,9 +498,9 @@ impl<T> Trait<T> for X { let generics = self.generics_of(body_owner_def_id); let p_span = self.def_span(generics.type_param(p, self).def_id); if !sp.contains(p_span) { - db.span_label(p_span, "this type parameter"); + diag.span_label(p_span, "this type parameter"); } - db.help(&format!( + diag.help(&format!( "every closure has a distinct type and so could not always match the \ caller-chosen type of parameter `{}`", p @@ -511,12 +510,12 @@ impl<T> Trait<T> for X { let generics = self.generics_of(body_owner_def_id); let p_span = self.def_span(generics.type_param(p, self).def_id); if !sp.contains(p_span) { - db.span_label(p_span, "this type parameter"); + diag.span_label(p_span, "this type parameter"); } } (ty::Projection(proj_ty), _) => { self.expected_projection( - db, + diag, proj_ty, values, body_owner_def_id, @@ -529,19 +528,19 @@ impl<T> Trait<T> for X { values.found, values.expected, ); if !(self.suggest_constraining_opaque_associated_type( - db, + diag, &msg, proj_ty, values.expected, ) || self.suggest_constraint( - db, + diag, &msg, body_owner_def_id, proj_ty, values.expected, )) { - db.help(&msg); - db.note( + diag.help(&msg); + diag.note( "for more information, visit \ https://doc.rust-lang.org/book/ch19-03-advanced-traits.html", ); @@ -560,7 +559,7 @@ impl<T> Trait<T> for X { CyclicTy(ty) => { // Watch out for various cases of cyclic types and try to explain. if ty.is_closure() || ty.is_generator() { - db.note( + diag.note( "closures cannot capture themselves or take themselves as argument;\n\ this error may be the result of a recent compiler bug-fix,\n\ see issue #46062 <https://github.com/rust-lang/rust/issues/46062>\n\ @@ -574,10 +573,10 @@ impl<T> Trait<T> for X { .iter() .filter(|attr| attr.has_name(sym::target_feature)) .map(|attr| attr.span); - db.note( + diag.note( "functions with `#[target_feature]` can only be coerced to `unsafe` function pointers" ); - db.span_labels(target_spans, "`#[target_feature]` added here"); + diag.span_labels(target_spans, "`#[target_feature]` added here"); } _ => {} } @@ -585,8 +584,7 @@ impl<T> Trait<T> for X { fn suggest_constraint( self, - // FIXME(eddyb) rename this since it's no longer a `DiagnosticBuilder`. - db: &mut Diagnostic, + diag: &mut Diagnostic, msg: &str, body_owner_def_id: DefId, proj_ty: &ty::ProjectionTy<'tcx>, @@ -623,7 +621,7 @@ impl<T> Trait<T> for X { } if self.constrain_generic_bound_associated_type_structured_suggestion( - db, + diag, &trait_ref, pred.bounds, &assoc, @@ -642,7 +640,7 @@ impl<T> Trait<T> for X { { // This is type param `A` in `<A as T>::Foo`. return self.constrain_generic_bound_associated_type_structured_suggestion( - db, + diag, &trait_ref, param.bounds, &assoc, @@ -673,8 +671,7 @@ impl<T> Trait<T> for X { /// fn that returns the type. fn expected_projection( self, - // FIXME(eddyb) rename this since it's no longer a `DiagnosticBuilder`. - db: &mut Diagnostic, + diag: &mut Diagnostic, proj_ty: &ty::ProjectionTy<'tcx>, values: &ExpectedFound<Ty<'tcx>>, body_owner_def_id: DefId, @@ -712,7 +709,7 @@ impl<T> Trait<T> for X { // want the more general suggestion later in this method about "consider constraining // the associated type or calling a method that returns the associated type". let point_at_assoc_fn = self.point_at_methods_that_satisfy_associated_type( - db, + diag, assoc.container.id(), current_method_ident, proj_ty.item_def_id, @@ -720,33 +717,36 @@ impl<T> Trait<T> for X { ); // Possibly suggest constraining the associated type to conform to the // found type. - if self.suggest_constraint(db, &msg, body_owner_def_id, proj_ty, values.found) + if self.suggest_constraint(diag, &msg, body_owner_def_id, proj_ty, values.found) || point_at_assoc_fn { return; } } - self.suggest_constraining_opaque_associated_type(db, &msg, proj_ty, values.found); + self.suggest_constraining_opaque_associated_type(diag, &msg, proj_ty, values.found); - if self.point_at_associated_type(db, body_owner_def_id, values.found) { + if self.point_at_associated_type(diag, body_owner_def_id, values.found) { return; } if !impl_comparison { // Generic suggestion when we can't be more specific. if callable_scope { - db.help(&format!("{} or calling a method that returns `{}`", msg, values.expected)); + diag.help(&format!( + "{} or calling a method that returns `{}`", + msg, values.expected + )); } else { - db.help(&msg); + diag.help(&msg); } - db.note( + diag.note( "for more information, visit \ https://doc.rust-lang.org/book/ch19-03-advanced-traits.html", ); } - if self.sess.teach(&db.get_code().unwrap()) { - db.help( + if self.sess.teach(&diag.get_code().unwrap()) { + diag.help( "given an associated type `T` and a method `foo`: ``` trait Trait { @@ -769,8 +769,7 @@ fn foo(&self) -> Self::T { String::new() } /// a return type. This can occur when dealing with `TryStream` (#71035). fn suggest_constraining_opaque_associated_type( self, - // FIXME(eddyb) rename this since it's no longer a `DiagnosticBuilder`. - db: &mut Diagnostic, + diag: &mut Diagnostic, msg: &str, proj_ty: &ty::ProjectionTy<'tcx>, ty: Ty<'tcx>, @@ -790,7 +789,7 @@ fn foo(&self) -> Self::T { String::new() } let (trait_ref, assoc_substs) = proj_ty.trait_ref_and_own_substs(self); self.constrain_generic_bound_associated_type_structured_suggestion( - db, + diag, &trait_ref, opaque_hir_ty.bounds, assoc, @@ -806,8 +805,7 @@ fn foo(&self) -> Self::T { String::new() } fn point_at_methods_that_satisfy_associated_type( self, - // FIXME(eddyb) rename this since it's no longer a `DiagnosticBuilder`. - db: &mut Diagnostic, + diag: &mut Diagnostic, assoc_container_id: DefId, current_method_ident: Option<Symbol>, proj_ty_item_def_id: DefId, @@ -854,7 +852,7 @@ fn foo(&self) -> Self::T { String::new() } for (sp, label) in methods.into_iter() { span.push_span_label(sp, label); } - db.span_help(span, &msg); + diag.span_help(span, &msg); return true; } false @@ -862,8 +860,7 @@ fn foo(&self) -> Self::T { String::new() } fn point_at_associated_type( self, - // FIXME(eddyb) rename this since it's no longer a `DiagnosticBuilder`. - db: &mut Diagnostic, + diag: &mut Diagnostic, body_owner_def_id: DefId, found: Ty<'tcx>, ) -> bool { @@ -887,7 +884,7 @@ fn foo(&self) -> Self::T { String::new() } if let hir::Defaultness::Default { has_value: true } = item.defaultness { if self.type_of(item.id.def_id) == found { - db.span_label( + diag.span_label( item.span, "associated type defaults can't be assumed inside the \ trait defining them", @@ -907,7 +904,7 @@ fn foo(&self) -> Self::T { String::new() } for item in &items[..] { if let hir::AssocItemKind::Type = item.kind { if self.type_of(item.id.def_id) == found { - db.span_label(item.span, "expected this associated type"); + diag.span_label(item.span, "expected this associated type"); return true; } } @@ -927,8 +924,7 @@ fn foo(&self) -> Self::T { String::new() } /// type is defined on a supertrait of the one present in the bounds. fn constrain_generic_bound_associated_type_structured_suggestion( self, - // FIXME(eddyb) rename this since it's no longer a `DiagnosticBuilder`. - db: &mut Diagnostic, + diag: &mut Diagnostic, trait_ref: &ty::TraitRef<'tcx>, bounds: hir::GenericBounds<'_>, assoc: &ty::AssocItem, @@ -958,15 +954,21 @@ fn foo(&self) -> Self::T { String::new() } _ => return false, }; - self.constrain_associated_type_structured_suggestion(db, span, assoc, assoc_substs, ty, msg) + self.constrain_associated_type_structured_suggestion( + diag, + span, + assoc, + assoc_substs, + ty, + msg, + ) } /// Given a span corresponding to a bound, provide a structured suggestion to set an /// associated type to a given type `ty`. fn constrain_associated_type_structured_suggestion( self, - // FIXME(eddyb) rename this since it's no longer a `DiagnosticBuilder`. - db: &mut Diagnostic, + diag: &mut Diagnostic, span: Span, assoc: &ty::AssocItem, assoc_substs: &[ty::GenericArg<'tcx>], @@ -984,7 +986,7 @@ fn foo(&self) -> Self::T { String::new() } let item_args = self.format_generic_args(assoc_substs); (span.shrink_to_hi(), format!("<{}{} = {}>", assoc.ident(self), item_args, ty)) }; - db.span_suggestion_verbose(span, msg, sugg, MaybeIncorrect); + diag.span_suggestion_verbose(span, msg, sugg, MaybeIncorrect); return true; } false diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 1e943f0e44abd..3ec63d102fab6 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1875,8 +1875,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { /// Returns whether to add `'static` lifetime to the suggested lifetime list. crate fn report_elision_failure( &mut self, - // FIXME(eddyb) rename this since it's no longer a `DiagnosticBuilder`. - db: &mut Diagnostic, + diag: &mut Diagnostic, params: &[ElisionFailureInfo], ) -> bool { let mut m = String::new(); @@ -1891,7 +1890,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { let ElisionFailureInfo { parent, index, lifetime_count: n, have_bound_regions, span } = info; - db.span_label(span, ""); + diag.span_label(span, ""); let help_name = if let Some(ident) = parent.and_then(|body| self.tcx.hir().body(body).params[index].pat.simple_ident()) { @@ -1923,27 +1922,27 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { } if len == 0 { - db.help( + diag.help( "this function's return type contains a borrowed value, \ but there is no value for it to be borrowed from", ); true } else if elided_len == 0 { - db.help( + diag.help( "this function's return type contains a borrowed value with \ an elided lifetime, but the lifetime cannot be derived from \ the arguments", ); true } else if elided_len == 1 { - db.help(&format!( + diag.help(&format!( "this function's return type contains a borrowed value, \ but the signature does not say which {} it is borrowed from", m )); false } else { - db.help(&format!( + diag.help(&format!( "this function's return type contains a borrowed value, \ but the signature does not say whether it is borrowed from {}", m 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 ac98dd5801e40..0cb70de241596 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -440,6 +440,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } } + if Some(trait_ref.def_id()) == tcx.lang_items().drop_trait() + && predicate_is_const + { + err.note("`~const Drop` was renamed to `~const Destruct`"); + err.note("See <https://github.com/rust-lang/rust/pull/94901> for more details"); + } + let explanation = if let ObligationCauseCode::MainFunctionType = obligation.cause.code() { 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 c920c80d1bba1..ead1f0126c465 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1083,20 +1083,31 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let parent_node = hir.get_parent_node(obligation.cause.body_id); let node = hir.find(parent_node); if let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. })) = node - && let body = hir.body(*body_id) - && let hir::ExprKind::Block(blk, _) = &body.value.kind + && let hir::ExprKind::Block(blk, _) = &hir.body(*body_id).value.kind && sig.decl.output.span().overlaps(span) && blk.expr.is_none() - && *trait_pred.self_ty().skip_binder().kind() == ty::Tuple(ty::List::empty()) - // FIXME(estebank): When encountering a method with a trait - // bound not satisfied in the return type with a body that has - // no return, suggest removal of semicolon on last statement. - // Once that is added, close #54771. + && trait_pred.self_ty().skip_binder().is_unit() && let Some(stmt) = blk.stmts.last() - && let hir::StmtKind::Semi(_) = stmt.kind + && let hir::StmtKind::Semi(expr) = stmt.kind + // Only suggest this if the expression behind the semicolon implements the predicate + && let Some(typeck_results) = self.in_progress_typeck_results + && let Some(ty) = typeck_results.borrow().expr_ty_opt(expr) + && self.predicate_may_hold(&self.mk_trait_obligation_with_new_self_ty(obligation.param_env, trait_pred, ty)) { - let sp = self.tcx.sess.source_map().end_point(stmt.span); - err.span_label(sp, "consider removing this semicolon"); + err.span_label( + expr.span, + &format!( + "this expression has type `{}`, which implements `{}`", + ty, + trait_pred.print_modifiers_and_trait_path() + ) + ); + err.span_suggestion( + self.tcx.sess.source_map().end_point(stmt.span), + "remove this semicolon", + String::new(), + Applicability::MachineApplicable + ); return true; } false diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 1cc1460750a23..f6a5243274cd2 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -936,7 +936,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { err.span_suggestion_short( span_semi, - "consider removing this semicolon", + "remove this semicolon", String::new(), Applicability::MachineApplicable, ); diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index dcae58ae590f1..488671d8d8d19 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2593,14 +2593,15 @@ impl<T, A: Allocator> VecDeque<T, A> { /// ``` /// /// If you want to insert an item to a sorted deque, while maintaining - /// sort order: + /// sort order, consider using [`partition_point`]: /// /// ``` /// use std::collections::VecDeque; /// /// let mut deque: VecDeque<_> = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into(); /// let num = 42; - /// let idx = deque.binary_search(&num).unwrap_or_else(|x| x); + /// let idx = deque.partition_point(|&x| x < num); + /// // The above is equivalent to `let idx = deque.binary_search(&num).unwrap_or_else(|x| x);` /// deque.insert(idx, num); /// assert_eq!(deque, &[0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]); /// ``` @@ -2744,6 +2745,19 @@ impl<T, A: Allocator> VecDeque<T, A> { /// assert!(deque.iter().take(i).all(|&x| x < 5)); /// assert!(deque.iter().skip(i).all(|&x| !(x < 5))); /// ``` + /// + /// If you want to insert an item to a sorted deque, while maintaining + /// sort order: + /// + /// ``` + /// use std::collections::VecDeque; + /// + /// let mut deque: VecDeque<_> = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into(); + /// let num = 42; + /// let idx = deque.partition_point(|&x| x < num); + /// deque.insert(idx, num); + /// assert_eq!(deque, &[0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]); + /// ``` #[stable(feature = "vecdeque_binary_search", since = "1.54.0")] pub fn partition_point<P>(&self, mut pred: P) -> usize where diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 2240c297a2531..2a4030de00b4e 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -2331,12 +2331,13 @@ impl<T> [T] { /// ``` /// /// If you want to insert an item to a sorted vector, while maintaining - /// sort order: + /// sort order, consider using [`partition_point`]: /// /// ``` /// let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; /// let num = 42; - /// let idx = s.binary_search(&num).unwrap_or_else(|x| x); + /// let idx = s.partition_point(|&x| x < num); + /// // The above is equivalent to `let idx = s.binary_search(&num).unwrap_or_else(|x| x);` /// s.insert(idx, num); /// assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]); /// ``` @@ -3743,6 +3744,17 @@ impl<T> [T] { /// assert!(v[..i].iter().all(|&x| x < 5)); /// assert!(v[i..].iter().all(|&x| !(x < 5))); /// ``` + /// + /// If you want to insert an item to a sorted vector, while maintaining + /// sort order: + /// + /// ``` + /// let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; + /// let num = 42; + /// let idx = s.partition_point(|&x| x < num); + /// s.insert(idx, num); + /// assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]); + /// ``` #[stable(feature = "partition_point", since = "1.52.0")] #[must_use] pub fn partition_point<P>(&self, mut pred: P) -> usize diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 32def67ed65e3..b3c4a52c414b2 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -31,18 +31,20 @@ All tier 1 targets with host tools support the full standard library. target | notes -------|------- `aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.2, glibc 2.17+) [^missing-stack-probes] -`i686-pc-windows-gnu` | 32-bit MinGW (Windows 7+) -`i686-pc-windows-msvc` | 32-bit MSVC (Windows 7+) +`i686-pc-windows-gnu` | 32-bit MinGW (Windows 7+) [^windows-support] +`i686-pc-windows-msvc` | 32-bit MSVC (Windows 7+) [^windows-support] `i686-unknown-linux-gnu` | 32-bit Linux (kernel 2.6.32+, glibc 2.11+) `x86_64-apple-darwin` | 64-bit macOS (10.7+, Lion+) -`x86_64-pc-windows-gnu` | 64-bit MinGW (Windows 7+) -`x86_64-pc-windows-msvc` | 64-bit MSVC (Windows 7+) +`x86_64-pc-windows-gnu` | 64-bit MinGW (Windows 7+) [^windows-support] +`x86_64-pc-windows-msvc` | 64-bit MSVC (Windows 7+) [^windows-support] `x86_64-unknown-linux-gnu` | 64-bit Linux (kernel 2.6.32+, glibc 2.11+) [^missing-stack-probes]: Stack probes support is missing on `aarch64-unknown-linux-gnu`, but it's planned to be implemented in the near future. The implementation is tracked on [issue #77071][77071]. +[^windows-support]: Only Windows 10 currently undergoes automated testing. Earlier versions of Windows rely on testing and support from the community. + [77071]: https://github.com/rust-lang/rust/issues/77071 ## Tier 1 diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e6ef3c26e290a..85a3e05e8b213 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -302,23 +302,13 @@ impl<'a> Clean<Option<WherePredicate>> for ty::Predicate<'a> { impl<'a> Clean<Option<WherePredicate>> for ty::PolyTraitPredicate<'a> { fn clean(&self, cx: &mut DocContext<'_>) -> Option<WherePredicate> { - // `T: ~const Drop` is not equivalent to `T: Drop`, and we don't currently document `~const` bounds - // because of its experimental status, so just don't show these. // `T: ~const Destruct` is hidden because `T: Destruct` is a no-op. if self.skip_binder().constness == ty::BoundConstness::ConstIfConst - && [cx.tcx.lang_items().drop_trait(), cx.tcx.lang_items().destruct_trait()] - .iter() - .any(|tr| *tr == Some(self.skip_binder().def_id())) + && Some(self.skip_binder().def_id()) == cx.tcx.lang_items().destruct_trait() { return None; } - #[cfg(bootstrap)] - { - // FIXME: remove `lang_items().drop_trait()` from above logic, - // as well as the comment about `~const Drop` because it was renamed to `Destruct`. - } - let poly_trait_ref = self.map_bound(|pred| pred.trait_ref); Some(WherePredicate::BoundPredicate { ty: poly_trait_ref.skip_binder().self_ty().clean(cx), diff --git a/src/test/codegen/asm-may_unwind.rs b/src/test/codegen/asm-may_unwind.rs index 3b34d79c3a946..bf4202764a7ec 100644 --- a/src/test/codegen/asm-may_unwind.rs +++ b/src/test/codegen/asm-may_unwind.rs @@ -18,10 +18,23 @@ impl Drop for Foo { } } -// CHECK-LABEL: @may_unwind +// CHECK-LABEL: @asm_may_unwind #[no_mangle] -pub unsafe fn may_unwind() { +pub unsafe fn asm_may_unwind() { let _m = Foo; // CHECK: invoke void asm sideeffect alignstack inteldialect unwind "" asm!("", options(may_unwind)); } + +// CHECK-LABEL: @asm_with_result_may_unwind +#[no_mangle] +pub unsafe fn asm_with_result_may_unwind() -> u64 { + let _m = Foo; + let res: u64; + // CHECK: [[RES:%[0-9]+]] = invoke i64 asm sideeffect alignstack inteldialect unwind + // CHECK-NEXT: to label %[[NORMALBB:[a-b0-9]+]] + asm!("mov {}, 1", out(reg) res, options(may_unwind)); + // CHECK: [[NORMALBB]]: + // CHECK: ret i64 [[RES:%[0-9]+]] + res +} diff --git a/src/test/rustdoc/rfc-2632-const-trait-impl.rs b/src/test/rustdoc/rfc-2632-const-trait-impl.rs index c5353c4d5b523..f9173feeeec81 100644 --- a/src/test/rustdoc/rfc-2632-const-trait-impl.rs +++ b/src/test/rustdoc/rfc-2632-const-trait-impl.rs @@ -1,5 +1,5 @@ // Test that we do not currently display `~const` in rustdoc -// as that syntax is currently provisional; `~const Drop` has +// as that syntax is currently provisional; `~const Destruct` has // no effect on stable code so it should be hidden as well. // // To future blessers: make sure that `const_trait_impl` is @@ -8,6 +8,8 @@ #![feature(const_trait_impl)] #![crate_name = "foo"] +use std::marker::Destruct; + pub struct S<T>(T); // @!has foo/trait.Tr.html '//pre[@class="rust trait"]/code/a[@class="trait"]' '~const' @@ -20,22 +22,36 @@ pub trait Tr<T> { // @!has - '//div[@id="method.a"]/h4[@class="code-header"]/span[@class="where"]' '~const' // @has - '//div[@id="method.a"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone' #[default_method_body_is_const] - fn a<A: ~const Clone>() where Option<A>: ~const Clone {} + fn a<A: ~const Clone + ~const Destruct>() + where + Option<A>: ~const Clone + ~const Destruct, + { + } } // @!has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]' '~const' // @has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/a[@class="trait"]' 'Clone' // @!has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/span[@class="where"]' '~const' // @has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/span[@class="where fmt-newline"]' ': Clone' -impl<T: ~const Clone> const Tr<T> for T where Option<T>: ~const Clone { - fn a<A: ~const Clone>() where Option<A>: ~const Clone {} +impl<T: ~const Clone + ~const Destruct> const Tr<T> for T +where + Option<T>: ~const Clone + ~const Destruct, +{ + fn a<A: ~const Clone + ~const Destruct>() + where + Option<A>: ~const Clone + ~const Destruct, + { + } } // @!has foo/fn.foo.html '//pre[@class="rust fn"]/code/a[@class="trait"]' '~const' // @has - '//pre[@class="rust fn"]/code/a[@class="trait"]' 'Clone' // @!has - '//pre[@class="rust fn"]/code/span[@class="where fmt-newline"]' '~const' // @has - '//pre[@class="rust fn"]/code/span[@class="where fmt-newline"]' ': Clone' -pub const fn foo<F: ~const Clone>() where Option<F>: ~const Clone { +pub const fn foo<F: ~const Clone + ~const Destruct>() +where + Option<F>: ~const Clone + ~const Destruct, +{ F::a() } @@ -44,7 +60,10 @@ impl<T> S<T> { // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/a[@class="trait"]' 'Clone' // @!has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where"]' '~const' // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone' - pub const fn foo<B: ~const Clone>() where B: ~const Clone { + pub const fn foo<B: ~const Clone + ~const Destruct>() + where + B: ~const Clone + ~const Destruct, + { B::a() } } diff --git a/src/test/ui/block-result/consider-removing-last-semi.stderr b/src/test/ui/block-result/consider-removing-last-semi.stderr index 99a367bfccdcd..2412dcd32f79a 100644 --- a/src/test/ui/block-result/consider-removing-last-semi.stderr +++ b/src/test/ui/block-result/consider-removing-last-semi.stderr @@ -7,7 +7,7 @@ LL | pub fn f() -> String { | implicitly returns `()` as its body has no tail or `return` expression LL | 0u8; LL | "bla".to_string(); - | - help: consider removing this semicolon + | - help: remove this semicolon error[E0308]: mismatched types --> $DIR/consider-removing-last-semi.rs:8:15 @@ -18,7 +18,7 @@ LL | pub fn g() -> String { | implicitly returns `()` as its body has no tail or `return` expression LL | "this won't work".to_string(); LL | "removeme".to_string(); - | - help: consider removing this semicolon + | - help: remove this semicolon error[E0308]: mismatched types --> $DIR/consider-removing-last-semi.rs:13:25 @@ -29,7 +29,7 @@ LL | pub fn macro_tests() -> u32 { | implicitly returns `()` as its body has no tail or `return` expression ... LL | mac!(); - | - help: consider removing this semicolon + | - help: remove this semicolon error: aborting due to 3 previous errors diff --git a/src/test/ui/block-result/issue-11714.stderr b/src/test/ui/block-result/issue-11714.stderr index 61991643a4a56..5b8d96fd4ebe2 100644 --- a/src/test/ui/block-result/issue-11714.stderr +++ b/src/test/ui/block-result/issue-11714.stderr @@ -7,7 +7,7 @@ LL | fn blah() -> i32 { | implicitly returns `()` as its body has no tail or `return` expression ... LL | ; - | - help: consider removing this semicolon + | - help: remove this semicolon error: aborting due to previous error diff --git a/src/test/ui/block-result/issue-13428.stderr b/src/test/ui/block-result/issue-13428.stderr index 2f24679cc9591..a33448edff2bc 100644 --- a/src/test/ui/block-result/issue-13428.stderr +++ b/src/test/ui/block-result/issue-13428.stderr @@ -15,7 +15,7 @@ LL | fn bar() -> String { | implicitly returns `()` as its body has no tail or `return` expression LL | "foobar".to_string() LL | ; - | - help: consider removing this semicolon + | - help: remove this semicolon error: aborting due to 2 previous errors diff --git a/src/test/ui/closures/old-closure-expression-remove-semicolon.fixed b/src/test/ui/closures/old-closure-expression-remove-semicolon.fixed index 5629d4b6e6e5f..623e917da07e8 100644 --- a/src/test/ui/closures/old-closure-expression-remove-semicolon.fixed +++ b/src/test/ui/closures/old-closure-expression-remove-semicolon.fixed @@ -7,6 +7,6 @@ fn foo() -> i32 { fn main() { let _x: i32 = { //~^ ERROR mismatched types - foo() //~ HELP consider removing this semicolon + foo() //~ HELP remove this semicolon }; } diff --git a/src/test/ui/closures/old-closure-expression-remove-semicolon.rs b/src/test/ui/closures/old-closure-expression-remove-semicolon.rs index 33f11b50afca2..4974b08664945 100644 --- a/src/test/ui/closures/old-closure-expression-remove-semicolon.rs +++ b/src/test/ui/closures/old-closure-expression-remove-semicolon.rs @@ -7,6 +7,6 @@ fn foo() -> i32 { fn main() { let _x: i32 = { //~^ ERROR mismatched types - foo(); //~ HELP consider removing this semicolon + foo(); //~ HELP remove this semicolon }; } diff --git a/src/test/ui/closures/old-closure-expression-remove-semicolon.stderr b/src/test/ui/closures/old-closure-expression-remove-semicolon.stderr index ab7983dc9e487..9b73ce4fee346 100644 --- a/src/test/ui/closures/old-closure-expression-remove-semicolon.stderr +++ b/src/test/ui/closures/old-closure-expression-remove-semicolon.stderr @@ -5,7 +5,7 @@ LL | let _x: i32 = { | ___________________^ LL | | LL | | foo(); - | | - help: consider removing this semicolon + | | - help: remove this semicolon LL | | }; | |_____^ expected `i32`, found `()` diff --git a/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr b/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr index df1fb58e25a02..a4843bca58c99 100644 --- a/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr +++ b/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr @@ -6,7 +6,7 @@ LL | fn plus_one(x: i32) -> i32 { | | | implicitly returns `()` as its body has no tail or `return` expression LL | x + 1; - | - help: consider removing this semicolon + | - help: remove this semicolon error[E0308]: mismatched types --> $DIR/coercion-missing-tail-expected-type.rs:8:13 @@ -16,7 +16,7 @@ LL | fn foo() -> Result<u8, u64> { | | | implicitly returns `()` as its body has no tail or `return` expression LL | Ok(1); - | - help: consider removing this semicolon + | - help: remove this semicolon | = note: expected enum `Result<u8, u64>` found unit type `()` diff --git a/src/test/ui/issues/issue-6458-4.stderr b/src/test/ui/issues/issue-6458-4.stderr index 0cf82d37d5d0b..d6e74d10e03c9 100644 --- a/src/test/ui/issues/issue-6458-4.stderr +++ b/src/test/ui/issues/issue-6458-4.stderr @@ -6,7 +6,7 @@ LL | fn foo(b: bool) -> Result<bool,String> { | | | implicitly returns `()` as its body has no tail or `return` expression LL | Err("bar".to_string()); - | - help: consider removing this semicolon + | - help: remove this semicolon | = note: expected enum `Result<bool, String>` found unit type `()` diff --git a/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr b/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr index 0b33d8d0a2b23..82d136bd318d8 100644 --- a/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr +++ b/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr @@ -14,7 +14,7 @@ LL | fn bar(x: u32) -> u32 { | | | implicitly returns `()` as its body has no tail or `return` expression LL | x * 2; - | - help: consider removing this semicolon + | - help: remove this semicolon error[E0308]: mismatched types --> $DIR/liveness-return-last-stmt-semi.rs:13:19 diff --git a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs index cad7d76c6ab5f..5a17c108ccc13 100644 --- a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs +++ b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs @@ -1,8 +1,25 @@ trait Bar {} -impl Bar for u8 {} + +impl Bar for i32 {} + +struct Qux; + +impl Bar for Qux {} + fn foo() -> impl Bar { - 5; //~^ ERROR the trait bound `(): Bar` is not satisfied + //~^ ERROR the trait bound `(): Bar` is not satisfied + //~| ERROR the trait bound `(): Bar` is not satisfied + //~| HELP the following other types implement trait `Bar`: + 5; + //~^ HELP remove this semicolon +} + +fn bar() -> impl Bar { + //~^ ERROR the trait bound `(): Bar` is not satisfied //~| ERROR the trait bound `(): Bar` is not satisfied + //~| HELP the following other types implement trait `Bar`: + //~| HELP the following other types implement trait `Bar`: + ""; } fn main() {} diff --git a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr index 0de765588e5b7..43f8b7c66f07a 100644 --- a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr +++ b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr @@ -1,23 +1,58 @@ error[E0277]: the trait bound `(): Bar` is not satisfied - --> $DIR/impl-trait-return-trailing-semicolon.rs:3:13 + --> $DIR/impl-trait-return-trailing-semicolon.rs:9:13 | LL | fn foo() -> impl Bar { | ^^^^^^^^ the trait `Bar` is not implemented for `()` +... LL | 5; - | - consider removing this semicolon + | -- help: remove this semicolon + | | + | this expression has type `{integer}`, which implements `Bar` error[E0277]: the trait bound `(): Bar` is not satisfied - --> $DIR/impl-trait-return-trailing-semicolon.rs:3:22 + --> $DIR/impl-trait-return-trailing-semicolon.rs:9:22 | LL | fn foo() -> impl Bar { | ______________________^ +LL | | +LL | | +LL | | LL | | 5; LL | | LL | | } | |_^ the trait `Bar` is not implemented for `()` | - = help: the trait `Bar` is implemented for `u8` + = help: the following other types implement trait `Bar`: + Qux + i32 + +error[E0277]: the trait bound `(): Bar` is not satisfied + --> $DIR/impl-trait-return-trailing-semicolon.rs:17:13 + | +LL | fn bar() -> impl Bar { + | ^^^^^^^^ the trait `Bar` is not implemented for `()` + | + = help: the following other types implement trait `Bar`: + Qux + i32 + +error[E0277]: the trait bound `(): Bar` is not satisfied + --> $DIR/impl-trait-return-trailing-semicolon.rs:17:22 + | +LL | fn bar() -> impl Bar { + | ______________________^ +LL | | +LL | | +LL | | +LL | | +LL | | ""; +LL | | } + | |_^ the trait `Bar` is not implemented for `()` + | + = help: the following other types implement trait `Bar`: + Qux + i32 -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggestions/issue-81098.stderr b/src/test/ui/suggestions/issue-81098.stderr index d62526442e9af..8665f2e70a85c 100644 --- a/src/test/ui/suggestions/issue-81098.stderr +++ b/src/test/ui/suggestions/issue-81098.stderr @@ -27,7 +27,9 @@ LL | fn ok() -> impl core::fmt::Display { | ^^^^^^^^^^^^^^^^^^^^^^^ `()` cannot be formatted with the default formatter LL | LL | 1; - | - consider removing this semicolon + | -- help: remove this semicolon + | | + | this expression has type `{integer}`, which implements `std::fmt::Display` | = help: the trait `std::fmt::Display` is not implemented for `()` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead diff --git a/src/test/ui/suggestions/match-with-different-arm-types-as-stmt-instead-of-expr.stderr b/src/test/ui/suggestions/match-with-different-arm-types-as-stmt-instead-of-expr.stderr index 7dce97468b6dd..60f423a116317 100644 --- a/src/test/ui/suggestions/match-with-different-arm-types-as-stmt-instead-of-expr.stderr +++ b/src/test/ui/suggestions/match-with-different-arm-types-as-stmt-instead-of-expr.stderr @@ -7,7 +7,7 @@ LL | fn not_all_paths(a: &str) -> u32 { | implicitly returns `()` as its body has no tail or `return` expression ... LL | }; - | - help: consider removing this semicolon + | - help: remove this semicolon error[E0308]: `match` arms have incompatible types --> $DIR/match-with-different-arm-types-as-stmt-instead-of-expr.rs:26:14