From 7e79dcdc06a2bbd4a1d3250b23dbfc024bf0a86f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar> Date: Sat, 9 Mar 2024 20:02:47 +0000 Subject: [PATCH 01/17] Drive-by fix string fmt --- compiler/rustc_borrowck/src/diagnostics/mod.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 560928d394145..4ebbe592628a0 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1226,20 +1226,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { { let msg = match &errors[..] { [] => "you can `clone` the value and consume it, but this \ - might not be your desired behavior" + might not be your desired behavior" .to_string(), [error] => { format!( - "you could `clone` the value and consume it, if \ - the `{}` trait bound could be satisfied", + "you could `clone` the value and consume it, if the \ + `{}` trait bound could be satisfied", error.obligation.predicate, ) } [errors @ .., last] => { format!( - "you could `clone` the value and consume it, if \ - the following trait bounds could be satisfied: {} \ - and `{}`", + "you could `clone` the value and consume it, if the \ + following trait bounds could be satisfied: \ + {} and `{}`", errors .iter() .map(|e| format!("`{}`", e.obligation.predicate)) From 2d3435b4df844bb0c25b86bb73519a3c867a92a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar> Date: Sat, 9 Mar 2024 20:18:43 +0000 Subject: [PATCH 02/17] Detect calls to `.clone()` on `T: !Clone` types on borrowck errors When encountering a lifetime error on a type that *holds* a type that doesn't implement `Clone`, explore the item's body for potential calls to `.clone()` that are only cloning the reference `&T` instead of `T` because `T: !Clone`. If we find this, suggest `T: Clone`. ``` error[E0502]: cannot borrow `*list` as mutable because it is also borrowed as immutable --> $DIR/clone-on-ref.rs:7:5 | LL | for v in list.iter() { | ---- immutable borrow occurs here LL | cloned_items.push(v.clone()) | ------- this call doesn't do anything, the result is still `&T` because `T` doesn't implement `Clone` LL | } LL | list.push(T::default()); | ^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here LL | LL | drop(cloned_items); | ------------ immutable borrow later used here | help: consider further restricting this bound | LL | fn foo<T: Default + Clone>(list: &mut Vec<T>) { | +++++++ ``` ``` error[E0505]: cannot move out of `x` because it is borrowed --> $DIR/clone-on-ref.rs:23:10 | LL | fn qux(x: A) { | - binding `x` declared here LL | let a = &x; | -- borrow of `x` occurs here LL | let b = a.clone(); | ------- this call doesn't do anything, the result is still `&A` because `A` doesn't implement `Clone` LL | drop(x); | ^ move out of `x` occurs here LL | LL | println!("{b:?}"); | ----- borrow later used here | help: consider annotating `A` with `#[derive(Clone)]` | LL + #[derive(Clone)] LL | struct A; | ``` --- .../src/diagnostics/conflict_errors.rs | 113 ++++++++++++++++-- tests/ui/borrowck/clone-on-ref.fixed | 32 +++++ tests/ui/borrowck/clone-on-ref.rs | 31 +++++ tests/ui/borrowck/clone-on-ref.stderr | 64 ++++++++++ 4 files changed, 233 insertions(+), 7 deletions(-) create mode 100644 tests/ui/borrowck/clone-on-ref.fixed create mode 100644 tests/ui/borrowck/clone-on-ref.rs create mode 100644 tests/ui/borrowck/clone-on-ref.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 0776f455efd9c..fcbad4724752e 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -12,7 +12,6 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::{walk_block, walk_expr, Visitor}; use rustc_hir::{CoroutineDesugaring, PatField}; use rustc_hir::{CoroutineKind, CoroutineSource, LangItem}; -use rustc_infer::traits::ObligationCause; use rustc_middle::hir::nested_filter::OnlyBodies; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ @@ -21,16 +20,21 @@ use rustc_middle::mir::{ PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm, }; -use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty, TyCtxt}; +use rustc_middle::ty::{ + self, suggest_constraining_type_params, PredicateKind, ToPredicate, Ty, TyCtxt, + TypeSuperVisitable, TypeVisitor, +}; use rustc_middle::util::CallKind; use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex}; +use rustc_span::def_id::DefId; use rustc_span::def_id::LocalDefId; use rustc_span::hygiene::DesugaringKind; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{BytePos, Span, Symbol}; use rustc_trait_selection::infer::InferCtxtExt; +use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt; use rustc_trait_selection::traits::error_reporting::FindExprBySpan; -use rustc_trait_selection::traits::ObligationCtxt; +use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt}; use std::iter; use crate::borrow_set::TwoPhaseActivation; @@ -283,7 +287,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // something that already has `Fn`-like bounds (or is a closure), so we can't // restrict anyways. } else { - self.suggest_adding_copy_bounds(&mut err, ty, span); + let copy_did = self.infcx.tcx.require_lang_item(LangItem::Copy, Some(span)); + self.suggest_adding_bounds(&mut err, ty, copy_did, span); } if needs_note { @@ -775,7 +780,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } - fn suggest_adding_copy_bounds(&self, err: &mut Diag<'_>, ty: Ty<'tcx>, span: Span) { + fn suggest_adding_bounds(&self, err: &mut Diag<'_>, ty: Ty<'tcx>, def_id: DefId, span: Span) { let tcx = self.infcx.tcx; let generics = tcx.generics_of(self.mir_def_id()); @@ -788,10 +793,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { }; // Try to find predicates on *generic params* that would allow copying `ty` let ocx = ObligationCtxt::new(self.infcx); - let copy_did = tcx.require_lang_item(LangItem::Copy, Some(span)); let cause = ObligationCause::misc(span, self.mir_def_id()); - ocx.register_bound(cause, self.param_env, ty, copy_did); + ocx.register_bound(cause, self.param_env, ty, def_id); let errors = ocx.select_all_or_error(); // Only emit suggestion if all required predicates are on generic @@ -877,6 +881,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { Some(borrow_span), None, ); + self.suggest_copy_for_type_in_cloned_ref(&mut err, place); self.buffer_error(err); } @@ -1215,10 +1220,104 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); self.suggest_using_local_if_applicable(&mut err, location, issued_borrow, explanation); + self.suggest_copy_for_type_in_cloned_ref(&mut err, place); err } + fn suggest_copy_for_type_in_cloned_ref(&self, err: &mut Diag<'tcx>, place: Place<'tcx>) { + let tcx = self.infcx.tcx; + let hir = tcx.hir(); + let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return }; + struct FindUselessClone<'hir> { + pub clones: Vec<&'hir hir::Expr<'hir>>, + } + impl<'hir> FindUselessClone<'hir> { + pub fn new() -> Self { + Self { clones: vec![] } + } + } + + impl<'v> Visitor<'v> for FindUselessClone<'v> { + fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { + // FIXME: use `lookup_method_for_diagnostic`? + if let hir::ExprKind::MethodCall(segment, _rcvr, args, _span) = ex.kind + && segment.ident.name == sym::clone + && args.len() == 0 + { + self.clones.push(ex); + } + hir::intravisit::walk_expr(self, ex); + } + } + let mut expr_finder = FindUselessClone::new(); + + let body = hir.body(body_id).value; + expr_finder.visit_expr(body); + + pub struct Holds<'tcx> { + ty: Ty<'tcx>, + holds: bool, + } + + impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Holds<'tcx> { + type Result = std::ops::ControlFlow<()>; + + fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result { + if t == self.ty { + self.holds = true; + } + t.super_visit_with(self) + } + } + + let mut types_to_constrain = FxIndexSet::default(); + + let local_ty = self.body.local_decls[place.local].ty; + let typeck_results = tcx.typeck(self.mir_def_id()); + let clone = tcx.require_lang_item(LangItem::Clone, Some(body.span)); + for expr in expr_finder.clones { + if let hir::ExprKind::MethodCall(_, rcvr, _, span) = expr.kind + && let Some(rcvr_ty) = typeck_results.node_type_opt(rcvr.hir_id) + && let Some(ty) = typeck_results.node_type_opt(expr.hir_id) + && rcvr_ty == ty + && let ty::Ref(_, inner, _) = rcvr_ty.kind() + && let inner = inner.peel_refs() + && let mut v = (Holds { ty: inner, holds: false }) + && let _ = v.visit_ty(local_ty) + && v.holds + && let None = self.infcx.type_implements_trait_shallow(clone, inner, self.param_env) + { + err.span_label( + span, + format!( + "this call doesn't do anything, the result is still `{rcvr_ty}` \ + because `{inner}` doesn't implement `Clone`", + ), + ); + types_to_constrain.insert(inner); + } + } + for ty in types_to_constrain { + self.suggest_adding_bounds(err, ty, clone, body.span); + if let ty::Adt(..) = ty.kind() { + // The type doesn't implement Clone. + let trait_ref = ty::Binder::dummy(ty::TraitRef::new(self.infcx.tcx, clone, [ty])); + let obligation = Obligation::new( + self.infcx.tcx, + ObligationCause::dummy(), + self.param_env, + trait_ref, + ); + self.infcx.err_ctxt().suggest_derive( + &obligation, + err, + trait_ref.to_predicate(self.infcx.tcx), + ); + } + } + } + #[instrument(level = "debug", skip(self, err))] fn suggest_using_local_if_applicable( &self, diff --git a/tests/ui/borrowck/clone-on-ref.fixed b/tests/ui/borrowck/clone-on-ref.fixed new file mode 100644 index 0000000000000..b6927ba590e34 --- /dev/null +++ b/tests/ui/borrowck/clone-on-ref.fixed @@ -0,0 +1,32 @@ +//@ run-rustfix +fn foo<T: Default + Clone>(list: &mut Vec<T>) { + let mut cloned_items = Vec::new(); + for v in list.iter() { + cloned_items.push(v.clone()) + } + list.push(T::default()); + //~^ ERROR cannot borrow `*list` as mutable because it is also borrowed as immutable + drop(cloned_items); +} +fn bar<T: std::fmt::Display + Clone>(x: T) { + let a = &x; + let b = a.clone(); + drop(x); + //~^ ERROR cannot move out of `x` because it is borrowed + println!("{b}"); +} +#[derive(Debug)] +#[derive(Clone)] +struct A; +fn qux(x: A) { + let a = &x; + let b = a.clone(); + drop(x); + //~^ ERROR cannot move out of `x` because it is borrowed + println!("{b:?}"); +} +fn main() { + foo(&mut vec![1, 2, 3]); + bar(""); + qux(A); +} diff --git a/tests/ui/borrowck/clone-on-ref.rs b/tests/ui/borrowck/clone-on-ref.rs new file mode 100644 index 0000000000000..f8c94d3cce31d --- /dev/null +++ b/tests/ui/borrowck/clone-on-ref.rs @@ -0,0 +1,31 @@ +//@ run-rustfix +fn foo<T: Default>(list: &mut Vec<T>) { + let mut cloned_items = Vec::new(); + for v in list.iter() { + cloned_items.push(v.clone()) + } + list.push(T::default()); + //~^ ERROR cannot borrow `*list` as mutable because it is also borrowed as immutable + drop(cloned_items); +} +fn bar<T: std::fmt::Display>(x: T) { + let a = &x; + let b = a.clone(); + drop(x); + //~^ ERROR cannot move out of `x` because it is borrowed + println!("{b}"); +} +#[derive(Debug)] +struct A; +fn qux(x: A) { + let a = &x; + let b = a.clone(); + drop(x); + //~^ ERROR cannot move out of `x` because it is borrowed + println!("{b:?}"); +} +fn main() { + foo(&mut vec![1, 2, 3]); + bar(""); + qux(A); +} diff --git a/tests/ui/borrowck/clone-on-ref.stderr b/tests/ui/borrowck/clone-on-ref.stderr new file mode 100644 index 0000000000000..ee4fcadf55ae1 --- /dev/null +++ b/tests/ui/borrowck/clone-on-ref.stderr @@ -0,0 +1,64 @@ +error[E0502]: cannot borrow `*list` as mutable because it is also borrowed as immutable + --> $DIR/clone-on-ref.rs:7:5 + | +LL | for v in list.iter() { + | ---- immutable borrow occurs here +LL | cloned_items.push(v.clone()) + | ------- this call doesn't do anything, the result is still `&T` because `T` doesn't implement `Clone` +LL | } +LL | list.push(T::default()); + | ^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here +LL | +LL | drop(cloned_items); + | ------------ immutable borrow later used here + | +help: consider further restricting this bound + | +LL | fn foo<T: Default + Clone>(list: &mut Vec<T>) { + | +++++++ + +error[E0505]: cannot move out of `x` because it is borrowed + --> $DIR/clone-on-ref.rs:14:10 + | +LL | fn bar<T: std::fmt::Display>(x: T) { + | - binding `x` declared here +LL | let a = &x; + | -- borrow of `x` occurs here +LL | let b = a.clone(); + | ------- this call doesn't do anything, the result is still `&T` because `T` doesn't implement `Clone` +LL | drop(x); + | ^ move out of `x` occurs here +LL | +LL | println!("{b}"); + | --- borrow later used here + | +help: consider further restricting this bound + | +LL | fn bar<T: std::fmt::Display + Clone>(x: T) { + | +++++++ + +error[E0505]: cannot move out of `x` because it is borrowed + --> $DIR/clone-on-ref.rs:23:10 + | +LL | fn qux(x: A) { + | - binding `x` declared here +LL | let a = &x; + | -- borrow of `x` occurs here +LL | let b = a.clone(); + | ------- this call doesn't do anything, the result is still `&A` because `A` doesn't implement `Clone` +LL | drop(x); + | ^ move out of `x` occurs here +LL | +LL | println!("{b:?}"); + | ----- borrow later used here + | +help: consider annotating `A` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | struct A; + | + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0502, E0505. +For more information about an error, try `rustc --explain E0502`. From b367c25367117a4ada5c9a1c807b74f0efcf6d51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar> Date: Sat, 9 Mar 2024 20:32:13 +0000 Subject: [PATCH 03/17] Tweak wording --- compiler/rustc_mir_build/messages.ftl | 2 +- ...can-live-while-the-other-survives-1.stderr | 4 +- ...t-by-move-and-ref-inverse-promotion.stderr | 2 +- ...orrowck-pat-by-move-and-ref-inverse.stderr | 50 +++++++++---------- .../borrowck-pat-ref-mut-twice.stderr | 8 +-- ...inding-modes-both-sides-independent.stderr | 2 +- .../ui/suggestions/ref-pattern-binding.stderr | 4 +- 7 files changed, 36 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index 8a6ccdb857829..1de691f32a70c 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -24,7 +24,7 @@ mir_build_borrow_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe mir_build_borrow_of_moved_value = borrow of moved value .label = value moved into `{$name}` here - .occurs_because_label = move occurs because `{$name}` has type `{$ty}` which does not implement the `Copy` trait + .occurs_because_label = move occurs because `{$name}` has type `{$ty}`, which does not implement the `Copy` trait .value_borrowed_label = value borrowed here after move .suggestion = borrow this binding in the pattern to avoid moving the value diff --git a/tests/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr b/tests/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr index 25838fbf0abdc..16a93a0d47d29 100644 --- a/tests/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr +++ b/tests/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr @@ -13,7 +13,7 @@ LL | Some(_z @ ref _y) => {} | ^^ ------ value borrowed here after move | | | value moved into `_z` here - | move occurs because `_z` has type `X` which does not implement the `Copy` trait + | move occurs because `_z` has type `X`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -35,7 +35,7 @@ LL | Some(_z @ ref mut _y) => {} | ^^ ---------- value borrowed here after move | | | value moved into `_z` here - | move occurs because `_z` has type `X` which does not implement the `Copy` trait + | move occurs because `_z` has type `X`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr index 815a4ade9956e..ea04d4bc055ac 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr @@ -5,7 +5,7 @@ LL | let a @ ref b = U; | ^ ----- value borrowed here after move | | | value moved into `a` here - | move occurs because `a` has type `U` which does not implement the `Copy` trait + | move occurs because `a` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr index fd7a51388bc10..25c940a3200ae 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr @@ -5,7 +5,7 @@ LL | let a @ ref b = U; | ^ ----- value borrowed here after move | | | value moved into `a` here - | move occurs because `a` has type `U` which does not implement the `Copy` trait + | move occurs because `a` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -20,7 +20,7 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait + | move occurs because `a` has type `(U, U)`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -34,7 +34,7 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); | ^^^^^ --------- value borrowed here after move | | | value moved into `b` here - | move occurs because `b` has type `U` which does not implement the `Copy` trait + | move occurs because `b` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -48,7 +48,7 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); | ^ ----- value borrowed here after move | | | value moved into `d` here - | move occurs because `d` has type `U` which does not implement the `Copy` trait + | move occurs because `d` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -63,7 +63,7 @@ LL | let a @ [ref mut b, ref c] = [U, U]; | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait + | move occurs because `a` has type `[U; 2]`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -77,7 +77,7 @@ LL | let a @ ref b = u(); | ^ ----- value borrowed here after move | | | value moved into `a` here - | move occurs because `a` has type `U` which does not implement the `Copy` trait + | move occurs because `a` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -92,7 +92,7 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait + | move occurs because `a` has type `(U, U)`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -106,7 +106,7 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); | ^^^^^ --------- value borrowed here after move | | | value moved into `b` here - | move occurs because `b` has type `U` which does not implement the `Copy` trait + | move occurs because `b` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -120,7 +120,7 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); | ^ ----- value borrowed here after move | | | value moved into `d` here - | move occurs because `d` has type `U` which does not implement the `Copy` trait + | move occurs because `d` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -135,7 +135,7 @@ LL | let a @ [ref mut b, ref c] = [u(), u()]; | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait + | move occurs because `a` has type `[U; 2]`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -149,7 +149,7 @@ LL | a @ Some(ref b) => {} | ^ ----- value borrowed here after move | | | value moved into `a` here - | move occurs because `a` has type `Option<U>` which does not implement the `Copy` trait + | move occurs because `a` has type `Option<U>`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -164,7 +164,7 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `Option<(U, U)>` which does not implement the `Copy` trait + | move occurs because `a` has type `Option<(U, U)>`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -178,7 +178,7 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | ^^^^^ --------- value borrowed here after move | | | value moved into `b` here - | move occurs because `b` has type `U` which does not implement the `Copy` trait + | move occurs because `b` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -192,7 +192,7 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | ^ ----- value borrowed here after move | | | value moved into `d` here - | move occurs because `d` has type `U` which does not implement the `Copy` trait + | move occurs because `d` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -207,7 +207,7 @@ LL | mut a @ Some([ref b, ref mut c]) => {} | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `Option<[U; 2]>` which does not implement the `Copy` trait + | move occurs because `a` has type `Option<[U; 2]>`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -221,7 +221,7 @@ LL | a @ Some(ref b) => {} | ^ ----- value borrowed here after move | | | value moved into `a` here - | move occurs because `a` has type `Option<U>` which does not implement the `Copy` trait + | move occurs because `a` has type `Option<U>`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -236,7 +236,7 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `Option<(U, U)>` which does not implement the `Copy` trait + | move occurs because `a` has type `Option<(U, U)>`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -250,7 +250,7 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | ^^^^^ --------- value borrowed here after move | | | value moved into `b` here - | move occurs because `b` has type `U` which does not implement the `Copy` trait + | move occurs because `b` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -264,7 +264,7 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | ^ ----- value borrowed here after move | | | value moved into `d` here - | move occurs because `d` has type `U` which does not implement the `Copy` trait + | move occurs because `d` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -279,7 +279,7 @@ LL | mut a @ Some([ref b, ref mut c]) => {} | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `Option<[U; 2]>` which does not implement the `Copy` trait + | move occurs because `a` has type `Option<[U; 2]>`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -349,7 +349,7 @@ LL | fn f1(a @ ref b: U) {} | ^ ----- value borrowed here after move | | | value moved into `a` here - | move occurs because `a` has type `U` which does not implement the `Copy` trait + | move occurs because `a` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -364,7 +364,7 @@ LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait + | move occurs because `a` has type `(U, U)`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -378,7 +378,7 @@ LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} | ^ ----- value borrowed here after move | | | value moved into `b` here - | move occurs because `b` has type `U` which does not implement the `Copy` trait + | move occurs because `b` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -392,7 +392,7 @@ LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} | ^^^^^ ----- value borrowed here after move | | | value moved into `d` here - | move occurs because `d` has type `U` which does not implement the `Copy` trait + | move occurs because `d` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -417,7 +417,7 @@ LL | fn f3(a @ [ref mut b, ref c]: [U; 2]) {} | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait + | move occurs because `a` has type `[U; 2]`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr index 3446148d2b15b..76085f897ff52 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr @@ -78,7 +78,7 @@ LL | let a @ (ref mut b, ref mut c) = (U, U); | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait + | move occurs because `a` has type `(U, U)`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -94,7 +94,7 @@ LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- | | | value borrowed here after move | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `&mut (U, [U; 2])` which does not implement the `Copy` trait + | move occurs because `a` has type `&mut (U, [U; 2])`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -108,7 +108,7 @@ LL | let a @ &mut ref mut b = &mut U; | ^ --------- value borrowed here after move | | | value moved into `a` here - | move occurs because `a` has type `&mut U` which does not implement the `Copy` trait + | move occurs because `a` has type `&mut U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -123,7 +123,7 @@ LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U); | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `&mut (U, U)` which does not implement the `Copy` trait + | move occurs because `a` has type `&mut (U, U)`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | diff --git a/tests/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr b/tests/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr index 36515c1a29bb5..a0a43e83a6a0d 100644 --- a/tests/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr +++ b/tests/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr @@ -29,7 +29,7 @@ LL | Ok(ref a @ b) | Err(b @ ref a) => { | ^ ----- value borrowed here after move | | | value moved into `b` here - | move occurs because `b` has type `NotCopy` which does not implement the `Copy` trait + | move occurs because `b` has type `NotCopy`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | diff --git a/tests/ui/suggestions/ref-pattern-binding.stderr b/tests/ui/suggestions/ref-pattern-binding.stderr index 69ce5d440af81..af21c6aef700b 100644 --- a/tests/ui/suggestions/ref-pattern-binding.stderr +++ b/tests/ui/suggestions/ref-pattern-binding.stderr @@ -5,7 +5,7 @@ LL | let _moved @ ref _from = String::from("foo"); | ^^^^^^ --------- value borrowed here after move | | | value moved into `_moved` here - | move occurs because `_moved` has type `String` which does not implement the `Copy` trait + | move occurs because `_moved` has type `String`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -35,7 +35,7 @@ LL | let _moved @ S { ref f } = S { f: String::from("foo") }; | ^^^^^^ ----- value borrowed here after move | | | value moved into `_moved` here - | move occurs because `_moved` has type `S` which does not implement the `Copy` trait + | move occurs because `_moved` has type `S`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | From 0953608debfa9d3df955f976e7bc857584ba1ed0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar> Date: Tue, 12 Mar 2024 17:21:15 +0000 Subject: [PATCH 04/17] Account for UnOps in borrowck message --- compiler/rustc_borrowck/messages.ftl | 3 +++ compiler/rustc_borrowck/src/diagnostics/mod.rs | 11 +++++++++-- compiler/rustc_borrowck/src/session_diagnostics.rs | 5 +++++ tests/ui/unop-move-semantics.stderr | 4 ++-- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_borrowck/messages.ftl b/compiler/rustc_borrowck/messages.ftl index bf14d5eb9a0a8..f2ca509e14bbc 100644 --- a/compiler/rustc_borrowck/messages.ftl +++ b/compiler/rustc_borrowck/messages.ftl @@ -16,6 +16,9 @@ borrowck_borrow_due_to_use_closure = borrowck_borrow_due_to_use_coroutine = borrow occurs due to use in coroutine +borrowck_calling_operator_moves = + calling this operator moves the value + borrowck_calling_operator_moves_lhs = calling this operator moves the left-hand side diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 4ebbe592628a0..914f68a38b4f5 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1050,7 +1050,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); err.subdiagnostic(self.dcx(), CaptureReasonNote::FnOnceMoveInCall { var_span }); } - CallKind::Operator { self_arg, .. } => { + CallKind::Operator { self_arg, trait_id, .. } => { let self_arg = self_arg.unwrap(); err.subdiagnostic( self.dcx(), @@ -1062,9 +1062,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { }, ); if self.fn_self_span_reported.insert(fn_span) { + let lang = self.infcx.tcx.lang_items(); err.subdiagnostic( self.dcx(), - CaptureReasonNote::LhsMoveByOperator { span: self_arg.span }, + if [lang.not_trait(), lang.deref_trait(), lang.neg_trait()] + .contains(&Some(trait_id)) + { + CaptureReasonNote::UnOpMoveByOperator { span: self_arg.span } + } else { + CaptureReasonNote::LhsMoveByOperator { span: self_arg.span } + }, ); } } diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index a055ce95e8ef3..77021ae4321d2 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -368,6 +368,11 @@ pub(crate) enum CaptureReasonNote { #[primary_span] var_span: Span, }, + #[note(borrowck_calling_operator_moves)] + UnOpMoveByOperator { + #[primary_span] + span: Span, + }, #[note(borrowck_calling_operator_moves_lhs)] LhsMoveByOperator { #[primary_span] diff --git a/tests/ui/unop-move-semantics.stderr b/tests/ui/unop-move-semantics.stderr index b6de7976ac944..187dd66b2fe59 100644 --- a/tests/ui/unop-move-semantics.stderr +++ b/tests/ui/unop-move-semantics.stderr @@ -9,7 +9,7 @@ LL | LL | x.clone(); | ^ value borrowed here after move | -note: calling this operator moves the left-hand side +note: calling this operator moves the value --> $SRC_DIR/core/src/ops/bit.rs:LL:COL help: consider cloning the value if the performance cost is acceptable | @@ -57,7 +57,7 @@ LL | !*m; | |move occurs because `*m` has type `T`, which does not implement the `Copy` trait | `*m` moved due to usage in operator | -note: calling this operator moves the left-hand side +note: calling this operator moves the value --> $SRC_DIR/core/src/ops/bit.rs:LL:COL error[E0507]: cannot move out of `*n` which is behind a shared reference From 8da262139af11628512d1d9bce059310461a1fa8 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar <manishsmail@gmail.com> Date: Thu, 14 Mar 2024 12:15:05 +0100 Subject: [PATCH 05/17] print ghosts --- src/librustdoc/html/render/print_item.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index d588f219739fe..4f74ae096fbaa 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -517,6 +517,11 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: } _ => "", }; + let hidden_emoji = if myitem.is_doc_hidden() { + "<span title=\"Hidden item\"> 👻</span> " + } else { + "" + }; w.write_str(ITEM_TABLE_ROW_OPEN); let docs = @@ -531,6 +536,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: "<div class=\"item-name\">\ <a class=\"{class}\" href=\"{href}\" title=\"{title}\">{name}</a>\ {visibility_emoji}\ + {hidden_emoji}\ {unsafety_flag}\ {stab_tags}\ </div>\ From 343c77c102608e7b9090789ea365a21d0156d191 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar <manishsmail@gmail.com> Date: Thu, 14 Mar 2024 12:39:27 +0100 Subject: [PATCH 06/17] Refactor visibility_print_with_space to directly take an item --- src/librustdoc/clean/inline.rs | 16 ++++++-- src/librustdoc/clean/mod.rs | 3 +- src/librustdoc/clean/types.rs | 2 +- src/librustdoc/clean/utils.rs | 5 ++- src/librustdoc/html/format.rs | 12 +++--- src/librustdoc/html/render/mod.rs | 7 ++-- src/librustdoc/html/render/print_item.rs | 48 ++++++++---------------- 7 files changed, 42 insertions(+), 51 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 77a78f57e950c..6f86c6450d969 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -62,6 +62,9 @@ pub(crate) fn try_inline( attrs_without_docs.as_ref().map(|(attrs, def_id)| (&attrs[..], *def_id)); let import_def_id = attrs.and_then(|(_, def_id)| def_id); + + let (attrs, cfg) = merge_attrs(cx, load_attrs(cx, did), attrs); + let kind = match res { Res::Def(DefKind::Trait, did) => { record_extern_fqn(cx, did, ItemType::Trait); @@ -131,7 +134,7 @@ pub(crate) fn try_inline( cx.with_param_env(did, |cx| clean::ConstantItem(build_const(cx, did))) } Res::Def(DefKind::Macro(kind), did) => { - let mac = build_macro(cx, did, name, import_def_id, kind); + let mac = build_macro(cx, did, name, import_def_id, kind, attrs.is_doc_hidden()); let type_kind = match kind { MacroKind::Bang => ItemType::Macro, @@ -144,7 +147,6 @@ pub(crate) fn try_inline( _ => return None, }; - let (attrs, cfg) = merge_attrs(cx, load_attrs(cx, did), attrs); cx.inlined.insert(did.into()); let mut item = clean::Item::from_def_id_and_attrs_and_parts(did, Some(name), kind, Box::new(attrs), cfg); @@ -751,6 +753,7 @@ fn build_macro( name: Symbol, import_def_id: Option<DefId>, macro_kind: MacroKind, + is_doc_hidden: bool, ) -> clean::ItemKind { match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.tcx) { LoadedMacro::MacroDef(item_def, _) => match macro_kind { @@ -758,7 +761,14 @@ fn build_macro( if let ast::ItemKind::MacroDef(ref def) = item_def.kind { let vis = cx.tcx.visibility(import_def_id.unwrap_or(def_id)); clean::MacroItem(clean::Macro { - source: utils::display_macro_source(cx, name, def, def_id, vis), + source: utils::display_macro_source( + cx, + name, + def, + def_id, + vis, + is_doc_hidden, + ), }) } else { unreachable!() diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index b32d3ad562d03..ec4c6d991f1ad 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2796,7 +2796,8 @@ fn clean_maybe_renamed_item<'tcx>( ItemKind::Macro(ref macro_def, MacroKind::Bang) => { let ty_vis = cx.tcx.visibility(def_id); MacroItem(Macro { - source: display_macro_source(cx, name, macro_def, def_id, ty_vis), + // FIXME this shouldn't be false + source: display_macro_source(cx, name, macro_def, def_id, ty_vis, false), }) } ItemKind::Macro(_, macro_kind) => clean_proc_macro(item, &mut name, macro_kind, cx), diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index c35baeb4cf587..a51f6360df2a4 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1161,7 +1161,7 @@ impl Attributes { false } - fn is_doc_hidden(&self) -> bool { + pub(crate) fn is_doc_hidden(&self) -> bool { self.has_doc_flag(sym::hidden) } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 57916ff0ff781..5464aa63ea806 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -625,6 +625,7 @@ pub(super) fn display_macro_source( def: &ast::MacroDef, def_id: DefId, vis: ty::Visibility<DefId>, + is_doc_hidden: bool, ) -> String { // Extract the spans of all matchers. They represent the "interface" of the macro. let matchers = def.body.tokens.chunks(4).map(|arm| &arm[0]); @@ -635,7 +636,7 @@ pub(super) fn display_macro_source( if matchers.len() <= 1 { format!( "{vis}macro {name}{matchers} {{\n ...\n}}", - vis = visibility_to_src_with_space(Some(vis), cx.tcx, def_id), + vis = visibility_to_src_with_space(Some(vis), cx.tcx, def_id, is_doc_hidden), matchers = matchers .map(|matcher| render_macro_matcher(cx.tcx, matcher)) .collect::<String>(), @@ -643,7 +644,7 @@ pub(super) fn display_macro_source( } else { format!( "{vis}macro {name} {{\n{arms}}}", - vis = visibility_to_src_with_space(Some(vis), cx.tcx, def_id), + vis = visibility_to_src_with_space(Some(vis), cx.tcx, def_id, is_doc_hidden), arms = render_macro_arms(cx.tcx, matchers, ","), ) } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index afd5eb42d019d..1973c2a6021ce 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -29,8 +29,7 @@ use rustc_target::spec::abi::Abi; use itertools::Itertools; use crate::clean::{ - self, types::ExternalLocation, utils::find_nearest_parent_module, ExternalCrate, ItemId, - PrimitiveType, + self, types::ExternalLocation, utils::find_nearest_parent_module, ExternalCrate, PrimitiveType, }; use crate::formats::cache::Cache; use crate::formats::item_type::ItemType; @@ -1506,20 +1505,18 @@ impl clean::FnDecl { } pub(crate) fn visibility_print_with_space<'a, 'tcx: 'a>( - visibility: Option<ty::Visibility<DefId>>, - item_did: ItemId, + item: &clean::Item, cx: &'a Context<'tcx>, ) -> impl Display + 'a + Captures<'tcx> { use std::fmt::Write as _; - - let to_print: Cow<'static, str> = match visibility { + let to_print: Cow<'static, str> = match item.visibility(cx.tcx()) { None => "".into(), Some(ty::Visibility::Public) => "pub ".into(), Some(ty::Visibility::Restricted(vis_did)) => { // FIXME(camelid): This may not work correctly if `item_did` is a module. // However, rustdoc currently never displays a module's // visibility, so it shouldn't matter. - let parent_module = find_nearest_parent_module(cx.tcx(), item_did.expect_def_id()); + let parent_module = find_nearest_parent_module(cx.tcx(), item.item_id.expect_def_id()); if vis_did.is_crate_root() { "pub(crate) ".into() @@ -1557,6 +1554,7 @@ pub(crate) fn visibility_to_src_with_space<'a, 'tcx: 'a>( visibility: Option<ty::Visibility<DefId>>, tcx: TyCtxt<'tcx>, item_did: DefId, + _is_doc_hidden: bool, ) -> impl Display + 'a + Captures<'tcx> { let to_print: Cow<'static, str> = match visibility { None => "".into(), diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index fe83095f944ab..54d51ca009b29 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -883,7 +883,7 @@ fn assoc_const( w, "{indent}{vis}const <a{href} class=\"constant\">{name}</a>{generics}: {ty}", indent = " ".repeat(indent), - vis = visibility_print_with_space(it.visibility(tcx), it.item_id, cx), + vis = visibility_print_with_space(it, cx), href = assoc_href_attr(it, link, cx), name = it.name.as_ref().unwrap(), generics = generics.print(cx), @@ -912,12 +912,11 @@ fn assoc_type( indent: usize, cx: &Context<'_>, ) { - let tcx = cx.tcx(); write!( w, "{indent}{vis}type <a{href} class=\"associatedtype\">{name}</a>{generics}", indent = " ".repeat(indent), - vis = visibility_print_with_space(it.visibility(tcx), it.item_id, cx), + vis = visibility_print_with_space(it, cx), href = assoc_href_attr(it, link, cx), name = it.name.as_ref().unwrap(), generics = generics.print(cx), @@ -945,7 +944,7 @@ fn assoc_method( let tcx = cx.tcx(); let header = meth.fn_header(tcx).expect("Trying to get header from a non-function item"); let name = meth.name.as_ref().unwrap(); - let vis = visibility_print_with_space(meth.visibility(tcx), meth.item_id, cx).to_string(); + let vis = visibility_print_with_space(meth, cx).to_string(); let defaultness = print_default_space(meth.is_default()); // FIXME: Once https://github.com/rust-lang/rust/issues/67792 is implemented, we can remove // this condition. diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 4f74ae096fbaa..d2a03d5840278 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -445,14 +445,14 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: Some(src) => write!( w, "<div class=\"item-name\"><code>{}extern crate {} as {};", - visibility_print_with_space(myitem.visibility(tcx), myitem.item_id, cx), + visibility_print_with_space(myitem, cx), anchor(myitem.item_id.expect_def_id(), src, cx), myitem.name.unwrap(), ), None => write!( w, "<div class=\"item-name\"><code>{}extern crate {};", - visibility_print_with_space(myitem.visibility(tcx), myitem.item_id, cx), + visibility_print_with_space(myitem, cx), anchor(myitem.item_id.expect_def_id(), myitem.name.unwrap(), cx), ), } @@ -491,7 +491,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: <code>{vis}{imp}</code>\ </div>\ {stab_tags_before}{stab_tags}{stab_tags_after}", - vis = visibility_print_with_space(myitem.visibility(tcx), myitem.item_id, cx), + vis = visibility_print_with_space(myitem, cx), imp = import.print(cx), ); w.write_str(ITEM_TABLE_ROW_CLOSE); @@ -631,7 +631,7 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle let unsafety = header.unsafety.print_with_space(); let abi = print_abi_with_space(header.abi).to_string(); let asyncness = header.asyncness.print_with_space(); - let visibility = visibility_print_with_space(it.visibility(tcx), it.item_id, cx).to_string(); + let visibility = visibility_print_with_space(it, cx).to_string(); let name = it.name.unwrap(); let generics_len = format!("{:#}", f.generics.print(cx)).len(); @@ -688,7 +688,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: w, "{attrs}{vis}{unsafety}{is_auto}trait {name}{generics}{bounds}", attrs = render_attributes_in_pre(it, "", cx), - vis = visibility_print_with_space(it.visibility(tcx), it.item_id, cx), + vis = visibility_print_with_space(it, cx), unsafety = t.unsafety(tcx).print_with_space(), is_auto = if t.is_auto(tcx) { "auto " } else { "" }, name = it.name.unwrap(), @@ -1243,7 +1243,7 @@ fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &c w, "{attrs}{vis}type {name}{generics}{where_clause} = {type_};", attrs = render_attributes_in_pre(it, "", cx), - vis = visibility_print_with_space(it.visibility(cx.tcx()), it.item_id, cx), + vis = visibility_print_with_space(it, cx), name = it.name.unwrap(), generics = t.generics.print(cx), where_clause = print_where_clause(&t.generics, cx, 0, Ending::Newline), @@ -1522,14 +1522,13 @@ fn print_tuple_struct_fields<'a, 'cx: 'a>( } fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::Enum) { - let tcx = cx.tcx(); let count_variants = e.variants().count(); wrap_item(w, |w| { render_attributes_in_code(w, it, cx); write!( w, "{}enum {}{}", - visibility_print_with_space(it.visibility(tcx), it.item_id, cx), + visibility_print_with_space(it, cx), it.name.unwrap(), e.generics.print(cx), ); @@ -1860,7 +1859,7 @@ fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &cle write!( w, "{vis}const {name}{generics}: {typ}{where_clause}", - vis = visibility_print_with_space(it.visibility(tcx), it.item_id, cx), + vis = visibility_print_with_space(it, cx), name = it.name.unwrap(), generics = c.generics.print(cx), typ = c.type_.print(cx), @@ -1964,7 +1963,7 @@ fn item_static(w: &mut impl fmt::Write, cx: &mut Context<'_>, it: &clean::Item, write!( buffer, "{vis}static {mutability}{name}: {typ}", - vis = visibility_print_with_space(it.visibility(cx.tcx()), it.item_id, cx), + vis = visibility_print_with_space(it, cx), mutability = s.mutability.print_with_space(), name = it.name.unwrap(), typ = s.type_.print(cx) @@ -1982,7 +1981,7 @@ fn item_foreign_type(w: &mut impl fmt::Write, cx: &mut Context<'_>, it: &clean:: write!( buffer, " {}type {};\n}}", - visibility_print_with_space(it.visibility(cx.tcx()), it.item_id, cx), + visibility_print_with_space(it, cx), it.name.unwrap(), ) .unwrap(); @@ -2139,13 +2138,7 @@ fn render_union<'a, 'cx: 'a>( cx: &'a Context<'cx>, ) -> impl fmt::Display + 'a + Captures<'cx> { display_fn(move |mut f| { - let tcx = cx.tcx(); - write!( - f, - "{}union {}", - visibility_print_with_space(it.visibility(tcx), it.item_id, cx), - it.name.unwrap(), - )?; + write!(f, "{}union {}", visibility_print_with_space(it, cx), it.name.unwrap(),)?; let where_displayed = g .map(|g| { @@ -2175,7 +2168,7 @@ fn render_union<'a, 'cx: 'a>( write!( f, " {}{}: {},\n", - visibility_print_with_space(field.visibility(tcx), field.item_id, cx), + visibility_print_with_space(field, cx), field.name.unwrap(), ty.print(cx) )?; @@ -2203,11 +2196,10 @@ fn render_struct( structhead: bool, cx: &Context<'_>, ) { - let tcx = cx.tcx(); write!( w, "{}{}{}", - visibility_print_with_space(it.visibility(tcx), it.item_id, cx), + visibility_print_with_space(it, cx), if structhead { "struct " } else { "" }, it.name.unwrap() ); @@ -2236,7 +2228,6 @@ fn render_struct_fields( has_stripped_entries: bool, cx: &Context<'_>, ) { - let tcx = cx.tcx(); match ty { None => { let where_displayed = @@ -2260,7 +2251,7 @@ fn render_struct_fields( write!( w, "\n{tab} {vis}{name}: {ty},", - vis = visibility_print_with_space(field.visibility(tcx), field.item_id, cx), + vis = visibility_print_with_space(field, cx), name = field.name.unwrap(), ty = ty.print(cx), ); @@ -2296,16 +2287,7 @@ fn render_struct_fields( match *field.kind { clean::StrippedItem(box clean::StructFieldItem(..)) => write!(w, "_"), clean::StructFieldItem(ref ty) => { - write!( - w, - "{}{}", - visibility_print_with_space( - field.visibility(tcx), - field.item_id, - cx - ), - ty.print(cx), - ) + write!(w, "{}{}", visibility_print_with_space(field, cx), ty.print(cx),) } _ => unreachable!(), } From 102015645d37579145c0ba955f22ece95d98c3bd Mon Sep 17 00:00:00 2001 From: Manish Goregaokar <manishsmail@gmail.com> Date: Thu, 14 Mar 2024 13:53:03 +0100 Subject: [PATCH 07/17] print doc(hidden) --- src/librustdoc/html/format.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 1973c2a6021ce..745001e035e77 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1509,7 +1509,9 @@ pub(crate) fn visibility_print_with_space<'a, 'tcx: 'a>( cx: &'a Context<'tcx>, ) -> impl Display + 'a + Captures<'tcx> { use std::fmt::Write as _; - let to_print: Cow<'static, str> = match item.visibility(cx.tcx()) { + + let hidden: &'static str = if item.is_doc_hidden() { "#[doc(hidden)] " } else { "" }; + let vis: Cow<'static, str> = match item.visibility(cx.tcx()) { None => "".into(), Some(ty::Visibility::Public) => "pub ".into(), Some(ty::Visibility::Restricted(vis_did)) => { @@ -1544,7 +1546,10 @@ pub(crate) fn visibility_print_with_space<'a, 'tcx: 'a>( } } }; - display_fn(move |f| f.write_str(&to_print)) + display_fn(move |f| { + f.write_str(&hidden)?; + f.write_str(&vis) + }) } /// This function is the same as print_with_space, except that it renders no links. @@ -1554,9 +1559,10 @@ pub(crate) fn visibility_to_src_with_space<'a, 'tcx: 'a>( visibility: Option<ty::Visibility<DefId>>, tcx: TyCtxt<'tcx>, item_did: DefId, - _is_doc_hidden: bool, + is_doc_hidden: bool, ) -> impl Display + 'a + Captures<'tcx> { - let to_print: Cow<'static, str> = match visibility { + let hidden: &'static str = if is_doc_hidden { "#[doc(hidden)] " } else { "" }; + let vis: Cow<'static, str> = match visibility { None => "".into(), Some(ty::Visibility::Public) => "pub ".into(), Some(ty::Visibility::Restricted(vis_did)) => { @@ -1580,7 +1586,10 @@ pub(crate) fn visibility_to_src_with_space<'a, 'tcx: 'a>( } } }; - display_fn(move |f| f.write_str(&to_print)) + display_fn(move |f| { + f.write_str(&hidden)?; + f.write_str(&vis) + }) } pub(crate) trait PrintWithSpace { From bd03fad8ee6554fbc57758d65015361f766468dd Mon Sep 17 00:00:00 2001 From: Manish Goregaokar <manishsmail@gmail.com> Date: Thu, 14 Mar 2024 14:30:38 +0100 Subject: [PATCH 08/17] Make compact --- src/librustdoc/html/render/print_item.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index d2a03d5840278..0af3f3bc99342 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -511,17 +511,18 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: _ => "", }; - let visibility_emoji = match myitem.visibility(tcx) { + let visibility_and_hidden = match myitem.visibility(tcx) { Some(ty::Visibility::Restricted(_)) => { - "<span title=\"Restricted Visibility\"> 🔒</span> " + if myitem.is_doc_hidden() { + "<span title=\"Restricted Visibility\"> 🔒</span> " + } else { + // Don't separate with a space when there are two of them + "<span title=\"Restricted Visibility\"> 🔒</span><span title=\"Hidden item\">👻</span> " + } } + _ if myitem.is_doc_hidden() => "<span title=\"Hidden item\"> 👻</span> ", _ => "", }; - let hidden_emoji = if myitem.is_doc_hidden() { - "<span title=\"Hidden item\"> 👻</span> " - } else { - "" - }; w.write_str(ITEM_TABLE_ROW_OPEN); let docs = @@ -535,14 +536,13 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: w, "<div class=\"item-name\">\ <a class=\"{class}\" href=\"{href}\" title=\"{title}\">{name}</a>\ - {visibility_emoji}\ - {hidden_emoji}\ + {visibility_and_hidden}\ {unsafety_flag}\ {stab_tags}\ </div>\ {docs_before}{docs}{docs_after}", name = myitem.name.unwrap(), - visibility_emoji = visibility_emoji, + visibility_and_hidden = visibility_and_hidden, stab_tags = extra_info_tags(myitem, item, tcx), class = myitem.type_(), unsafety_flag = unsafety_flag, From 26028209e808377d52ea36618b2cf2d75e0bcd6c Mon Sep 17 00:00:00 2001 From: Manish Goregaokar <manishsmail@gmail.com> Date: Thu, 14 Mar 2024 14:40:54 +0100 Subject: [PATCH 09/17] tests --- tests/rustdoc/display-hidden-items.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/rustdoc/display-hidden-items.rs b/tests/rustdoc/display-hidden-items.rs index 76124554767f2..901ca17d4d2c3 100644 --- a/tests/rustdoc/display-hidden-items.rs +++ b/tests/rustdoc/display-hidden-items.rs @@ -5,19 +5,22 @@ #![crate_name = "foo"] // @has 'foo/index.html' -// @has - '//*[@id="reexport.hidden_reexport"]/code' 'pub use hidden::inside_hidden as hidden_reexport;' +// @has - '//*[@class="item-name"]/span[@title="Hidden item"]' '👻' + +// @has - '//*[@id="reexport.hidden_reexport"]/code' '#[doc(hidden)] pub use hidden::inside_hidden as hidden_reexport;' #[doc(hidden)] pub use hidden::inside_hidden as hidden_reexport; // @has - '//*[@class="item-name"]/a[@class="trait"]' 'TraitHidden' // @has 'foo/trait.TraitHidden.html' +// @has - '//code' '#[doc(hidden)] pub trait TraitHidden' #[doc(hidden)] pub trait TraitHidden {} // @has 'foo/index.html' '//*[@class="item-name"]/a[@class="trait"]' 'Trait' pub trait Trait { // @has 'foo/trait.Trait.html' - // @has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' 'const BAR: u32 = 0u32' + // @has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' '#[doc(hidden)] const BAR: u32 = 0u32' #[doc(hidden)] const BAR: u32 = 0; @@ -41,14 +44,15 @@ impl Struct { } impl Trait for Struct { - // @has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' 'const BAR: u32 = 0u32' - // @has - '//*[@id="method.foo"]/*[@class="code-header"]' 'fn foo()' + // @has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' '#[doc(hidden)] const BAR: u32 = 0u32' + // @has - '//*[@id="method.foo"]/*[@class="code-header"]' '#[doc(hidden)] fn foo()' } // @has - '//*[@id="impl-TraitHidden-for-Struct"]/*[@class="code-header"]' 'impl TraitHidden for Struct' impl TraitHidden for Struct {} // @has 'foo/index.html' '//*[@class="item-name"]/a[@class="enum"]' 'HiddenEnum' // @has 'foo/enum.HiddenEnum.html' +// @has - '//code' '#[doc(hidden)] pub enum HiddenEnum' #[doc(hidden)] pub enum HiddenEnum { A, From 580e5b855d58d2076460b7a16c87e622b7d68960 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar <manishsmail@gmail.com> Date: Thu, 14 Mar 2024 15:07:30 +0100 Subject: [PATCH 10/17] inline --- src/librustdoc/html/format.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 745001e035e77..312765d3e6d03 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1509,8 +1509,6 @@ pub(crate) fn visibility_print_with_space<'a, 'tcx: 'a>( cx: &'a Context<'tcx>, ) -> impl Display + 'a + Captures<'tcx> { use std::fmt::Write as _; - - let hidden: &'static str = if item.is_doc_hidden() { "#[doc(hidden)] " } else { "" }; let vis: Cow<'static, str> = match item.visibility(cx.tcx()) { None => "".into(), Some(ty::Visibility::Public) => "pub ".into(), @@ -1546,8 +1544,13 @@ pub(crate) fn visibility_print_with_space<'a, 'tcx: 'a>( } } }; + + let is_doc_hidden = item.is_doc_hidden(); display_fn(move |f| { - f.write_str(&hidden)?; + if is_doc_hidden { + f.write_str("#[doc(hidden)] ")?; + } + f.write_str(&vis) }) } @@ -1561,7 +1564,6 @@ pub(crate) fn visibility_to_src_with_space<'a, 'tcx: 'a>( item_did: DefId, is_doc_hidden: bool, ) -> impl Display + 'a + Captures<'tcx> { - let hidden: &'static str = if is_doc_hidden { "#[doc(hidden)] " } else { "" }; let vis: Cow<'static, str> = match visibility { None => "".into(), Some(ty::Visibility::Public) => "pub ".into(), @@ -1587,7 +1589,9 @@ pub(crate) fn visibility_to_src_with_space<'a, 'tcx: 'a>( } }; display_fn(move |f| { - f.write_str(&hidden)?; + if is_doc_hidden { + f.write_str("#[doc(hidden)] ")?; + } f.write_str(&vis) }) } From 9718144599d633c95efe6459566a4f86087467ee Mon Sep 17 00:00:00 2001 From: Manish Goregaokar <manishsmail@gmail.com> Date: Thu, 14 Mar 2024 15:08:16 +0100 Subject: [PATCH 11/17] fix polarity --- src/librustdoc/html/render/print_item.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 0af3f3bc99342..5d4f1acc4b188 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -514,10 +514,10 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: let visibility_and_hidden = match myitem.visibility(tcx) { Some(ty::Visibility::Restricted(_)) => { if myitem.is_doc_hidden() { - "<span title=\"Restricted Visibility\"> 🔒</span> " - } else { // Don't separate with a space when there are two of them "<span title=\"Restricted Visibility\"> 🔒</span><span title=\"Hidden item\">👻</span> " + } else { + "<span title=\"Restricted Visibility\"> 🔒</span> " } } _ if myitem.is_doc_hidden() => "<span title=\"Hidden item\"> 👻</span> ", From dc35339514f79f4816f5a36121c25abcfa5723e3 Mon Sep 17 00:00:00 2001 From: Jack Wrenn <jack@wrenn.fyi> Date: Fri, 15 Mar 2024 17:11:11 +0000 Subject: [PATCH 12/17] Safe Transmute: Use 'not yet supported', not 'unspecified' in errors We can (and will) support analyzing the transmutability of types whose layouts aren't completely specified by its repr. This change ensures that the error messages remain sensible after this support lands. --- .../error_reporting/type_err_ctxt_ext.rs | 8 +++---- compiler/rustc_transmute/src/layout/tree.rs | 14 +++++------ compiler/rustc_transmute/src/lib.rs | 8 +++---- .../src/maybe_transmutable/mod.rs | 4 ++-- .../should_require_well_defined_layout.stderr | 12 +++++----- .../should_require_well_defined_layout.stderr | 12 +++++----- .../should_require_well_defined_layout.stderr | 24 +++++++++---------- .../should_require_well_defined_layout.stderr | 4 ++-- 8 files changed, 43 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index b85a05c774fa9..e060803c1cb7d 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -3073,12 +3073,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let src = trait_ref.args.type_at(1); let err_msg = format!("`{src}` cannot be safely transmuted into `{dst}`"); let safe_transmute_explanation = match reason { - rustc_transmute::Reason::SrcIsUnspecified => { - format!("`{src}` does not have a well-specified layout") + rustc_transmute::Reason::SrcIsNotYetSupported => { + format!("analyzing the transmutability of `{src}` is not yet supported.") } - rustc_transmute::Reason::DstIsUnspecified => { - format!("`{dst}` does not have a well-specified layout") + rustc_transmute::Reason::DstIsNotYetSupported => { + format!("analyzing the transmutability of `{dst}` is not yet supported.") } rustc_transmute::Reason::DstIsBitIncompatible => { diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs index c2fc55542ffbc..9a43d67d4351e 100644 --- a/compiler/rustc_transmute/src/layout/tree.rs +++ b/compiler/rustc_transmute/src/layout/tree.rs @@ -186,8 +186,8 @@ pub(crate) mod rustc { #[derive(Debug, Copy, Clone)] pub(crate) enum Err { - /// The layout of the type is unspecified. - Unspecified, + /// The layout of the type is not yet supported. + NotYetSupported, /// This error will be surfaced elsewhere by rustc, so don't surface it. UnknownLayout, /// Overflow size @@ -288,14 +288,14 @@ pub(crate) mod rustc { if members.len() == 0 { Ok(Tree::unit()) } else { - Err(Err::Unspecified) + Err(Err::NotYetSupported) } } ty::Array(ty, len) => { let len = len .try_eval_target_usize(tcx, ParamEnv::reveal_all()) - .ok_or(Err::Unspecified)?; + .ok_or(Err::NotYetSupported)?; let elt = Tree::from_ty(*ty, tcx)?; Ok(std::iter::repeat(elt) .take(len as usize) @@ -307,7 +307,7 @@ pub(crate) mod rustc { // If the layout is ill-specified, halt. if !(adt_def.repr().c() || adt_def.repr().int.is_some()) { - return Err(Err::Unspecified); + return Err(Err::NotYetSupported); } // Compute a summary of the type's layout. @@ -348,7 +348,7 @@ pub(crate) mod rustc { AdtKind::Union => { // is the layout well-defined? if !adt_def.repr().c() { - return Err(Err::Unspecified); + return Err(Err::NotYetSupported); } let ty_layout = layout_of(tcx, ty)?; @@ -384,7 +384,7 @@ pub(crate) mod rustc { })) } - _ => Err(Err::Unspecified), + _ => Err(Err::NotYetSupported), } } diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index 8f3af491453e5..e871c4659b4b9 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -43,10 +43,10 @@ pub enum Condition<R> { /// Answers "why wasn't the source type transmutable into the destination type?" #[derive(Debug, Hash, Eq, PartialEq, PartialOrd, Ord, Clone)] pub enum Reason<T> { - /// The layout of the source type is unspecified. - SrcIsUnspecified, - /// The layout of the destination type is unspecified. - DstIsUnspecified, + /// The layout of the source type is not yet supported. + SrcIsNotYetSupported, + /// The layout of the destination type is not yet supported. + DstIsNotYetSupported, /// The layout of the destination type is bit-incompatible with the source type. DstIsBitIncompatible, /// The destination type may carry safety invariants. diff --git a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs index e9f425686c4c9..16d15580a05b8 100644 --- a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs +++ b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs @@ -56,8 +56,8 @@ mod rustc { } (Err(Err::UnknownLayout), _) => Answer::No(Reason::SrcLayoutUnknown), (_, Err(Err::UnknownLayout)) => Answer::No(Reason::DstLayoutUnknown), - (Err(Err::Unspecified), _) => Answer::No(Reason::SrcIsUnspecified), - (_, Err(Err::Unspecified)) => Answer::No(Reason::DstIsUnspecified), + (Err(Err::NotYetSupported), _) => Answer::No(Reason::SrcIsNotYetSupported), + (_, Err(Err::NotYetSupported)) => Answer::No(Reason::DstIsNotYetSupported), (Err(Err::SizeOverflow), _) => Answer::No(Reason::SrcSizeOverflow), (_, Err(Err::SizeOverflow)) => Answer::No(Reason::DstSizeOverflow), (Ok(src), Ok(dst)) => MaybeTransmutableQuery { src, dst, assume, context }.answer(), diff --git a/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr b/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr index fd21ac34183f5..e486928a44520 100644 --- a/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr +++ b/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr @@ -2,7 +2,7 @@ error[E0277]: `[String; 0]` cannot be safely transmuted into `()` --> $DIR/should_require_well_defined_layout.rs:25:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `[String; 0]` does not have a well-specified layout + | ^^ analyzing the transmutability of `[String; 0]` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -23,7 +23,7 @@ error[E0277]: `u128` cannot be safely transmuted into `[String; 0]` --> $DIR/should_require_well_defined_layout.rs:26:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `[String; 0]` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `[String; 0]` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -44,7 +44,7 @@ error[E0277]: `[String; 1]` cannot be safely transmuted into `()` --> $DIR/should_require_well_defined_layout.rs:31:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `[String; 1]` does not have a well-specified layout + | ^^ analyzing the transmutability of `[String; 1]` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -65,7 +65,7 @@ error[E0277]: `u128` cannot be safely transmuted into `[String; 1]` --> $DIR/should_require_well_defined_layout.rs:32:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `[String; 1]` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `[String; 1]` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -86,7 +86,7 @@ error[E0277]: `[String; 2]` cannot be safely transmuted into `()` --> $DIR/should_require_well_defined_layout.rs:37:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `[String; 2]` does not have a well-specified layout + | ^^ analyzing the transmutability of `[String; 2]` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -107,7 +107,7 @@ error[E0277]: `u128` cannot be safely transmuted into `[String; 2]` --> $DIR/should_require_well_defined_layout.rs:38:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `[String; 2]` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `[String; 2]` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 diff --git a/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr b/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr index 24730935047bc..2a683de6a65cb 100644 --- a/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr +++ b/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr @@ -2,7 +2,7 @@ error[E0277]: `void::repr_rust` cannot be safely transmuted into `()` --> $DIR/should_require_well_defined_layout.rs:27:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `void::repr_rust` does not have a well-specified layout + | ^^ analyzing the transmutability of `void::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 @@ -24,7 +24,7 @@ error[E0277]: `u128` cannot be safely transmuted into `void::repr_rust` --> $DIR/should_require_well_defined_layout.rs:28:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `void::repr_rust` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `void::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 @@ -46,7 +46,7 @@ error[E0277]: `singleton::repr_rust` cannot be safely transmuted into `()` --> $DIR/should_require_well_defined_layout.rs:33:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `singleton::repr_rust` does not have a well-specified layout + | ^^ analyzing the transmutability of `singleton::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 @@ -68,7 +68,7 @@ error[E0277]: `u128` cannot be safely transmuted into `singleton::repr_rust` --> $DIR/should_require_well_defined_layout.rs:34:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `singleton::repr_rust` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `singleton::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 @@ -90,7 +90,7 @@ error[E0277]: `duplex::repr_rust` cannot be safely transmuted into `()` --> $DIR/should_require_well_defined_layout.rs:39:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `duplex::repr_rust` does not have a well-specified layout + | ^^ analyzing the transmutability of `duplex::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 @@ -112,7 +112,7 @@ error[E0277]: `u128` cannot be safely transmuted into `duplex::repr_rust` --> $DIR/should_require_well_defined_layout.rs:40:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `duplex::repr_rust` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `duplex::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 diff --git a/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr b/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr index 924422de5382a..77788f72c2168 100644 --- a/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr +++ b/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr @@ -2,7 +2,7 @@ error[E0277]: `should_reject_repr_rust::unit::repr_rust` cannot be safely transm --> $DIR/should_require_well_defined_layout.rs:27:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `should_reject_repr_rust::unit::repr_rust` does not have a well-specified layout + | ^^ analyzing the transmutability of `should_reject_repr_rust::unit::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -24,7 +24,7 @@ error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust:: --> $DIR/should_require_well_defined_layout.rs:28:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `should_reject_repr_rust::unit::repr_rust` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `should_reject_repr_rust::unit::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -46,7 +46,7 @@ error[E0277]: `should_reject_repr_rust::tuple::repr_rust` cannot be safely trans --> $DIR/should_require_well_defined_layout.rs:33:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `should_reject_repr_rust::tuple::repr_rust` does not have a well-specified layout + | ^^ analyzing the transmutability of `should_reject_repr_rust::tuple::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -68,7 +68,7 @@ error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust:: --> $DIR/should_require_well_defined_layout.rs:34:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `should_reject_repr_rust::tuple::repr_rust` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `should_reject_repr_rust::tuple::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -90,7 +90,7 @@ error[E0277]: `should_reject_repr_rust::braces::repr_rust` cannot be safely tran --> $DIR/should_require_well_defined_layout.rs:39:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `should_reject_repr_rust::braces::repr_rust` does not have a well-specified layout + | ^^ analyzing the transmutability of `should_reject_repr_rust::braces::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -112,7 +112,7 @@ error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust:: --> $DIR/should_require_well_defined_layout.rs:40:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `should_reject_repr_rust::braces::repr_rust` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `should_reject_repr_rust::braces::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -134,7 +134,7 @@ error[E0277]: `aligned::repr_rust` cannot be safely transmuted into `()` --> $DIR/should_require_well_defined_layout.rs:45:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `aligned::repr_rust` does not have a well-specified layout + | ^^ analyzing the transmutability of `aligned::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -156,7 +156,7 @@ error[E0277]: `u128` cannot be safely transmuted into `aligned::repr_rust` --> $DIR/should_require_well_defined_layout.rs:46:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `aligned::repr_rust` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `aligned::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -178,7 +178,7 @@ error[E0277]: `packed::repr_rust` cannot be safely transmuted into `()` --> $DIR/should_require_well_defined_layout.rs:51:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `packed::repr_rust` does not have a well-specified layout + | ^^ analyzing the transmutability of `packed::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -200,7 +200,7 @@ error[E0277]: `u128` cannot be safely transmuted into `packed::repr_rust` --> $DIR/should_require_well_defined_layout.rs:52:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `packed::repr_rust` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `packed::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -222,7 +222,7 @@ error[E0277]: `nested::repr_c` cannot be safely transmuted into `()` --> $DIR/should_require_well_defined_layout.rs:58:49 | LL | assert::is_maybe_transmutable::<repr_c, ()>(); - | ^^ `nested::repr_c` does not have a well-specified layout + | ^^ analyzing the transmutability of `nested::repr_c` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -244,7 +244,7 @@ error[E0277]: `u128` cannot be safely transmuted into `nested::repr_c` --> $DIR/should_require_well_defined_layout.rs:59:47 | LL | assert::is_maybe_transmutable::<u128, repr_c>(); - | ^^^^^^ `nested::repr_c` does not have a well-specified layout + | ^^^^^^ analyzing the transmutability of `nested::repr_c` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 diff --git a/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr b/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr index ee0e8a6643419..bec07f131039b 100644 --- a/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr +++ b/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr @@ -2,7 +2,7 @@ error[E0277]: `should_reject_repr_rust::repr_rust` cannot be safely transmuted i --> $DIR/should_require_well_defined_layout.rs:29:48 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `should_reject_repr_rust::repr_rust` does not have a well-specified layout + | ^^ analyzing the transmutability of `should_reject_repr_rust::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -24,7 +24,7 @@ error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust:: --> $DIR/should_require_well_defined_layout.rs:30:43 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `should_reject_repr_rust::repr_rust` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `should_reject_repr_rust::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 From 19bc3370632c4f26be1cb16b90f72375c55879a3 Mon Sep 17 00:00:00 2001 From: Maybe Waffle <waffle.lapkin@gmail.com> Date: Fri, 15 Mar 2024 12:27:54 +0000 Subject: [PATCH 13/17] Add `rustc_never_type_mode` crate-level attribute to allow experimenting --- compiler/rustc_feature/src/builtin_attrs.rs | 7 ++ compiler/rustc_hir_typeck/src/fallback.rs | 119 ++++++++++++++------ compiler/rustc_span/src/symbol.rs | 4 + 3 files changed, 96 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 1f77484d65ce0..a5f8b0b270fc1 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -580,6 +580,13 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ "`may_dangle` has unstable semantics and may be removed in the future", ), + rustc_attr!( + rustc_never_type_mode, Normal, template!(NameValueStr: "fallback_to_unit|fallback_to_niko|no_fallback"), ErrorFollowing, + @only_local: true, + "`rustc_never_type_fallback` is used to experiment with never type fallback and work on \ + never type stabilization, and will never be stable" + ), + // ========================================================================== // Internal attributes: Runtime related: // ========================================================================== diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index aa8bbad1d1246..5206e79177bbe 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -4,8 +4,19 @@ use rustc_data_structures::{ graph::{iterate::DepthFirstSearch, vec_graph::VecGraph}, unord::{UnordBag, UnordMap, UnordSet}, }; +use rustc_hir::def_id::CRATE_DEF_ID; use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; use rustc_middle::ty::{self, Ty}; +use rustc_span::sym; + +enum DivergingFallbackBehavior { + /// Always fallback to `()` (aka "always spontaneous decay") + FallbackToUnit, + /// Sometimes fallback to `!`, but mainly fallback to `()` so that most of the crates are not broken. + FallbackToNiko, + /// Don't fallback at all + NoFallback, +} impl<'tcx> FnCtxt<'_, 'tcx> { /// Performs type inference fallback, setting `FnCtxt::fallback_has_occurred` @@ -64,7 +75,9 @@ impl<'tcx> FnCtxt<'_, 'tcx> { return false; } - let diverging_fallback = self.calculate_diverging_fallback(&unresolved_variables); + let diverging_behavior = self.diverging_fallback_behavior(); + let diverging_fallback = + self.calculate_diverging_fallback(&unresolved_variables, diverging_behavior); // We do fallback in two passes, to try to generate // better error messages. @@ -78,6 +91,31 @@ impl<'tcx> FnCtxt<'_, 'tcx> { fallback_occurred } + fn diverging_fallback_behavior(&self) -> DivergingFallbackBehavior { + let Some((mode, span)) = self + .tcx + .get_attr(CRATE_DEF_ID, sym::rustc_never_type_mode) + .map(|attr| (attr.value_str().unwrap(), attr.span)) + else { + if self.tcx.features().never_type_fallback { + return DivergingFallbackBehavior::FallbackToNiko; + } + + return DivergingFallbackBehavior::FallbackToUnit; + }; + + match mode { + sym::fallback_to_unit => DivergingFallbackBehavior::FallbackToUnit, + sym::fallback_to_niko => DivergingFallbackBehavior::FallbackToNiko, + sym::no_fallback => DivergingFallbackBehavior::NoFallback, + _ => { + self.tcx.dcx().span_err(span, format!("unknown never type mode: `{mode}` (supported: `fallback_to_unit`, `fallback_to_niko`, and `no_fallback`)")); + + DivergingFallbackBehavior::FallbackToUnit + } + } + } + fn fallback_effects(&self) -> bool { let unsolved_effects = self.unsolved_effects(); @@ -232,6 +270,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { fn calculate_diverging_fallback( &self, unresolved_variables: &[Ty<'tcx>], + behavior: DivergingFallbackBehavior, ) -> UnordMap<Ty<'tcx>, Ty<'tcx>> { debug!("calculate_diverging_fallback({:?})", unresolved_variables); @@ -345,39 +384,51 @@ impl<'tcx> FnCtxt<'_, 'tcx> { output: infer_var_infos.items().any(|info| info.output), }; - if found_infer_var_info.self_in_trait && found_infer_var_info.output { - // This case falls back to () to ensure that the code pattern in - // tests/ui/never_type/fallback-closure-ret.rs continues to - // compile when never_type_fallback is enabled. - // - // This rule is not readily explainable from first principles, - // but is rather intended as a patchwork fix to ensure code - // which compiles before the stabilization of never type - // fallback continues to work. - // - // Typically this pattern is encountered in a function taking a - // closure as a parameter, where the return type of that closure - // (checked by `relationship.output`) is expected to implement - // some trait (checked by `relationship.self_in_trait`). This - // can come up in non-closure cases too, so we do not limit this - // rule to specifically `FnOnce`. - // - // When the closure's body is something like `panic!()`, the - // return type would normally be inferred to `!`. However, it - // needs to fall back to `()` in order to still compile, as the - // trait is specifically implemented for `()` but not `!`. - // - // For details on the requirements for these relationships to be - // set, see the relationship finding module in - // compiler/rustc_trait_selection/src/traits/relationships.rs. - debug!("fallback to () - found trait and projection: {:?}", diverging_vid); - diverging_fallback.insert(diverging_ty, self.tcx.types.unit); - } else if can_reach_non_diverging { - debug!("fallback to () - reached non-diverging: {:?}", diverging_vid); - diverging_fallback.insert(diverging_ty, self.tcx.types.unit); - } else { - debug!("fallback to ! - all diverging: {:?}", diverging_vid); - diverging_fallback.insert(diverging_ty, Ty::new_diverging_default(self.tcx)); + use DivergingFallbackBehavior::*; + match behavior { + FallbackToUnit => { + debug!("fallback to () - legacy: {:?}", diverging_vid); + diverging_fallback.insert(diverging_ty, self.tcx.types.unit); + } + FallbackToNiko => { + if found_infer_var_info.self_in_trait && found_infer_var_info.output { + // This case falls back to () to ensure that the code pattern in + // tests/ui/never_type/fallback-closure-ret.rs continues to + // compile when never_type_fallback is enabled. + // + // This rule is not readily explainable from first principles, + // but is rather intended as a patchwork fix to ensure code + // which compiles before the stabilization of never type + // fallback continues to work. + // + // Typically this pattern is encountered in a function taking a + // closure as a parameter, where the return type of that closure + // (checked by `relationship.output`) is expected to implement + // some trait (checked by `relationship.self_in_trait`). This + // can come up in non-closure cases too, so we do not limit this + // rule to specifically `FnOnce`. + // + // When the closure's body is something like `panic!()`, the + // return type would normally be inferred to `!`. However, it + // needs to fall back to `()` in order to still compile, as the + // trait is specifically implemented for `()` but not `!`. + // + // For details on the requirements for these relationships to be + // set, see the relationship finding module in + // compiler/rustc_trait_selection/src/traits/relationships.rs. + debug!("fallback to () - found trait and projection: {:?}", diverging_vid); + diverging_fallback.insert(diverging_ty, self.tcx.types.unit); + } else if can_reach_non_diverging { + debug!("fallback to () - reached non-diverging: {:?}", diverging_vid); + diverging_fallback.insert(diverging_ty, self.tcx.types.unit); + } else { + debug!("fallback to ! - all diverging: {:?}", diverging_vid); + diverging_fallback.insert(diverging_ty, self.tcx.types.never); + } + } + NoFallback => { + debug!("no fallback - `rustc_never_type_mode = "no_fallback"`: {:?}", diverging_vid); + } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 7de0555bb220d..0df5e7873c264 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -815,6 +815,8 @@ symbols! { fadd_algebraic, fadd_fast, fake_variadic, + fallback_to_niko, + fallback_to_unit, fdiv_algebraic, fdiv_fast, feature, @@ -1233,6 +1235,7 @@ symbols! { no_crate_inject, no_debug, no_default_passes, + no_fallback, no_implicit_prelude, no_inline, no_link, @@ -1551,6 +1554,7 @@ symbols! { rustc_mir, rustc_must_implement_one_of, rustc_never_returns_null_ptr, + rustc_never_type_mode, rustc_no_mir_inline, rustc_nonnull_optimization_guaranteed, rustc_nounwind, From adfdd273ae2bf79aa3bb1f7b453e4df9c188a781 Mon Sep 17 00:00:00 2001 From: Maybe Waffle <waffle.lapkin@gmail.com> Date: Fri, 15 Mar 2024 14:50:45 +0000 Subject: [PATCH 14/17] Add `rustc_never_type_mode = "no_fallback"` --- compiler/rustc_feature/src/builtin_attrs.rs | 2 +- compiler/rustc_hir_typeck/src/fallback.rs | 18 ++++++++++++++++-- compiler/rustc_span/src/symbol.rs | 1 + 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index a5f8b0b270fc1..e5a29f3a8462e 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -581,7 +581,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), rustc_attr!( - rustc_never_type_mode, Normal, template!(NameValueStr: "fallback_to_unit|fallback_to_niko|no_fallback"), ErrorFollowing, + rustc_never_type_mode, Normal, template!(NameValueStr: "fallback_to_unit|fallback_to_niko|fallback_to_never|no_fallback"), ErrorFollowing, @only_local: true, "`rustc_never_type_fallback` is used to experiment with never type fallback and work on \ never type stabilization, and will never be stable" diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 5206e79177bbe..c16e941d4c5b7 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -14,6 +14,9 @@ enum DivergingFallbackBehavior { FallbackToUnit, /// Sometimes fallback to `!`, but mainly fallback to `()` so that most of the crates are not broken. FallbackToNiko, + /// Always fallback to `!` (which should be equivalent to never falling back + not making + /// never-to-any coercions unless necessary) + FallbackToNever, /// Don't fallback at all NoFallback, } @@ -107,9 +110,10 @@ impl<'tcx> FnCtxt<'_, 'tcx> { match mode { sym::fallback_to_unit => DivergingFallbackBehavior::FallbackToUnit, sym::fallback_to_niko => DivergingFallbackBehavior::FallbackToNiko, + sym::fallback_to_never => DivergingFallbackBehavior::FallbackToNever, sym::no_fallback => DivergingFallbackBehavior::NoFallback, _ => { - self.tcx.dcx().span_err(span, format!("unknown never type mode: `{mode}` (supported: `fallback_to_unit`, `fallback_to_niko`, and `no_fallback`)")); + self.tcx.dcx().span_err(span, format!("unknown never type mode: `{mode}` (supported: `fallback_to_unit`, `fallback_to_niko`, `fallback_to_never` and `no_fallback`)")); DivergingFallbackBehavior::FallbackToUnit } @@ -426,8 +430,18 @@ impl<'tcx> FnCtxt<'_, 'tcx> { diverging_fallback.insert(diverging_ty, self.tcx.types.never); } } + FallbackToNever => { + debug!( + "fallback to ! - `rustc_never_type_mode = \"fallback_to_never\")`: {:?}", + diverging_vid + ); + diverging_fallback.insert(diverging_ty, self.tcx.types.never); + } NoFallback => { - debug!("no fallback - `rustc_never_type_mode = "no_fallback"`: {:?}", diverging_vid); + debug!( + "no fallback - `rustc_never_type_mode = \"no_fallback\"`: {:?}", + diverging_vid + ); } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 0df5e7873c264..e43c9533382e1 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -815,6 +815,7 @@ symbols! { fadd_algebraic, fadd_fast, fake_variadic, + fallback_to_never, fallback_to_niko, fallback_to_unit, fdiv_algebraic, From e1e719e1a1916dee9365c390dcb640390433d078 Mon Sep 17 00:00:00 2001 From: Wilfred Hughes <wilfred@meta.com> Date: Fri, 15 Mar 2024 10:51:41 -0700 Subject: [PATCH 15/17] Mention labelled blocks in `break` docs `break` doesn't require a loop, so note this in the docs. This is covered in the linked sections of the rust reference, but this page implied that `break` is only for loops. --- library/std/src/keyword_docs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index 873bfb6218b64..8415f36eba251 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -48,7 +48,7 @@ mod as_keyword {} #[doc(keyword = "break")] // -/// Exit early from a loop. +/// Exit early from a loop or labelled block. /// /// When `break` is encountered, execution of the associated loop body is /// immediately terminated. From 107807d3932c2765580725604802f76935239723 Mon Sep 17 00:00:00 2001 From: Jack Wrenn <jack@wrenn.fyi> Date: Fri, 15 Mar 2024 17:55:49 +0000 Subject: [PATCH 16/17] Safe Transmute: lowercase diagnostics --- .../error_reporting/type_err_ctxt_ext.rs | 8 +- .../alignment/align-fail.stderr | 2 +- ...ve_reprs_should_have_correct_length.stderr | 40 +++--- .../enums/should_pad_variants.stderr | 2 +- .../enums/should_respect_endianness.stderr | 2 +- .../primitives/bool-mut.stderr | 2 +- .../primitives/bool.current.stderr | 2 +- .../primitives/bool.next.stderr | 2 +- .../primitives/numbers.current.stderr | 114 +++++++++--------- .../primitives/numbers.next.stderr | 114 +++++++++--------- .../primitives/unit.current.stderr | 2 +- .../primitives/unit.next.stderr | 2 +- ...sive-wrapper-types-bit-incompatible.stderr | 2 +- .../references/reject_extension.stderr | 2 +- .../references/unit-to-u8.stderr | 2 +- tests/ui/transmutability/region-infer.stderr | 2 +- .../transmute-padding-ice.stderr | 2 +- .../unions/should_pad_variants.stderr | 2 +- .../unions/should_reject_contraction.stderr | 2 +- .../unions/should_reject_disjoint.stderr | 4 +- .../unions/should_reject_intersecting.stderr | 4 +- 21 files changed, 157 insertions(+), 157 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index e060803c1cb7d..8011d725420be 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -3082,20 +3082,20 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } rustc_transmute::Reason::DstIsBitIncompatible => { - format!("At least one value of `{src}` isn't a bit-valid value of `{dst}`") + format!("at least one value of `{src}` isn't a bit-valid value of `{dst}`") } rustc_transmute::Reason::DstMayHaveSafetyInvariants => { format!("`{dst}` may carry safety invariants") } rustc_transmute::Reason::DstIsTooBig => { - format!("The size of `{src}` is smaller than the size of `{dst}`") + format!("the size of `{src}` is smaller than the size of `{dst}`") } rustc_transmute::Reason::DstRefIsTooBig { src, dst } => { let src_size = src.size; let dst_size = dst.size; format!( - "The referent size of `{src}` ({src_size} bytes) is smaller than that of `{dst}` ({dst_size} bytes)" + "the referent size of `{src}` ({src_size} bytes) is smaller than that of `{dst}` ({dst_size} bytes)" ) } rustc_transmute::Reason::SrcSizeOverflow => { @@ -3113,7 +3113,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { dst_min_align, } => { format!( - "The minimum alignment of `{src}` ({src_min_align}) should be greater than that of `{dst}` ({dst_min_align})" + "the minimum alignment of `{src}` ({src_min_align}) should be greater than that of `{dst}` ({dst_min_align})" ) } rustc_transmute::Reason::DstIsMoreUnique => { diff --git a/tests/ui/transmutability/alignment/align-fail.stderr b/tests/ui/transmutability/alignment/align-fail.stderr index c92c3d841f294..f05e55fb024d8 100644 --- a/tests/ui/transmutability/alignment/align-fail.stderr +++ b/tests/ui/transmutability/alignment/align-fail.stderr @@ -2,7 +2,7 @@ error[E0277]: `&[u8; 0]` cannot be safely transmuted into `&[u16; 0]` --> $DIR/align-fail.rs:21:55 | LL | ...tatic [u8; 0], &'static [u16; 0]>(); - | ^^^^^^^^^^^^^^^^^ The minimum alignment of `&[u8; 0]` (1) should be greater than that of `&[u16; 0]` (2) + | ^^^^^^^^^^^^^^^^^ the minimum alignment of `&[u8; 0]` (1) should be greater than that of `&[u16; 0]` (2) | note: required by a bound in `is_maybe_transmutable` --> $DIR/align-fail.rs:9:14 diff --git a/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr index b2ff04eeed9e4..6c88bf4ff9686 100644 --- a/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr +++ b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr @@ -2,7 +2,7 @@ error[E0277]: `Zst` cannot be safely transmuted into `V0i8` --> $DIR/primitive_reprs_should_have_correct_length.rs:46:44 | LL | assert::is_transmutable::<Smaller, Current>(); - | ^^^^^^^ The size of `Zst` is smaller than the size of `V0i8` + | ^^^^^^^ the size of `Zst` is smaller than the size of `V0i8` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -24,7 +24,7 @@ error[E0277]: `V0i8` cannot be safely transmuted into `u16` --> $DIR/primitive_reprs_should_have_correct_length.rs:48:44 | LL | assert::is_transmutable::<Current, Larger>(); - | ^^^^^^ The size of `V0i8` is smaller than the size of `u16` + | ^^^^^^ the size of `V0i8` is smaller than the size of `u16` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -46,7 +46,7 @@ error[E0277]: `Zst` cannot be safely transmuted into `V0u8` --> $DIR/primitive_reprs_should_have_correct_length.rs:54:44 | LL | assert::is_transmutable::<Smaller, Current>(); - | ^^^^^^^ The size of `Zst` is smaller than the size of `V0u8` + | ^^^^^^^ the size of `Zst` is smaller than the size of `V0u8` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -68,7 +68,7 @@ error[E0277]: `V0u8` cannot be safely transmuted into `u16` --> $DIR/primitive_reprs_should_have_correct_length.rs:56:44 | LL | assert::is_transmutable::<Current, Larger>(); - | ^^^^^^ The size of `V0u8` is smaller than the size of `u16` + | ^^^^^^ the size of `V0u8` is smaller than the size of `u16` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -90,7 +90,7 @@ error[E0277]: `u8` cannot be safely transmuted into `V0i16` --> $DIR/primitive_reprs_should_have_correct_length.rs:68:44 | LL | assert::is_transmutable::<Smaller, Current>(); - | ^^^^^^^ The size of `u8` is smaller than the size of `V0i16` + | ^^^^^^^ the size of `u8` is smaller than the size of `V0i16` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -112,7 +112,7 @@ error[E0277]: `V0i16` cannot be safely transmuted into `u32` --> $DIR/primitive_reprs_should_have_correct_length.rs:70:44 | LL | assert::is_transmutable::<Current, Larger>(); - | ^^^^^^ The size of `V0i16` is smaller than the size of `u32` + | ^^^^^^ the size of `V0i16` is smaller than the size of `u32` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -134,7 +134,7 @@ error[E0277]: `u8` cannot be safely transmuted into `V0u16` --> $DIR/primitive_reprs_should_have_correct_length.rs:76:44 | LL | assert::is_transmutable::<Smaller, Current>(); - | ^^^^^^^ The size of `u8` is smaller than the size of `V0u16` + | ^^^^^^^ the size of `u8` is smaller than the size of `V0u16` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -156,7 +156,7 @@ error[E0277]: `V0u16` cannot be safely transmuted into `u32` --> $DIR/primitive_reprs_should_have_correct_length.rs:78:44 | LL | assert::is_transmutable::<Current, Larger>(); - | ^^^^^^ The size of `V0u16` is smaller than the size of `u32` + | ^^^^^^ the size of `V0u16` is smaller than the size of `u32` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -178,7 +178,7 @@ error[E0277]: `u16` cannot be safely transmuted into `V0i32` --> $DIR/primitive_reprs_should_have_correct_length.rs:90:44 | LL | assert::is_transmutable::<Smaller, Current>(); - | ^^^^^^^ The size of `u16` is smaller than the size of `V0i32` + | ^^^^^^^ the size of `u16` is smaller than the size of `V0i32` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -200,7 +200,7 @@ error[E0277]: `V0i32` cannot be safely transmuted into `u64` --> $DIR/primitive_reprs_should_have_correct_length.rs:92:44 | LL | assert::is_transmutable::<Current, Larger>(); - | ^^^^^^ The size of `V0i32` is smaller than the size of `u64` + | ^^^^^^ the size of `V0i32` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -222,7 +222,7 @@ error[E0277]: `u16` cannot be safely transmuted into `V0u32` --> $DIR/primitive_reprs_should_have_correct_length.rs:98:44 | LL | assert::is_transmutable::<Smaller, Current>(); - | ^^^^^^^ The size of `u16` is smaller than the size of `V0u32` + | ^^^^^^^ the size of `u16` is smaller than the size of `V0u32` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -244,7 +244,7 @@ error[E0277]: `V0u32` cannot be safely transmuted into `u64` --> $DIR/primitive_reprs_should_have_correct_length.rs:100:44 | LL | assert::is_transmutable::<Current, Larger>(); - | ^^^^^^ The size of `V0u32` is smaller than the size of `u64` + | ^^^^^^ the size of `V0u32` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -266,7 +266,7 @@ error[E0277]: `u32` cannot be safely transmuted into `V0i64` --> $DIR/primitive_reprs_should_have_correct_length.rs:112:44 | LL | assert::is_transmutable::<Smaller, Current>(); - | ^^^^^^^ The size of `u32` is smaller than the size of `V0i64` + | ^^^^^^^ the size of `u32` is smaller than the size of `V0i64` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -288,7 +288,7 @@ error[E0277]: `V0i64` cannot be safely transmuted into `u128` --> $DIR/primitive_reprs_should_have_correct_length.rs:114:44 | LL | assert::is_transmutable::<Current, Larger>(); - | ^^^^^^ The size of `V0i64` is smaller than the size of `u128` + | ^^^^^^ the size of `V0i64` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -310,7 +310,7 @@ error[E0277]: `u32` cannot be safely transmuted into `V0u64` --> $DIR/primitive_reprs_should_have_correct_length.rs:120:44 | LL | assert::is_transmutable::<Smaller, Current>(); - | ^^^^^^^ The size of `u32` is smaller than the size of `V0u64` + | ^^^^^^^ the size of `u32` is smaller than the size of `V0u64` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -332,7 +332,7 @@ error[E0277]: `V0u64` cannot be safely transmuted into `u128` --> $DIR/primitive_reprs_should_have_correct_length.rs:122:44 | LL | assert::is_transmutable::<Current, Larger>(); - | ^^^^^^ The size of `V0u64` is smaller than the size of `u128` + | ^^^^^^ the size of `V0u64` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -354,7 +354,7 @@ error[E0277]: `u8` cannot be safely transmuted into `V0isize` --> $DIR/primitive_reprs_should_have_correct_length.rs:134:44 | LL | assert::is_transmutable::<Smaller, Current>(); - | ^^^^^^^ The size of `u8` is smaller than the size of `V0isize` + | ^^^^^^^ the size of `u8` is smaller than the size of `V0isize` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -376,7 +376,7 @@ error[E0277]: `V0isize` cannot be safely transmuted into `[usize; 2]` --> $DIR/primitive_reprs_should_have_correct_length.rs:136:44 | LL | assert::is_transmutable::<Current, Larger>(); - | ^^^^^^ The size of `V0isize` is smaller than the size of `[usize; 2]` + | ^^^^^^ the size of `V0isize` is smaller than the size of `[usize; 2]` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -398,7 +398,7 @@ error[E0277]: `u8` cannot be safely transmuted into `V0usize` --> $DIR/primitive_reprs_should_have_correct_length.rs:142:44 | LL | assert::is_transmutable::<Smaller, Current>(); - | ^^^^^^^ The size of `u8` is smaller than the size of `V0usize` + | ^^^^^^^ the size of `u8` is smaller than the size of `V0usize` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -420,7 +420,7 @@ error[E0277]: `V0usize` cannot be safely transmuted into `[usize; 2]` --> $DIR/primitive_reprs_should_have_correct_length.rs:144:44 | LL | assert::is_transmutable::<Current, Larger>(); - | ^^^^^^ The size of `V0usize` is smaller than the size of `[usize; 2]` + | ^^^^^^ the size of `V0usize` is smaller than the size of `[usize; 2]` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 diff --git a/tests/ui/transmutability/enums/should_pad_variants.stderr b/tests/ui/transmutability/enums/should_pad_variants.stderr index 13b4c8053adb2..da4294bdbce8c 100644 --- a/tests/ui/transmutability/enums/should_pad_variants.stderr +++ b/tests/ui/transmutability/enums/should_pad_variants.stderr @@ -2,7 +2,7 @@ error[E0277]: `Src` cannot be safely transmuted into `Dst` --> $DIR/should_pad_variants.rs:43:36 | LL | assert::is_transmutable::<Src, Dst>(); - | ^^^ The size of `Src` is smaller than the size of `Dst` + | ^^^ the size of `Src` is smaller than the size of `Dst` | note: required by a bound in `is_transmutable` --> $DIR/should_pad_variants.rs:13:14 diff --git a/tests/ui/transmutability/enums/should_respect_endianness.stderr b/tests/ui/transmutability/enums/should_respect_endianness.stderr index c2a2eb53458eb..9f88bb0681345 100644 --- a/tests/ui/transmutability/enums/should_respect_endianness.stderr +++ b/tests/ui/transmutability/enums/should_respect_endianness.stderr @@ -2,7 +2,7 @@ error[E0277]: `Src` cannot be safely transmuted into `Unexpected` --> $DIR/should_respect_endianness.rs:35:36 | LL | assert::is_transmutable::<Src, Unexpected>(); - | ^^^^^^^^^^ At least one value of `Src` isn't a bit-valid value of `Unexpected` + | ^^^^^^^^^^ at least one value of `Src` isn't a bit-valid value of `Unexpected` | note: required by a bound in `is_transmutable` --> $DIR/should_respect_endianness.rs:13:14 diff --git a/tests/ui/transmutability/primitives/bool-mut.stderr b/tests/ui/transmutability/primitives/bool-mut.stderr index c4f295fc70a2e..464c2755e11b6 100644 --- a/tests/ui/transmutability/primitives/bool-mut.stderr +++ b/tests/ui/transmutability/primitives/bool-mut.stderr @@ -2,7 +2,7 @@ error[E0277]: `u8` cannot be safely transmuted into `bool` --> $DIR/bool-mut.rs:15:50 | LL | assert::is_transmutable::<&'static mut bool, &'static mut u8>() - | ^^^^^^^^^^^^^^^ At least one value of `u8` isn't a bit-valid value of `bool` + | ^^^^^^^^^^^^^^^ at least one value of `u8` isn't a bit-valid value of `bool` | note: required by a bound in `is_transmutable` --> $DIR/bool-mut.rs:10:14 diff --git a/tests/ui/transmutability/primitives/bool.current.stderr b/tests/ui/transmutability/primitives/bool.current.stderr index 98e4a1029c907..da6a4a44e95e0 100644 --- a/tests/ui/transmutability/primitives/bool.current.stderr +++ b/tests/ui/transmutability/primitives/bool.current.stderr @@ -2,7 +2,7 @@ error[E0277]: `u8` cannot be safely transmuted into `bool` --> $DIR/bool.rs:21:35 | LL | assert::is_transmutable::<u8, bool>(); - | ^^^^ At least one value of `u8` isn't a bit-valid value of `bool` + | ^^^^ at least one value of `u8` isn't a bit-valid value of `bool` | note: required by a bound in `is_transmutable` --> $DIR/bool.rs:11:14 diff --git a/tests/ui/transmutability/primitives/bool.next.stderr b/tests/ui/transmutability/primitives/bool.next.stderr index 98e4a1029c907..da6a4a44e95e0 100644 --- a/tests/ui/transmutability/primitives/bool.next.stderr +++ b/tests/ui/transmutability/primitives/bool.next.stderr @@ -2,7 +2,7 @@ error[E0277]: `u8` cannot be safely transmuted into `bool` --> $DIR/bool.rs:21:35 | LL | assert::is_transmutable::<u8, bool>(); - | ^^^^ At least one value of `u8` isn't a bit-valid value of `bool` + | ^^^^ at least one value of `u8` isn't a bit-valid value of `bool` | note: required by a bound in `is_transmutable` --> $DIR/bool.rs:11:14 diff --git a/tests/ui/transmutability/primitives/numbers.current.stderr b/tests/ui/transmutability/primitives/numbers.current.stderr index 7a80e444149d4..0a9b9d182f856 100644 --- a/tests/ui/transmutability/primitives/numbers.current.stderr +++ b/tests/ui/transmutability/primitives/numbers.current.stderr @@ -2,7 +2,7 @@ error[E0277]: `i8` cannot be safely transmuted into `i16` --> $DIR/numbers.rs:64:40 | LL | assert::is_transmutable::< i8, i16>(); - | ^^^ The size of `i8` is smaller than the size of `i16` + | ^^^ the size of `i8` is smaller than the size of `i16` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -17,7 +17,7 @@ error[E0277]: `i8` cannot be safely transmuted into `u16` --> $DIR/numbers.rs:65:40 | LL | assert::is_transmutable::< i8, u16>(); - | ^^^ The size of `i8` is smaller than the size of `u16` + | ^^^ the size of `i8` is smaller than the size of `u16` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -32,7 +32,7 @@ error[E0277]: `i8` cannot be safely transmuted into `i32` --> $DIR/numbers.rs:66:40 | LL | assert::is_transmutable::< i8, i32>(); - | ^^^ The size of `i8` is smaller than the size of `i32` + | ^^^ the size of `i8` is smaller than the size of `i32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -47,7 +47,7 @@ error[E0277]: `i8` cannot be safely transmuted into `f32` --> $DIR/numbers.rs:67:40 | LL | assert::is_transmutable::< i8, f32>(); - | ^^^ The size of `i8` is smaller than the size of `f32` + | ^^^ the size of `i8` is smaller than the size of `f32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -62,7 +62,7 @@ error[E0277]: `i8` cannot be safely transmuted into `u32` --> $DIR/numbers.rs:68:40 | LL | assert::is_transmutable::< i8, u32>(); - | ^^^ The size of `i8` is smaller than the size of `u32` + | ^^^ the size of `i8` is smaller than the size of `u32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -77,7 +77,7 @@ error[E0277]: `i8` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:69:40 | LL | assert::is_transmutable::< i8, u64>(); - | ^^^ The size of `i8` is smaller than the size of `u64` + | ^^^ the size of `i8` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -92,7 +92,7 @@ error[E0277]: `i8` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:70:40 | LL | assert::is_transmutable::< i8, i64>(); - | ^^^ The size of `i8` is smaller than the size of `i64` + | ^^^ the size of `i8` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -107,7 +107,7 @@ error[E0277]: `i8` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:71:40 | LL | assert::is_transmutable::< i8, f64>(); - | ^^^ The size of `i8` is smaller than the size of `f64` + | ^^^ the size of `i8` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -122,7 +122,7 @@ error[E0277]: `i8` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:72:39 | LL | assert::is_transmutable::< i8, u128>(); - | ^^^^ The size of `i8` is smaller than the size of `u128` + | ^^^^ the size of `i8` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -137,7 +137,7 @@ error[E0277]: `i8` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:73:39 | LL | assert::is_transmutable::< i8, i128>(); - | ^^^^ The size of `i8` is smaller than the size of `i128` + | ^^^^ the size of `i8` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -152,7 +152,7 @@ error[E0277]: `u8` cannot be safely transmuted into `i16` --> $DIR/numbers.rs:75:40 | LL | assert::is_transmutable::< u8, i16>(); - | ^^^ The size of `u8` is smaller than the size of `i16` + | ^^^ the size of `u8` is smaller than the size of `i16` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -167,7 +167,7 @@ error[E0277]: `u8` cannot be safely transmuted into `u16` --> $DIR/numbers.rs:76:40 | LL | assert::is_transmutable::< u8, u16>(); - | ^^^ The size of `u8` is smaller than the size of `u16` + | ^^^ the size of `u8` is smaller than the size of `u16` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -182,7 +182,7 @@ error[E0277]: `u8` cannot be safely transmuted into `i32` --> $DIR/numbers.rs:77:40 | LL | assert::is_transmutable::< u8, i32>(); - | ^^^ The size of `u8` is smaller than the size of `i32` + | ^^^ the size of `u8` is smaller than the size of `i32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -197,7 +197,7 @@ error[E0277]: `u8` cannot be safely transmuted into `f32` --> $DIR/numbers.rs:78:40 | LL | assert::is_transmutable::< u8, f32>(); - | ^^^ The size of `u8` is smaller than the size of `f32` + | ^^^ the size of `u8` is smaller than the size of `f32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -212,7 +212,7 @@ error[E0277]: `u8` cannot be safely transmuted into `u32` --> $DIR/numbers.rs:79:40 | LL | assert::is_transmutable::< u8, u32>(); - | ^^^ The size of `u8` is smaller than the size of `u32` + | ^^^ the size of `u8` is smaller than the size of `u32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -227,7 +227,7 @@ error[E0277]: `u8` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:80:40 | LL | assert::is_transmutable::< u8, u64>(); - | ^^^ The size of `u8` is smaller than the size of `u64` + | ^^^ the size of `u8` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -242,7 +242,7 @@ error[E0277]: `u8` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:81:40 | LL | assert::is_transmutable::< u8, i64>(); - | ^^^ The size of `u8` is smaller than the size of `i64` + | ^^^ the size of `u8` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -257,7 +257,7 @@ error[E0277]: `u8` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:82:40 | LL | assert::is_transmutable::< u8, f64>(); - | ^^^ The size of `u8` is smaller than the size of `f64` + | ^^^ the size of `u8` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -272,7 +272,7 @@ error[E0277]: `u8` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:83:39 | LL | assert::is_transmutable::< u8, u128>(); - | ^^^^ The size of `u8` is smaller than the size of `u128` + | ^^^^ the size of `u8` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -287,7 +287,7 @@ error[E0277]: `u8` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:84:39 | LL | assert::is_transmutable::< u8, i128>(); - | ^^^^ The size of `u8` is smaller than the size of `i128` + | ^^^^ the size of `u8` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -302,7 +302,7 @@ error[E0277]: `i16` cannot be safely transmuted into `i32` --> $DIR/numbers.rs:86:40 | LL | assert::is_transmutable::< i16, i32>(); - | ^^^ The size of `i16` is smaller than the size of `i32` + | ^^^ the size of `i16` is smaller than the size of `i32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -317,7 +317,7 @@ error[E0277]: `i16` cannot be safely transmuted into `f32` --> $DIR/numbers.rs:87:40 | LL | assert::is_transmutable::< i16, f32>(); - | ^^^ The size of `i16` is smaller than the size of `f32` + | ^^^ the size of `i16` is smaller than the size of `f32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -332,7 +332,7 @@ error[E0277]: `i16` cannot be safely transmuted into `u32` --> $DIR/numbers.rs:88:40 | LL | assert::is_transmutable::< i16, u32>(); - | ^^^ The size of `i16` is smaller than the size of `u32` + | ^^^ the size of `i16` is smaller than the size of `u32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -347,7 +347,7 @@ error[E0277]: `i16` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:89:40 | LL | assert::is_transmutable::< i16, u64>(); - | ^^^ The size of `i16` is smaller than the size of `u64` + | ^^^ the size of `i16` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -362,7 +362,7 @@ error[E0277]: `i16` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:90:40 | LL | assert::is_transmutable::< i16, i64>(); - | ^^^ The size of `i16` is smaller than the size of `i64` + | ^^^ the size of `i16` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -377,7 +377,7 @@ error[E0277]: `i16` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:91:40 | LL | assert::is_transmutable::< i16, f64>(); - | ^^^ The size of `i16` is smaller than the size of `f64` + | ^^^ the size of `i16` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -392,7 +392,7 @@ error[E0277]: `i16` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:92:39 | LL | assert::is_transmutable::< i16, u128>(); - | ^^^^ The size of `i16` is smaller than the size of `u128` + | ^^^^ the size of `i16` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -407,7 +407,7 @@ error[E0277]: `i16` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:93:39 | LL | assert::is_transmutable::< i16, i128>(); - | ^^^^ The size of `i16` is smaller than the size of `i128` + | ^^^^ the size of `i16` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -422,7 +422,7 @@ error[E0277]: `u16` cannot be safely transmuted into `i32` --> $DIR/numbers.rs:95:40 | LL | assert::is_transmutable::< u16, i32>(); - | ^^^ The size of `u16` is smaller than the size of `i32` + | ^^^ the size of `u16` is smaller than the size of `i32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -437,7 +437,7 @@ error[E0277]: `u16` cannot be safely transmuted into `f32` --> $DIR/numbers.rs:96:40 | LL | assert::is_transmutable::< u16, f32>(); - | ^^^ The size of `u16` is smaller than the size of `f32` + | ^^^ the size of `u16` is smaller than the size of `f32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -452,7 +452,7 @@ error[E0277]: `u16` cannot be safely transmuted into `u32` --> $DIR/numbers.rs:97:40 | LL | assert::is_transmutable::< u16, u32>(); - | ^^^ The size of `u16` is smaller than the size of `u32` + | ^^^ the size of `u16` is smaller than the size of `u32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -467,7 +467,7 @@ error[E0277]: `u16` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:98:40 | LL | assert::is_transmutable::< u16, u64>(); - | ^^^ The size of `u16` is smaller than the size of `u64` + | ^^^ the size of `u16` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -482,7 +482,7 @@ error[E0277]: `u16` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:99:40 | LL | assert::is_transmutable::< u16, i64>(); - | ^^^ The size of `u16` is smaller than the size of `i64` + | ^^^ the size of `u16` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -497,7 +497,7 @@ error[E0277]: `u16` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:100:40 | LL | assert::is_transmutable::< u16, f64>(); - | ^^^ The size of `u16` is smaller than the size of `f64` + | ^^^ the size of `u16` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -512,7 +512,7 @@ error[E0277]: `u16` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:101:39 | LL | assert::is_transmutable::< u16, u128>(); - | ^^^^ The size of `u16` is smaller than the size of `u128` + | ^^^^ the size of `u16` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -527,7 +527,7 @@ error[E0277]: `u16` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:102:39 | LL | assert::is_transmutable::< u16, i128>(); - | ^^^^ The size of `u16` is smaller than the size of `i128` + | ^^^^ the size of `u16` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -542,7 +542,7 @@ error[E0277]: `i32` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:104:40 | LL | assert::is_transmutable::< i32, u64>(); - | ^^^ The size of `i32` is smaller than the size of `u64` + | ^^^ the size of `i32` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -557,7 +557,7 @@ error[E0277]: `i32` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:105:40 | LL | assert::is_transmutable::< i32, i64>(); - | ^^^ The size of `i32` is smaller than the size of `i64` + | ^^^ the size of `i32` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -572,7 +572,7 @@ error[E0277]: `i32` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:106:40 | LL | assert::is_transmutable::< i32, f64>(); - | ^^^ The size of `i32` is smaller than the size of `f64` + | ^^^ the size of `i32` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -587,7 +587,7 @@ error[E0277]: `i32` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:107:39 | LL | assert::is_transmutable::< i32, u128>(); - | ^^^^ The size of `i32` is smaller than the size of `u128` + | ^^^^ the size of `i32` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -602,7 +602,7 @@ error[E0277]: `i32` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:108:39 | LL | assert::is_transmutable::< i32, i128>(); - | ^^^^ The size of `i32` is smaller than the size of `i128` + | ^^^^ the size of `i32` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -617,7 +617,7 @@ error[E0277]: `f32` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:110:40 | LL | assert::is_transmutable::< f32, u64>(); - | ^^^ The size of `f32` is smaller than the size of `u64` + | ^^^ the size of `f32` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -632,7 +632,7 @@ error[E0277]: `f32` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:111:40 | LL | assert::is_transmutable::< f32, i64>(); - | ^^^ The size of `f32` is smaller than the size of `i64` + | ^^^ the size of `f32` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -647,7 +647,7 @@ error[E0277]: `f32` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:112:40 | LL | assert::is_transmutable::< f32, f64>(); - | ^^^ The size of `f32` is smaller than the size of `f64` + | ^^^ the size of `f32` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -662,7 +662,7 @@ error[E0277]: `f32` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:113:39 | LL | assert::is_transmutable::< f32, u128>(); - | ^^^^ The size of `f32` is smaller than the size of `u128` + | ^^^^ the size of `f32` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -677,7 +677,7 @@ error[E0277]: `f32` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:114:39 | LL | assert::is_transmutable::< f32, i128>(); - | ^^^^ The size of `f32` is smaller than the size of `i128` + | ^^^^ the size of `f32` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -692,7 +692,7 @@ error[E0277]: `u32` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:116:40 | LL | assert::is_transmutable::< u32, u64>(); - | ^^^ The size of `u32` is smaller than the size of `u64` + | ^^^ the size of `u32` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -707,7 +707,7 @@ error[E0277]: `u32` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:117:40 | LL | assert::is_transmutable::< u32, i64>(); - | ^^^ The size of `u32` is smaller than the size of `i64` + | ^^^ the size of `u32` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -722,7 +722,7 @@ error[E0277]: `u32` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:118:40 | LL | assert::is_transmutable::< u32, f64>(); - | ^^^ The size of `u32` is smaller than the size of `f64` + | ^^^ the size of `u32` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -737,7 +737,7 @@ error[E0277]: `u32` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:119:39 | LL | assert::is_transmutable::< u32, u128>(); - | ^^^^ The size of `u32` is smaller than the size of `u128` + | ^^^^ the size of `u32` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -752,7 +752,7 @@ error[E0277]: `u32` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:120:39 | LL | assert::is_transmutable::< u32, i128>(); - | ^^^^ The size of `u32` is smaller than the size of `i128` + | ^^^^ the size of `u32` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -767,7 +767,7 @@ error[E0277]: `u64` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:122:39 | LL | assert::is_transmutable::< u64, u128>(); - | ^^^^ The size of `u64` is smaller than the size of `u128` + | ^^^^ the size of `u64` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -782,7 +782,7 @@ error[E0277]: `u64` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:123:39 | LL | assert::is_transmutable::< u64, i128>(); - | ^^^^ The size of `u64` is smaller than the size of `i128` + | ^^^^ the size of `u64` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -797,7 +797,7 @@ error[E0277]: `i64` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:125:39 | LL | assert::is_transmutable::< i64, u128>(); - | ^^^^ The size of `i64` is smaller than the size of `u128` + | ^^^^ the size of `i64` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -812,7 +812,7 @@ error[E0277]: `i64` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:126:39 | LL | assert::is_transmutable::< i64, i128>(); - | ^^^^ The size of `i64` is smaller than the size of `i128` + | ^^^^ the size of `i64` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -827,7 +827,7 @@ error[E0277]: `f64` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:128:39 | LL | assert::is_transmutable::< f64, u128>(); - | ^^^^ The size of `f64` is smaller than the size of `u128` + | ^^^^ the size of `f64` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -842,7 +842,7 @@ error[E0277]: `f64` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:129:39 | LL | assert::is_transmutable::< f64, i128>(); - | ^^^^ The size of `f64` is smaller than the size of `i128` + | ^^^^ the size of `f64` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 diff --git a/tests/ui/transmutability/primitives/numbers.next.stderr b/tests/ui/transmutability/primitives/numbers.next.stderr index 7a80e444149d4..0a9b9d182f856 100644 --- a/tests/ui/transmutability/primitives/numbers.next.stderr +++ b/tests/ui/transmutability/primitives/numbers.next.stderr @@ -2,7 +2,7 @@ error[E0277]: `i8` cannot be safely transmuted into `i16` --> $DIR/numbers.rs:64:40 | LL | assert::is_transmutable::< i8, i16>(); - | ^^^ The size of `i8` is smaller than the size of `i16` + | ^^^ the size of `i8` is smaller than the size of `i16` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -17,7 +17,7 @@ error[E0277]: `i8` cannot be safely transmuted into `u16` --> $DIR/numbers.rs:65:40 | LL | assert::is_transmutable::< i8, u16>(); - | ^^^ The size of `i8` is smaller than the size of `u16` + | ^^^ the size of `i8` is smaller than the size of `u16` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -32,7 +32,7 @@ error[E0277]: `i8` cannot be safely transmuted into `i32` --> $DIR/numbers.rs:66:40 | LL | assert::is_transmutable::< i8, i32>(); - | ^^^ The size of `i8` is smaller than the size of `i32` + | ^^^ the size of `i8` is smaller than the size of `i32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -47,7 +47,7 @@ error[E0277]: `i8` cannot be safely transmuted into `f32` --> $DIR/numbers.rs:67:40 | LL | assert::is_transmutable::< i8, f32>(); - | ^^^ The size of `i8` is smaller than the size of `f32` + | ^^^ the size of `i8` is smaller than the size of `f32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -62,7 +62,7 @@ error[E0277]: `i8` cannot be safely transmuted into `u32` --> $DIR/numbers.rs:68:40 | LL | assert::is_transmutable::< i8, u32>(); - | ^^^ The size of `i8` is smaller than the size of `u32` + | ^^^ the size of `i8` is smaller than the size of `u32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -77,7 +77,7 @@ error[E0277]: `i8` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:69:40 | LL | assert::is_transmutable::< i8, u64>(); - | ^^^ The size of `i8` is smaller than the size of `u64` + | ^^^ the size of `i8` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -92,7 +92,7 @@ error[E0277]: `i8` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:70:40 | LL | assert::is_transmutable::< i8, i64>(); - | ^^^ The size of `i8` is smaller than the size of `i64` + | ^^^ the size of `i8` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -107,7 +107,7 @@ error[E0277]: `i8` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:71:40 | LL | assert::is_transmutable::< i8, f64>(); - | ^^^ The size of `i8` is smaller than the size of `f64` + | ^^^ the size of `i8` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -122,7 +122,7 @@ error[E0277]: `i8` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:72:39 | LL | assert::is_transmutable::< i8, u128>(); - | ^^^^ The size of `i8` is smaller than the size of `u128` + | ^^^^ the size of `i8` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -137,7 +137,7 @@ error[E0277]: `i8` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:73:39 | LL | assert::is_transmutable::< i8, i128>(); - | ^^^^ The size of `i8` is smaller than the size of `i128` + | ^^^^ the size of `i8` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -152,7 +152,7 @@ error[E0277]: `u8` cannot be safely transmuted into `i16` --> $DIR/numbers.rs:75:40 | LL | assert::is_transmutable::< u8, i16>(); - | ^^^ The size of `u8` is smaller than the size of `i16` + | ^^^ the size of `u8` is smaller than the size of `i16` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -167,7 +167,7 @@ error[E0277]: `u8` cannot be safely transmuted into `u16` --> $DIR/numbers.rs:76:40 | LL | assert::is_transmutable::< u8, u16>(); - | ^^^ The size of `u8` is smaller than the size of `u16` + | ^^^ the size of `u8` is smaller than the size of `u16` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -182,7 +182,7 @@ error[E0277]: `u8` cannot be safely transmuted into `i32` --> $DIR/numbers.rs:77:40 | LL | assert::is_transmutable::< u8, i32>(); - | ^^^ The size of `u8` is smaller than the size of `i32` + | ^^^ the size of `u8` is smaller than the size of `i32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -197,7 +197,7 @@ error[E0277]: `u8` cannot be safely transmuted into `f32` --> $DIR/numbers.rs:78:40 | LL | assert::is_transmutable::< u8, f32>(); - | ^^^ The size of `u8` is smaller than the size of `f32` + | ^^^ the size of `u8` is smaller than the size of `f32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -212,7 +212,7 @@ error[E0277]: `u8` cannot be safely transmuted into `u32` --> $DIR/numbers.rs:79:40 | LL | assert::is_transmutable::< u8, u32>(); - | ^^^ The size of `u8` is smaller than the size of `u32` + | ^^^ the size of `u8` is smaller than the size of `u32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -227,7 +227,7 @@ error[E0277]: `u8` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:80:40 | LL | assert::is_transmutable::< u8, u64>(); - | ^^^ The size of `u8` is smaller than the size of `u64` + | ^^^ the size of `u8` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -242,7 +242,7 @@ error[E0277]: `u8` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:81:40 | LL | assert::is_transmutable::< u8, i64>(); - | ^^^ The size of `u8` is smaller than the size of `i64` + | ^^^ the size of `u8` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -257,7 +257,7 @@ error[E0277]: `u8` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:82:40 | LL | assert::is_transmutable::< u8, f64>(); - | ^^^ The size of `u8` is smaller than the size of `f64` + | ^^^ the size of `u8` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -272,7 +272,7 @@ error[E0277]: `u8` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:83:39 | LL | assert::is_transmutable::< u8, u128>(); - | ^^^^ The size of `u8` is smaller than the size of `u128` + | ^^^^ the size of `u8` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -287,7 +287,7 @@ error[E0277]: `u8` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:84:39 | LL | assert::is_transmutable::< u8, i128>(); - | ^^^^ The size of `u8` is smaller than the size of `i128` + | ^^^^ the size of `u8` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -302,7 +302,7 @@ error[E0277]: `i16` cannot be safely transmuted into `i32` --> $DIR/numbers.rs:86:40 | LL | assert::is_transmutable::< i16, i32>(); - | ^^^ The size of `i16` is smaller than the size of `i32` + | ^^^ the size of `i16` is smaller than the size of `i32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -317,7 +317,7 @@ error[E0277]: `i16` cannot be safely transmuted into `f32` --> $DIR/numbers.rs:87:40 | LL | assert::is_transmutable::< i16, f32>(); - | ^^^ The size of `i16` is smaller than the size of `f32` + | ^^^ the size of `i16` is smaller than the size of `f32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -332,7 +332,7 @@ error[E0277]: `i16` cannot be safely transmuted into `u32` --> $DIR/numbers.rs:88:40 | LL | assert::is_transmutable::< i16, u32>(); - | ^^^ The size of `i16` is smaller than the size of `u32` + | ^^^ the size of `i16` is smaller than the size of `u32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -347,7 +347,7 @@ error[E0277]: `i16` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:89:40 | LL | assert::is_transmutable::< i16, u64>(); - | ^^^ The size of `i16` is smaller than the size of `u64` + | ^^^ the size of `i16` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -362,7 +362,7 @@ error[E0277]: `i16` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:90:40 | LL | assert::is_transmutable::< i16, i64>(); - | ^^^ The size of `i16` is smaller than the size of `i64` + | ^^^ the size of `i16` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -377,7 +377,7 @@ error[E0277]: `i16` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:91:40 | LL | assert::is_transmutable::< i16, f64>(); - | ^^^ The size of `i16` is smaller than the size of `f64` + | ^^^ the size of `i16` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -392,7 +392,7 @@ error[E0277]: `i16` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:92:39 | LL | assert::is_transmutable::< i16, u128>(); - | ^^^^ The size of `i16` is smaller than the size of `u128` + | ^^^^ the size of `i16` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -407,7 +407,7 @@ error[E0277]: `i16` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:93:39 | LL | assert::is_transmutable::< i16, i128>(); - | ^^^^ The size of `i16` is smaller than the size of `i128` + | ^^^^ the size of `i16` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -422,7 +422,7 @@ error[E0277]: `u16` cannot be safely transmuted into `i32` --> $DIR/numbers.rs:95:40 | LL | assert::is_transmutable::< u16, i32>(); - | ^^^ The size of `u16` is smaller than the size of `i32` + | ^^^ the size of `u16` is smaller than the size of `i32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -437,7 +437,7 @@ error[E0277]: `u16` cannot be safely transmuted into `f32` --> $DIR/numbers.rs:96:40 | LL | assert::is_transmutable::< u16, f32>(); - | ^^^ The size of `u16` is smaller than the size of `f32` + | ^^^ the size of `u16` is smaller than the size of `f32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -452,7 +452,7 @@ error[E0277]: `u16` cannot be safely transmuted into `u32` --> $DIR/numbers.rs:97:40 | LL | assert::is_transmutable::< u16, u32>(); - | ^^^ The size of `u16` is smaller than the size of `u32` + | ^^^ the size of `u16` is smaller than the size of `u32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -467,7 +467,7 @@ error[E0277]: `u16` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:98:40 | LL | assert::is_transmutable::< u16, u64>(); - | ^^^ The size of `u16` is smaller than the size of `u64` + | ^^^ the size of `u16` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -482,7 +482,7 @@ error[E0277]: `u16` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:99:40 | LL | assert::is_transmutable::< u16, i64>(); - | ^^^ The size of `u16` is smaller than the size of `i64` + | ^^^ the size of `u16` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -497,7 +497,7 @@ error[E0277]: `u16` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:100:40 | LL | assert::is_transmutable::< u16, f64>(); - | ^^^ The size of `u16` is smaller than the size of `f64` + | ^^^ the size of `u16` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -512,7 +512,7 @@ error[E0277]: `u16` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:101:39 | LL | assert::is_transmutable::< u16, u128>(); - | ^^^^ The size of `u16` is smaller than the size of `u128` + | ^^^^ the size of `u16` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -527,7 +527,7 @@ error[E0277]: `u16` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:102:39 | LL | assert::is_transmutable::< u16, i128>(); - | ^^^^ The size of `u16` is smaller than the size of `i128` + | ^^^^ the size of `u16` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -542,7 +542,7 @@ error[E0277]: `i32` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:104:40 | LL | assert::is_transmutable::< i32, u64>(); - | ^^^ The size of `i32` is smaller than the size of `u64` + | ^^^ the size of `i32` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -557,7 +557,7 @@ error[E0277]: `i32` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:105:40 | LL | assert::is_transmutable::< i32, i64>(); - | ^^^ The size of `i32` is smaller than the size of `i64` + | ^^^ the size of `i32` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -572,7 +572,7 @@ error[E0277]: `i32` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:106:40 | LL | assert::is_transmutable::< i32, f64>(); - | ^^^ The size of `i32` is smaller than the size of `f64` + | ^^^ the size of `i32` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -587,7 +587,7 @@ error[E0277]: `i32` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:107:39 | LL | assert::is_transmutable::< i32, u128>(); - | ^^^^ The size of `i32` is smaller than the size of `u128` + | ^^^^ the size of `i32` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -602,7 +602,7 @@ error[E0277]: `i32` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:108:39 | LL | assert::is_transmutable::< i32, i128>(); - | ^^^^ The size of `i32` is smaller than the size of `i128` + | ^^^^ the size of `i32` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -617,7 +617,7 @@ error[E0277]: `f32` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:110:40 | LL | assert::is_transmutable::< f32, u64>(); - | ^^^ The size of `f32` is smaller than the size of `u64` + | ^^^ the size of `f32` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -632,7 +632,7 @@ error[E0277]: `f32` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:111:40 | LL | assert::is_transmutable::< f32, i64>(); - | ^^^ The size of `f32` is smaller than the size of `i64` + | ^^^ the size of `f32` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -647,7 +647,7 @@ error[E0277]: `f32` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:112:40 | LL | assert::is_transmutable::< f32, f64>(); - | ^^^ The size of `f32` is smaller than the size of `f64` + | ^^^ the size of `f32` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -662,7 +662,7 @@ error[E0277]: `f32` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:113:39 | LL | assert::is_transmutable::< f32, u128>(); - | ^^^^ The size of `f32` is smaller than the size of `u128` + | ^^^^ the size of `f32` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -677,7 +677,7 @@ error[E0277]: `f32` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:114:39 | LL | assert::is_transmutable::< f32, i128>(); - | ^^^^ The size of `f32` is smaller than the size of `i128` + | ^^^^ the size of `f32` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -692,7 +692,7 @@ error[E0277]: `u32` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:116:40 | LL | assert::is_transmutable::< u32, u64>(); - | ^^^ The size of `u32` is smaller than the size of `u64` + | ^^^ the size of `u32` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -707,7 +707,7 @@ error[E0277]: `u32` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:117:40 | LL | assert::is_transmutable::< u32, i64>(); - | ^^^ The size of `u32` is smaller than the size of `i64` + | ^^^ the size of `u32` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -722,7 +722,7 @@ error[E0277]: `u32` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:118:40 | LL | assert::is_transmutable::< u32, f64>(); - | ^^^ The size of `u32` is smaller than the size of `f64` + | ^^^ the size of `u32` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -737,7 +737,7 @@ error[E0277]: `u32` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:119:39 | LL | assert::is_transmutable::< u32, u128>(); - | ^^^^ The size of `u32` is smaller than the size of `u128` + | ^^^^ the size of `u32` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -752,7 +752,7 @@ error[E0277]: `u32` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:120:39 | LL | assert::is_transmutable::< u32, i128>(); - | ^^^^ The size of `u32` is smaller than the size of `i128` + | ^^^^ the size of `u32` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -767,7 +767,7 @@ error[E0277]: `u64` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:122:39 | LL | assert::is_transmutable::< u64, u128>(); - | ^^^^ The size of `u64` is smaller than the size of `u128` + | ^^^^ the size of `u64` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -782,7 +782,7 @@ error[E0277]: `u64` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:123:39 | LL | assert::is_transmutable::< u64, i128>(); - | ^^^^ The size of `u64` is smaller than the size of `i128` + | ^^^^ the size of `u64` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -797,7 +797,7 @@ error[E0277]: `i64` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:125:39 | LL | assert::is_transmutable::< i64, u128>(); - | ^^^^ The size of `i64` is smaller than the size of `u128` + | ^^^^ the size of `i64` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -812,7 +812,7 @@ error[E0277]: `i64` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:126:39 | LL | assert::is_transmutable::< i64, i128>(); - | ^^^^ The size of `i64` is smaller than the size of `i128` + | ^^^^ the size of `i64` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -827,7 +827,7 @@ error[E0277]: `f64` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:128:39 | LL | assert::is_transmutable::< f64, u128>(); - | ^^^^ The size of `f64` is smaller than the size of `u128` + | ^^^^ the size of `f64` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -842,7 +842,7 @@ error[E0277]: `f64` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:129:39 | LL | assert::is_transmutable::< f64, i128>(); - | ^^^^ The size of `f64` is smaller than the size of `i128` + | ^^^^ the size of `f64` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 diff --git a/tests/ui/transmutability/primitives/unit.current.stderr b/tests/ui/transmutability/primitives/unit.current.stderr index b2831dbf84255..52b708d680e83 100644 --- a/tests/ui/transmutability/primitives/unit.current.stderr +++ b/tests/ui/transmutability/primitives/unit.current.stderr @@ -2,7 +2,7 @@ error[E0277]: `()` cannot be safely transmuted into `u8` --> $DIR/unit.rs:31:35 | LL | assert::is_transmutable::<(), u8>(); - | ^^ The size of `()` is smaller than the size of `u8` + | ^^ the size of `()` is smaller than the size of `u8` | note: required by a bound in `is_transmutable` --> $DIR/unit.rs:16:14 diff --git a/tests/ui/transmutability/primitives/unit.next.stderr b/tests/ui/transmutability/primitives/unit.next.stderr index b2831dbf84255..52b708d680e83 100644 --- a/tests/ui/transmutability/primitives/unit.next.stderr +++ b/tests/ui/transmutability/primitives/unit.next.stderr @@ -2,7 +2,7 @@ error[E0277]: `()` cannot be safely transmuted into `u8` --> $DIR/unit.rs:31:35 | LL | assert::is_transmutable::<(), u8>(); - | ^^ The size of `()` is smaller than the size of `u8` + | ^^ the size of `()` is smaller than the size of `u8` | note: required by a bound in `is_transmutable` --> $DIR/unit.rs:16:14 diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr b/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr index 305fca30939ca..2b7cab1660d11 100644 --- a/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr +++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr @@ -2,7 +2,7 @@ error[E0277]: `B` cannot be safely transmuted into `A` --> $DIR/recursive-wrapper-types-bit-incompatible.rs:23:49 | LL | assert::is_maybe_transmutable::<&'static B, &'static A>(); - | ^^^^^^^^^^ At least one value of `B` isn't a bit-valid value of `A` + | ^^^^^^^^^^ at least one value of `B` isn't a bit-valid value of `A` | note: required by a bound in `is_maybe_transmutable` --> $DIR/recursive-wrapper-types-bit-incompatible.rs:9:14 diff --git a/tests/ui/transmutability/references/reject_extension.stderr b/tests/ui/transmutability/references/reject_extension.stderr index e02ef89c4a03b..88dd0313e3c86 100644 --- a/tests/ui/transmutability/references/reject_extension.stderr +++ b/tests/ui/transmutability/references/reject_extension.stderr @@ -2,7 +2,7 @@ error[E0277]: `&Packed<Two>` cannot be safely transmuted into `&Packed<Four>` --> $DIR/reject_extension.rs:48:37 | LL | assert::is_transmutable::<&Src, &Dst>(); - | ^^^^ The referent size of `&Packed<Two>` (2 bytes) is smaller than that of `&Packed<Four>` (4 bytes) + | ^^^^ the referent size of `&Packed<Two>` (2 bytes) is smaller than that of `&Packed<Four>` (4 bytes) | note: required by a bound in `is_transmutable` --> $DIR/reject_extension.rs:13:14 diff --git a/tests/ui/transmutability/references/unit-to-u8.stderr b/tests/ui/transmutability/references/unit-to-u8.stderr index 7cb45e24e0a45..5d73dfdc8eb72 100644 --- a/tests/ui/transmutability/references/unit-to-u8.stderr +++ b/tests/ui/transmutability/references/unit-to-u8.stderr @@ -2,7 +2,7 @@ error[E0277]: `&Unit` cannot be safely transmuted into `&u8` --> $DIR/unit-to-u8.rs:22:52 | LL | assert::is_maybe_transmutable::<&'static Unit, &'static u8>(); - | ^^^^^^^^^^^ The referent size of `&Unit` (0 bytes) is smaller than that of `&u8` (1 bytes) + | ^^^^^^^^^^^ the referent size of `&Unit` (0 bytes) is smaller than that of `&u8` (1 bytes) | note: required by a bound in `is_maybe_transmutable` --> $DIR/unit-to-u8.rs:9:14 diff --git a/tests/ui/transmutability/region-infer.stderr b/tests/ui/transmutability/region-infer.stderr index 5497af2429e5e..03c46823838d7 100644 --- a/tests/ui/transmutability/region-infer.stderr +++ b/tests/ui/transmutability/region-infer.stderr @@ -2,7 +2,7 @@ error[E0277]: `()` cannot be safely transmuted into `W<'_>` --> $DIR/region-infer.rs:18:5 | LL | test(); - | ^^^^^^ The size of `()` is smaller than the size of `W<'_>` + | ^^^^^^ the size of `()` is smaller than the size of `W<'_>` | note: required by a bound in `test` --> $DIR/region-infer.rs:10:12 diff --git a/tests/ui/transmutability/transmute-padding-ice.stderr b/tests/ui/transmutability/transmute-padding-ice.stderr index c48a5cd80ce7f..4c121d463c602 100644 --- a/tests/ui/transmutability/transmute-padding-ice.stderr +++ b/tests/ui/transmutability/transmute-padding-ice.stderr @@ -2,7 +2,7 @@ error[E0277]: `B` cannot be safely transmuted into `A` --> $DIR/transmute-padding-ice.rs:25:40 | LL | assert::is_maybe_transmutable::<B, A>(); - | ^ The size of `B` is smaller than the size of `A` + | ^ the size of `B` is smaller than the size of `A` | note: required by a bound in `is_maybe_transmutable` --> $DIR/transmute-padding-ice.rs:10:14 diff --git a/tests/ui/transmutability/unions/should_pad_variants.stderr b/tests/ui/transmutability/unions/should_pad_variants.stderr index 13b4c8053adb2..da4294bdbce8c 100644 --- a/tests/ui/transmutability/unions/should_pad_variants.stderr +++ b/tests/ui/transmutability/unions/should_pad_variants.stderr @@ -2,7 +2,7 @@ error[E0277]: `Src` cannot be safely transmuted into `Dst` --> $DIR/should_pad_variants.rs:43:36 | LL | assert::is_transmutable::<Src, Dst>(); - | ^^^ The size of `Src` is smaller than the size of `Dst` + | ^^^ the size of `Src` is smaller than the size of `Dst` | note: required by a bound in `is_transmutable` --> $DIR/should_pad_variants.rs:13:14 diff --git a/tests/ui/transmutability/unions/should_reject_contraction.stderr b/tests/ui/transmutability/unions/should_reject_contraction.stderr index a3e387a0f8469..20eaa3a6b095c 100644 --- a/tests/ui/transmutability/unions/should_reject_contraction.stderr +++ b/tests/ui/transmutability/unions/should_reject_contraction.stderr @@ -2,7 +2,7 @@ error[E0277]: `Superset` cannot be safely transmuted into `Subset` --> $DIR/should_reject_contraction.rs:34:41 | LL | assert::is_transmutable::<Superset, Subset>(); - | ^^^^^^ At least one value of `Superset` isn't a bit-valid value of `Subset` + | ^^^^^^ at least one value of `Superset` isn't a bit-valid value of `Subset` | note: required by a bound in `is_transmutable` --> $DIR/should_reject_contraction.rs:12:14 diff --git a/tests/ui/transmutability/unions/should_reject_disjoint.stderr b/tests/ui/transmutability/unions/should_reject_disjoint.stderr index 447ab6d9de7a3..ea47797c97056 100644 --- a/tests/ui/transmutability/unions/should_reject_disjoint.stderr +++ b/tests/ui/transmutability/unions/should_reject_disjoint.stderr @@ -2,7 +2,7 @@ error[E0277]: `A` cannot be safely transmuted into `B` --> $DIR/should_reject_disjoint.rs:32:40 | LL | assert::is_maybe_transmutable::<A, B>(); - | ^ At least one value of `A` isn't a bit-valid value of `B` + | ^ at least one value of `A` isn't a bit-valid value of `B` | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_reject_disjoint.rs:12:14 @@ -17,7 +17,7 @@ error[E0277]: `B` cannot be safely transmuted into `A` --> $DIR/should_reject_disjoint.rs:33:40 | LL | assert::is_maybe_transmutable::<B, A>(); - | ^ At least one value of `B` isn't a bit-valid value of `A` + | ^ at least one value of `B` isn't a bit-valid value of `A` | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_reject_disjoint.rs:12:14 diff --git a/tests/ui/transmutability/unions/should_reject_intersecting.stderr b/tests/ui/transmutability/unions/should_reject_intersecting.stderr index f0763bc8be782..79dec659d9db6 100644 --- a/tests/ui/transmutability/unions/should_reject_intersecting.stderr +++ b/tests/ui/transmutability/unions/should_reject_intersecting.stderr @@ -2,7 +2,7 @@ error[E0277]: `A` cannot be safely transmuted into `B` --> $DIR/should_reject_intersecting.rs:35:34 | LL | assert::is_transmutable::<A, B>(); - | ^ At least one value of `A` isn't a bit-valid value of `B` + | ^ at least one value of `A` isn't a bit-valid value of `B` | note: required by a bound in `is_transmutable` --> $DIR/should_reject_intersecting.rs:13:14 @@ -17,7 +17,7 @@ error[E0277]: `B` cannot be safely transmuted into `A` --> $DIR/should_reject_intersecting.rs:36:34 | LL | assert::is_transmutable::<B, A>(); - | ^ At least one value of `B` isn't a bit-valid value of `A` + | ^ at least one value of `B` isn't a bit-valid value of `A` | note: required by a bound in `is_transmutable` --> $DIR/should_reject_intersecting.rs:13:14 From 07545959c5cf2557ed0a6045c2e85a9c8b4a080c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= <berykubik@gmail.com> Date: Fri, 15 Mar 2024 19:03:28 +0100 Subject: [PATCH 17/17] CI: cache PR CI Docker builds --- src/ci/docker/run.sh | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index bd5447ac835d9..740eb7504f87b 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -92,21 +92,38 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then # Print docker version docker --version - # On non-CI or PR jobs, we don't have permissions to write to the registry cache, so we should - # not use `docker login` nor caching. - if [[ "$CI" == "" ]] || [[ "$PR_CI_JOB" == "1" ]]; + REGISTRY=ghcr.io + # PR CI runs on rust-lang, but we want to use the cache from rust-lang-ci + REGISTRY_USERNAME=rust-lang-ci + # Tag used to push the final Docker image, so that it can be pulled by e.g. rustup + IMAGE_TAG=${REGISTRY}/${REGISTRY_USERNAME}/rust-ci:${cksum} + # Tag used to cache the Docker build + # It seems that it cannot be the same as $IMAGE_TAG, otherwise it overwrites the cache + CACHE_IMAGE_TAG=${REGISTRY}/${REGISTRY_USERNAME}/rust-ci-cache:${cksum} + + # On non-CI jobs, we don't do any caching. + if [[ "$CI" == "" ]]; then retry docker build --rm -t rust-ci -f "$dockerfile" "$context" - else - REGISTRY=ghcr.io - # Most probably rust-lang-ci, but in general the owner of the repository where CI runs - REGISTRY_USERNAME=${GITHUB_REPOSITORY_OWNER} - # Tag used to push the final Docker image, so that it can be pulled by e.g. rustup - IMAGE_TAG=${REGISTRY}/${REGISTRY_USERNAME}/rust-ci:${cksum} - # Tag used to cache the Docker build - # It seems that it cannot be the same as $IMAGE_TAG, otherwise it overwrites the cache - CACHE_IMAGE_TAG=${REGISTRY}/${REGISTRY_USERNAME}/rust-ci-cache:${cksum} + # On PR CI jobs, we don't have permissions to write to the registry cache, + # but we can still read from it. + elif [[ "$PR_CI_JOB" == "1" ]]; + then + # Enable a new Docker driver so that --cache-from works with a registry backend + docker buildx create --use --driver docker-container + # Build the image using registry caching backend + retry docker \ + buildx \ + build \ + --rm \ + -t rust-ci \ + -f "$dockerfile" \ + --cache-from type=registry,ref=${CACHE_IMAGE_TAG} \ + --output=type=docker \ + "$context" + # On auto/try builds, we can also write to the cache. + else # Log into the Docker registry, so that we can read/write cache and the final image echo ${DOCKER_TOKEN} | docker login ${REGISTRY} \ --username ${REGISTRY_USERNAME} \