about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs50
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs54
-rw-r--r--compiler/rustc_lint/src/precedence.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs8
-rw-r--r--compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs2
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),