diff options
Diffstat (limited to 'compiler')
7 files changed, 66 insertions, 55 deletions
diff --git a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs index 02555bd799c..7eb1f17a59c 100644 --- a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs +++ b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs @@ -1,5 +1,3 @@ -use std::mem::swap; - use ast::ptr::P; use ast::HasAttrs; use rustc_ast::mut_visit::MutVisitor; @@ -154,13 +152,28 @@ pub fn expand_deriving_smart_ptr( { let pointee = &mut impl_generics.params[pointee_param_idx]; self_bounds = pointee.bounds.clone(); + if !contains_maybe_sized_bound(&self_bounds) + && !contains_maybe_sized_bound_on_pointee( + &generics.where_clause.predicates, + pointee_ty_ident.name, + ) + { + cx.dcx() + .struct_span_err( + pointee_ty_ident.span, + format!( + "`derive(SmartPointer)` requires {} to be marked `?Sized`", + pointee_ty_ident.name + ), + ) + .emit(); + return; + } let arg = GenericArg::Type(s_ty.clone()); let unsize = cx.path_all(span, true, path!(span, core::marker::Unsize), vec![arg]); pointee.bounds.push(cx.trait_bound(unsize, false)); - let mut attrs = thin_vec![]; - swap(&mut pointee.attrs, &mut attrs); // Drop `#[pointee]` attribute since it should not be recognized outside `derive(SmartPointer)` - pointee.attrs = attrs.into_iter().filter(|attr| !attr.has_name(sym::pointee)).collect(); + pointee.attrs.retain(|attr| !attr.has_name(sym::pointee)); } // # Rewrite generic parameter bounds @@ -169,14 +182,14 @@ pub fn expand_deriving_smart_ptr( // ``` // struct< // U: Trait<T>, - // #[pointee] T: Trait<T>, + // #[pointee] T: Trait<T> + ?Sized, // V: Trait<T>> ... // ``` // ... generates this `impl` generic parameters // ``` // impl< // U: Trait<T> + Trait<__S>, - // T: Trait<T> + Unsize<__S>, // (**) + // T: Trait<T> + ?Sized + Unsize<__S>, // (**) // __S: Trait<__S> + ?Sized, // (*) // V: Trait<T> + Trait<__S>> ... // ``` @@ -218,23 +231,6 @@ pub fn expand_deriving_smart_ptr( // // We now insert `__S` with the missing bounds marked with (*) above. // We should also write the bounds from `#[pointee]` to `__S` as required by `Unsize<__S>`. - let sized = cx.path_global(span, path!(span, core::marker::Sized)); - // For some reason, we are not allowed to write `?Sized` bound twice like `__S: ?Sized + ?Sized`. - if !contains_maybe_sized_bound(&self_bounds) - && !contains_maybe_sized_bound_on_pointee( - &generics.where_clause.predicates, - pointee_ty_ident.name, - ) - { - self_bounds.push(GenericBound::Trait( - cx.poly_trait_ref(span, sized), - TraitBoundModifiers { - polarity: ast::BoundPolarity::Maybe(span), - constness: ast::BoundConstness::Never, - asyncness: ast::BoundAsyncness::Normal, - }, - )); - } { let mut substitution = TypeSubstitution { from_name: pointee_ty_ident.name, to_ty: &s_ty, rewritten: false }; @@ -252,7 +248,7 @@ pub fn expand_deriving_smart_ptr( // where // U: Trait<V> + Trait<T>, // Companion<T>: Trait<T>, - // T: Trait<T>, + // T: Trait<T> + ?Sized, // { .. } // ``` // ... will have a impl prelude like so @@ -263,8 +259,8 @@ pub fn expand_deriving_smart_ptr( // U: Trait<__S>, // Companion<T>: Trait<T>, // Companion<__S>: Trait<__S>, - // T: Trait<T>, - // __S: Trait<__S>, + // T: Trait<T> + ?Sized, + // __S: Trait<__S> + ?Sized, // ``` // // We should also write a few new `where` bounds from `#[pointee] T` to `__S` diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index d75a5f8806b..e54f9486f6a 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1306,6 +1306,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // No way to know whether it's diverging because // of a `break` or an outer `break` or `return`. self.diverges.set(Diverges::Maybe); + } else { + self.diverges.set(self.diverges.get() | Diverges::always(expr.span)); } // If we permit break with a value, then result type is diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index dea125bb9b1..40d9a2985da 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -48,30 +48,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Produces warning on the given node, if the current point in the /// function is unreachable, and there hasn't been another warning. pub(crate) fn warn_if_unreachable(&self, id: HirId, span: Span, kind: &str) { - // FIXME: Combine these two 'if' expressions into one once - // let chains are implemented - if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() { - // If span arose from a desugaring of `if` or `while`, then it is the condition itself, - // which diverges, that we are about to lint on. This gives suboptimal diagnostics. - // Instead, stop here so that the `if`- or `while`-expression's block is linted instead. - if !span.is_desugaring(DesugaringKind::CondTemporary) - && !span.is_desugaring(DesugaringKind::Async) - && !orig_span.is_desugaring(DesugaringKind::Await) - { - self.diverges.set(Diverges::WarnedAlways); + // If span arose from a desugaring of `if` or `while`, then it is the condition itself, + // which diverges, that we are about to lint on. This gives suboptimal diagnostics. + // Instead, stop here so that the `if`- or `while`-expression's block is linted instead. + if span.is_desugaring(DesugaringKind::CondTemporary) { + return; + } - debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind); + // Don't lint if the result of an async block or async function is `!`. + // This does not affect the unreachable lints *within* the body. + if span.is_desugaring(DesugaringKind::Async) { + return; + } - let msg = format!("unreachable {kind}"); - self.tcx().node_span_lint(lint::builtin::UNREACHABLE_CODE, id, span, |lint| { - lint.primary_message(msg.clone()); - lint.span_label(span, msg).span_label( - orig_span, - custom_note.unwrap_or("any code following this expression is unreachable"), - ); - }) - } + // Don't lint *within* the `.await` operator, since that's all just desugaring junk. + // We only want to lint if there is a subsequent expression after the `.await`. + if span.is_desugaring(DesugaringKind::Await) { + return; } + + let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() else { + return; + }; + + // Don't warn twice. + self.diverges.set(Diverges::WarnedAlways); + + debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind); + + let msg = format!("unreachable {kind}"); + self.tcx().node_span_lint(lint::builtin::UNREACHABLE_CODE, id, span, |lint| { + lint.primary_message(msg.clone()); + lint.span_label(span, msg).span_label( + orig_span, + custom_note.unwrap_or("any code following this expression is unreachable"), + ); + }) } /// Resolves type and const variables in `ty` if possible. Unlike the infcx diff --git a/compiler/rustc_lint/src/precedence.rs b/compiler/rustc_lint/src/precedence.rs index eb2ba397277..52321e25c7d 100644 --- a/compiler/rustc_lint/src/precedence.rs +++ b/compiler/rustc_lint/src/precedence.rs @@ -16,6 +16,7 @@ declare_lint! { /// ### Example /// /// ```rust,compile_fail + /// # #![deny(ambiguous_negative_literals)] /// # #![allow(unused)] /// -1i32.abs(); // equals -1, while `(-1i32).abs()` equals 1 /// ``` @@ -27,7 +28,7 @@ declare_lint! { /// Method calls take precedence over unary precedence. Setting the /// precedence explicitly makes the code clearer and avoid potential bugs. pub AMBIGUOUS_NEGATIVE_LITERALS, - Deny, + Allow, "ambiguous negative literals operations", report_in_external_macro } diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs index 19b04607f0e..f7a6e0bd857 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs @@ -4,10 +4,10 @@ pub fn target() -> Target { Target { llvm_target: "loongarch64-unknown-linux-musl".into(), metadata: crate::spec::TargetMetadata { - description: Some("LoongArch64 Linux (LP64D ABI) with musl 1.2.3".into()), - tier: Some(3), - host_tools: Some(false), - std: None, // ? + description: Some("LoongArch64 Linux (LP64D ABI) with musl 1.2.5".into()), + tier: Some(2), + host_tools: Some(true), + std: Some(true), }, pointer_width: 64, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs index 138491972e5..c7f47da6972 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs @@ -6,7 +6,7 @@ pub fn target() -> Target { Target { llvm_target: "loongarch64-unknown-none".into(), metadata: crate::spec::TargetMetadata { - description: None, + description: Some("Freestanding/bare-metal LoongArch64".into()), tier: Some(2), host_tools: Some(false), std: Some(false), diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs index 41519078f80..21e4f4a2b05 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs @@ -6,7 +6,7 @@ pub fn target() -> Target { Target { llvm_target: "loongarch64-unknown-none".into(), metadata: crate::spec::TargetMetadata { - description: None, + description: Some("Freestanding/bare-metal LoongArch64 softfloat".into()), tier: Some(2), host_tools: Some(false), std: Some(false), |
