mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Auto merge of #121003 - matthiaskrgr:rollup-u5wyztn, r=matthiaskrgr
Rollup of 10 pull requests Successful merges: - #120696 (Properly handle `async` block and `async fn` in `if` exprs without `else`) - #120751 (Provide more suggestions on invalid equality where bounds) - #120802 (Bail out of drop elaboration when encountering error types) - #120967 (docs: mention round-to-even in precision formatting) - #120973 (allow static_mut_ref in some tests that specifically test mutable statics) - #120974 (llvm-wrapper: adapt for LLVM API change: Add support for EXPORTAS name types) - #120986 (iterator.rs: remove "Basic usage" text) - #120987 (remove redundant logic) - #120988 (fix comment) - #120995 (PassWrapper: adapt for llvm/llvm-project@93cdd1b5cf) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
fd9bb7fdde
@ -1593,44 +1593,98 @@ fn deny_equality_constraints(
|
||||
}
|
||||
}
|
||||
}
|
||||
// Given `A: Foo, A::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
|
||||
if let TyKind::Path(None, full_path) = &predicate.lhs_ty.kind {
|
||||
if let [potential_param, potential_assoc] = &full_path.segments[..] {
|
||||
for param in &generics.params {
|
||||
if param.ident == potential_param.ident {
|
||||
for bound in ¶m.bounds {
|
||||
if let ast::GenericBound::Trait(trait_ref, TraitBoundModifiers::NONE) =
|
||||
bound
|
||||
|
||||
let mut suggest =
|
||||
|poly: &PolyTraitRef, potential_assoc: &PathSegment, predicate: &WhereEqPredicate| {
|
||||
if let [trait_segment] = &poly.trait_ref.path.segments[..] {
|
||||
let assoc = pprust::path_to_string(&ast::Path::from_ident(potential_assoc.ident));
|
||||
let ty = pprust::ty_to_string(&predicate.rhs_ty);
|
||||
let (args, span) = match &trait_segment.args {
|
||||
Some(args) => match args.deref() {
|
||||
ast::GenericArgs::AngleBracketed(args) => {
|
||||
let Some(arg) = args.args.last() else {
|
||||
return;
|
||||
};
|
||||
(format!(", {assoc} = {ty}"), arg.span().shrink_to_hi())
|
||||
}
|
||||
_ => return,
|
||||
},
|
||||
None => (format!("<{assoc} = {ty}>"), trait_segment.span().shrink_to_hi()),
|
||||
};
|
||||
let removal_span = if generics.where_clause.predicates.len() == 1 {
|
||||
// We're removing th eonly where bound left, remove the whole thing.
|
||||
generics.where_clause.span
|
||||
} else {
|
||||
let mut span = predicate.span;
|
||||
let mut prev: Option<Span> = None;
|
||||
let mut preds = generics.where_clause.predicates.iter().peekable();
|
||||
// Find the predicate that shouldn't have been in the where bound list.
|
||||
while let Some(pred) = preds.next() {
|
||||
if let WherePredicate::EqPredicate(pred) = pred
|
||||
&& pred.span == predicate.span
|
||||
{
|
||||
if let [trait_segment] = &trait_ref.trait_ref.path.segments[..] {
|
||||
let assoc = pprust::path_to_string(&ast::Path::from_ident(
|
||||
potential_assoc.ident,
|
||||
));
|
||||
let ty = pprust::ty_to_string(&predicate.rhs_ty);
|
||||
let (args, span) = match &trait_segment.args {
|
||||
Some(args) => match args.deref() {
|
||||
ast::GenericArgs::AngleBracketed(args) => {
|
||||
let Some(arg) = args.args.last() else {
|
||||
continue;
|
||||
};
|
||||
(format!(", {assoc} = {ty}"), arg.span().shrink_to_hi())
|
||||
}
|
||||
_ => continue,
|
||||
},
|
||||
None => (
|
||||
format!("<{assoc} = {ty}>"),
|
||||
trait_segment.span().shrink_to_hi(),
|
||||
),
|
||||
};
|
||||
err.assoc2 = Some(errors::AssociatedSuggestion2 {
|
||||
span,
|
||||
args,
|
||||
predicate: predicate.span,
|
||||
trait_segment: trait_segment.ident,
|
||||
potential_assoc: potential_assoc.ident,
|
||||
});
|
||||
if let Some(next) = preds.peek() {
|
||||
// This is the first predicate, remove the trailing comma as well.
|
||||
span = span.with_hi(next.span().lo());
|
||||
} else if let Some(prev) = prev {
|
||||
// Remove the previous comma as well.
|
||||
span = span.with_lo(prev.hi());
|
||||
}
|
||||
}
|
||||
prev = Some(pred.span());
|
||||
}
|
||||
span
|
||||
};
|
||||
err.assoc2 = Some(errors::AssociatedSuggestion2 {
|
||||
span,
|
||||
args,
|
||||
predicate: removal_span,
|
||||
trait_segment: trait_segment.ident,
|
||||
potential_assoc: potential_assoc.ident,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if let TyKind::Path(None, full_path) = &predicate.lhs_ty.kind {
|
||||
// Given `A: Foo, Foo::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
|
||||
for bounds in generics.params.iter().map(|p| &p.bounds).chain(
|
||||
generics.where_clause.predicates.iter().filter_map(|pred| match pred {
|
||||
WherePredicate::BoundPredicate(p) => Some(&p.bounds),
|
||||
_ => None,
|
||||
}),
|
||||
) {
|
||||
for bound in bounds {
|
||||
if let GenericBound::Trait(poly, TraitBoundModifiers::NONE) = bound {
|
||||
if full_path.segments[..full_path.segments.len() - 1]
|
||||
.iter()
|
||||
.map(|segment| segment.ident.name)
|
||||
.zip(poly.trait_ref.path.segments.iter().map(|segment| segment.ident.name))
|
||||
.all(|(a, b)| a == b)
|
||||
&& let Some(potential_assoc) = full_path.segments.iter().last()
|
||||
{
|
||||
suggest(poly, potential_assoc, predicate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Given `A: Foo, A::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
|
||||
if let [potential_param, potential_assoc] = &full_path.segments[..] {
|
||||
for (ident, bounds) in generics.params.iter().map(|p| (p.ident, &p.bounds)).chain(
|
||||
generics.where_clause.predicates.iter().filter_map(|pred| match pred {
|
||||
WherePredicate::BoundPredicate(p)
|
||||
if let ast::TyKind::Path(None, path) = &p.bounded_ty.kind
|
||||
&& let [segment] = &path.segments[..] =>
|
||||
{
|
||||
Some((segment.ident, &p.bounds))
|
||||
}
|
||||
_ => None,
|
||||
}),
|
||||
) {
|
||||
if ident == potential_param.ident {
|
||||
for bound in bounds {
|
||||
if let ast::GenericBound::Trait(poly, TraitBoundModifiers::NONE) = bound {
|
||||
suggest(poly, potential_assoc, predicate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -98,8 +98,11 @@ struct CollectRetsVisitor<'tcx> {
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for CollectRetsVisitor<'tcx> {
|
||||
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
|
||||
if let hir::ExprKind::Ret(_) = expr.kind {
|
||||
self.ret_exprs.push(expr);
|
||||
match expr.kind {
|
||||
hir::ExprKind::Ret(_) => self.ret_exprs.push(expr),
|
||||
// `return` in closures does not return from the outer function
|
||||
hir::ExprKind::Closure(_) => return,
|
||||
_ => {}
|
||||
}
|
||||
intravisit::walk_expr(self, expr);
|
||||
}
|
||||
@ -1845,13 +1848,31 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||
}
|
||||
|
||||
let parent_id = fcx.tcx.hir().get_parent_item(id);
|
||||
let parent_item = fcx.tcx.hir_node_by_def_id(parent_id.def_id);
|
||||
let mut parent_item = fcx.tcx.hir_node_by_def_id(parent_id.def_id);
|
||||
// When suggesting return, we need to account for closures and async blocks, not just items.
|
||||
for (_, node) in fcx.tcx.hir().parent_iter(id) {
|
||||
match node {
|
||||
hir::Node::Expr(&hir::Expr {
|
||||
kind: hir::ExprKind::Closure(hir::Closure { .. }),
|
||||
..
|
||||
}) => {
|
||||
parent_item = node;
|
||||
break;
|
||||
}
|
||||
hir::Node::Item(_) | hir::Node::TraitItem(_) | hir::Node::ImplItem(_) => break,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
if let (Some(expr), Some(_), Some((fn_id, fn_decl, _, _))) =
|
||||
(expression, blk_id, fcx.get_node_fn_decl(parent_item))
|
||||
{
|
||||
if let (Some(expr), Some(_), Some(fn_decl)) = (expression, blk_id, parent_item.fn_decl()) {
|
||||
fcx.suggest_missing_break_or_return_expr(
|
||||
&mut err, expr, fn_decl, expected, found, id, fn_id,
|
||||
&mut err,
|
||||
expr,
|
||||
fn_decl,
|
||||
expected,
|
||||
found,
|
||||
id,
|
||||
parent_id.into(),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -963,14 +963,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
owner_id,
|
||||
..
|
||||
}) => Some((hir::HirId::make_owner(owner_id.def_id), &sig.decl, ident, false)),
|
||||
Node::Expr(&hir::Expr { hir_id, kind: hir::ExprKind::Closure(..), .. })
|
||||
if let Node::Item(&hir::Item {
|
||||
ident,
|
||||
kind: hir::ItemKind::Fn(ref sig, ..),
|
||||
owner_id,
|
||||
..
|
||||
}) = self.tcx.parent_hir_node(hir_id) =>
|
||||
{
|
||||
Node::Expr(&hir::Expr {
|
||||
hir_id,
|
||||
kind:
|
||||
hir::ExprKind::Closure(hir::Closure {
|
||||
kind: hir::ClosureKind::Coroutine(..), ..
|
||||
}),
|
||||
..
|
||||
}) => {
|
||||
let (ident, sig, owner_id) = match self.tcx.parent_hir_node(hir_id) {
|
||||
Node::Item(&hir::Item {
|
||||
ident,
|
||||
kind: hir::ItemKind::Fn(ref sig, ..),
|
||||
owner_id,
|
||||
..
|
||||
}) => (ident, sig, owner_id),
|
||||
Node::TraitItem(&hir::TraitItem {
|
||||
ident,
|
||||
kind: hir::TraitItemKind::Fn(ref sig, ..),
|
||||
owner_id,
|
||||
..
|
||||
}) => (ident, sig, owner_id),
|
||||
Node::ImplItem(&hir::ImplItem {
|
||||
ident,
|
||||
kind: hir::ImplItemKind::Fn(ref sig, ..),
|
||||
owner_id,
|
||||
..
|
||||
}) => (ident, sig, owner_id),
|
||||
_ => return None,
|
||||
};
|
||||
Some((
|
||||
hir::HirId::make_owner(owner_id.def_id),
|
||||
&sig.decl,
|
||||
|
@ -1726,7 +1726,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
/// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
|
||||
fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> {
|
||||
pub(crate) fn get_parent_fn_decl(
|
||||
&self,
|
||||
blk_id: hir::HirId,
|
||||
) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> {
|
||||
let parent = self.tcx.hir_node_by_def_id(self.tcx.hir().get_parent_item(blk_id).def_id);
|
||||
self.get_node_fn_decl(parent).map(|(_, fn_decl, ident, _)| (fn_decl, ident))
|
||||
}
|
||||
|
@ -827,6 +827,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
hir::FnRetTy::Return(hir_ty) => {
|
||||
if let hir::TyKind::OpaqueDef(item_id, ..) = hir_ty.kind
|
||||
// FIXME: account for RPITIT.
|
||||
&& let hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::OpaqueTy(op_ty), ..
|
||||
}) = self.tcx.hir_node(item_id.hir_id())
|
||||
@ -1038,33 +1039,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
return;
|
||||
}
|
||||
|
||||
if let hir::FnRetTy::Return(ty) = fn_decl.output {
|
||||
let ty = self.astconv().ast_ty_to_ty(ty);
|
||||
let bound_vars = self.tcx.late_bound_vars(fn_id);
|
||||
let ty = self
|
||||
.tcx
|
||||
.instantiate_bound_regions_with_erased(Binder::bind_with_vars(ty, bound_vars));
|
||||
let ty = match self.tcx.asyncness(fn_id.owner) {
|
||||
ty::Asyncness::Yes => self.get_impl_future_output_ty(ty).unwrap_or_else(|| {
|
||||
span_bug!(fn_decl.output.span(), "failed to get output type of async function")
|
||||
}),
|
||||
ty::Asyncness::No => ty,
|
||||
};
|
||||
let ty = self.normalize(expr.span, ty);
|
||||
if self.can_coerce(found, ty) {
|
||||
if let Some(owner_node) = self.tcx.hir_node(fn_id).as_owner()
|
||||
&& let Some(span) = expr.span.find_ancestor_inside(*owner_node.span())
|
||||
{
|
||||
err.multipart_suggestion(
|
||||
"you might have meant to return this value",
|
||||
vec![
|
||||
(span.shrink_to_lo(), "return ".to_string()),
|
||||
(span.shrink_to_hi(), ";".to_string()),
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
let scope = self
|
||||
.tcx
|
||||
.hir()
|
||||
.parent_iter(id)
|
||||
.filter(|(_, node)| {
|
||||
matches!(
|
||||
node,
|
||||
Node::Expr(Expr { kind: ExprKind::Closure(..), .. })
|
||||
| Node::Item(_)
|
||||
| Node::TraitItem(_)
|
||||
| Node::ImplItem(_)
|
||||
)
|
||||
})
|
||||
.next();
|
||||
let in_closure =
|
||||
matches!(scope, Some((_, Node::Expr(Expr { kind: ExprKind::Closure(..), .. }))));
|
||||
|
||||
let can_return = match fn_decl.output {
|
||||
hir::FnRetTy::Return(ty) => {
|
||||
let ty = self.astconv().ast_ty_to_ty(ty);
|
||||
let bound_vars = self.tcx.late_bound_vars(fn_id);
|
||||
let ty = self
|
||||
.tcx
|
||||
.instantiate_bound_regions_with_erased(Binder::bind_with_vars(ty, bound_vars));
|
||||
let ty = match self.tcx.asyncness(fn_id.owner) {
|
||||
ty::Asyncness::Yes => self.get_impl_future_output_ty(ty).unwrap_or_else(|| {
|
||||
span_bug!(
|
||||
fn_decl.output.span(),
|
||||
"failed to get output type of async function"
|
||||
)
|
||||
}),
|
||||
ty::Asyncness::No => ty,
|
||||
};
|
||||
let ty = self.normalize(expr.span, ty);
|
||||
self.can_coerce(found, ty)
|
||||
}
|
||||
hir::FnRetTy::DefaultReturn(_) if in_closure => {
|
||||
self.ret_coercion.as_ref().map_or(false, |ret| {
|
||||
let ret_ty = ret.borrow().expected_ty();
|
||||
self.can_coerce(found, ret_ty)
|
||||
})
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
if can_return
|
||||
&& let Some(owner_node) = self.tcx.hir_node(fn_id).as_owner()
|
||||
&& let Some(span) = expr.span.find_ancestor_inside(*owner_node.span())
|
||||
{
|
||||
err.multipart_suggestion(
|
||||
"you might have meant to return this value",
|
||||
vec![
|
||||
(span.shrink_to_lo(), "return ".to_string()),
|
||||
(span.shrink_to_hi(), ";".to_string()),
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1073,12 +1073,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// for instance
|
||||
self.tcx.at(span).type_of(*def_id).instantiate_identity()
|
||||
!= rcvr_ty
|
||||
&& self
|
||||
.tcx
|
||||
.at(span)
|
||||
.type_of(*def_id)
|
||||
.instantiate_identity()
|
||||
!= rcvr_ty
|
||||
}
|
||||
(Mode::Path, false, _) => true,
|
||||
_ => false,
|
||||
@ -1092,7 +1086,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
inherent_impls_candidate.sort();
|
||||
inherent_impls_candidate.dedup();
|
||||
|
||||
// number of type to shows at most.
|
||||
// number of types to show at most
|
||||
let limit = if inherent_impls_candidate.len() == 5 { 5 } else { 4 };
|
||||
let type_candidates = inherent_impls_candidate
|
||||
.iter()
|
||||
|
@ -43,6 +43,9 @@
|
||||
#include "llvm/Transforms/Instrumentation.h"
|
||||
#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
|
||||
#include "llvm/Support/TimeProfiler.h"
|
||||
#if LLVM_VERSION_GE(19, 0)
|
||||
#include "llvm/Support/PGOOptions.h"
|
||||
#endif
|
||||
#include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
|
||||
#include "llvm/Transforms/Instrumentation/InstrProfiling.h"
|
||||
#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
|
||||
@ -749,6 +752,9 @@ LLVMRustOptimize(
|
||||
FS,
|
||||
#endif
|
||||
PGOOptions::IRInstr, PGOOptions::NoCSAction,
|
||||
#if LLVM_VERSION_GE(19, 0)
|
||||
PGOOptions::ColdFuncOpt::Default,
|
||||
#endif
|
||||
DebugInfoForProfiling);
|
||||
} else if (PGOUsePath) {
|
||||
assert(!PGOSampleUsePath);
|
||||
@ -758,6 +764,9 @@ LLVMRustOptimize(
|
||||
FS,
|
||||
#endif
|
||||
PGOOptions::IRUse, PGOOptions::NoCSAction,
|
||||
#if LLVM_VERSION_GE(19, 0)
|
||||
PGOOptions::ColdFuncOpt::Default,
|
||||
#endif
|
||||
DebugInfoForProfiling);
|
||||
} else if (PGOSampleUsePath) {
|
||||
PGOOpt = PGOOptions(PGOSampleUsePath, "", "",
|
||||
@ -766,6 +775,9 @@ LLVMRustOptimize(
|
||||
FS,
|
||||
#endif
|
||||
PGOOptions::SampleUse, PGOOptions::NoCSAction,
|
||||
#if LLVM_VERSION_GE(19, 0)
|
||||
PGOOptions::ColdFuncOpt::Default,
|
||||
#endif
|
||||
DebugInfoForProfiling);
|
||||
} else if (DebugInfoForProfiling) {
|
||||
PGOOpt = PGOOptions("", "", "",
|
||||
@ -774,6 +786,9 @@ LLVMRustOptimize(
|
||||
FS,
|
||||
#endif
|
||||
PGOOptions::NoAction, PGOOptions::NoCSAction,
|
||||
#if LLVM_VERSION_GE(19, 0)
|
||||
PGOOptions::ColdFuncOpt::Default,
|
||||
#endif
|
||||
DebugInfoForProfiling);
|
||||
}
|
||||
|
||||
|
@ -1801,6 +1801,9 @@ extern "C" LLVMRustResult LLVMRustWriteImportLibrary(
|
||||
std::string{}, // ExtName
|
||||
std::string{}, // SymbolName
|
||||
std::string{}, // AliasTarget
|
||||
#if LLVM_VERSION_GE(19, 0)
|
||||
std::string{}, // ExportAs
|
||||
#endif
|
||||
ordinal, // Ordinal
|
||||
ordinal_present, // Noname
|
||||
false, // Data
|
||||
|
@ -617,7 +617,7 @@ impl<'hir> Map<'hir> {
|
||||
Node::Item(_)
|
||||
| Node::ForeignItem(_)
|
||||
| Node::TraitItem(_)
|
||||
| Node::Expr(Expr { kind: ExprKind::Closure { .. }, .. })
|
||||
| Node::Expr(Expr { kind: ExprKind::Closure(_), .. })
|
||||
| Node::ImplItem(_)
|
||||
// The input node `id` must be enclosed in the method's body as opposed
|
||||
// to some other place such as its return type (fixes #114918).
|
||||
|
@ -1,7 +1,7 @@
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::mir::tcx::{PlaceTy, RvalueInitializationState};
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
|
||||
use std::mem;
|
||||
@ -132,6 +132,9 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
|
||||
let body = self.builder.body;
|
||||
let tcx = self.builder.tcx;
|
||||
let place_ty = place_ref.ty(body, tcx).ty;
|
||||
if place_ty.references_error() {
|
||||
return MovePathResult::Error;
|
||||
}
|
||||
match elem {
|
||||
ProjectionElem::Deref => match place_ty.kind() {
|
||||
ty::Ref(..) | ty::RawPtr(..) => {
|
||||
|
@ -900,7 +900,7 @@ impl<'a> Parser<'a> {
|
||||
// fn foo() -> Foo {
|
||||
// field: value,
|
||||
// }
|
||||
info!(?maybe_struct_name, ?self.token);
|
||||
debug!(?maybe_struct_name, ?self.token);
|
||||
let mut snapshot = self.create_snapshot_for_diagnostic();
|
||||
let path = Path {
|
||||
segments: ThinVec::new(),
|
||||
|
@ -278,6 +278,22 @@
|
||||
//! Hello, ` 123` has 3 right-aligned characters
|
||||
//! ```
|
||||
//!
|
||||
//! When truncating these values, Rust uses [round half-to-even](https://en.wikipedia.org/wiki/Rounding#Rounding_half_to_even),
|
||||
//! which is the default rounding mode in IEEE 754.
|
||||
//! For example,
|
||||
//!
|
||||
//! ```
|
||||
//! print!("{0:.1$e}", 12345, 3);
|
||||
//! print!("{0:.1$e}", 12355, 3);
|
||||
//! ```
|
||||
//!
|
||||
//! Would return:
|
||||
//!
|
||||
//! ```text
|
||||
//! 1.234e4
|
||||
//! 1.236e4
|
||||
//! ```
|
||||
//!
|
||||
//! ## Localization
|
||||
//!
|
||||
//! In some programming languages, the behavior of string formatting functions
|
||||
|
@ -89,8 +89,6 @@ pub trait Iterator {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let a = [1, 2, 3];
|
||||
///
|
||||
@ -249,8 +247,6 @@ pub trait Iterator {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let a = [1, 2, 3];
|
||||
/// assert_eq!(a.iter().count(), 3);
|
||||
@ -280,8 +276,6 @@ pub trait Iterator {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let a = [1, 2, 3];
|
||||
/// assert_eq!(a.iter().last(), Some(&3));
|
||||
@ -324,8 +318,6 @@ pub trait Iterator {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(iter_advance_by)]
|
||||
///
|
||||
@ -432,8 +424,6 @@ pub trait Iterator {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let a = [0, 1, 2, 3, 4, 5];
|
||||
/// let mut iter = a.iter().step_by(2);
|
||||
@ -1342,8 +1332,6 @@ pub trait Iterator {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let a = [1, 2, 3];
|
||||
///
|
||||
@ -1434,8 +1422,6 @@ pub trait Iterator {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let a = [1, 2, 3, 4];
|
||||
///
|
||||
@ -1486,8 +1472,6 @@ pub trait Iterator {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let words = ["alpha", "beta", "gamma"];
|
||||
///
|
||||
@ -1765,8 +1749,6 @@ pub trait Iterator {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// // an iterator which alternates between Some and None
|
||||
/// struct Alternate {
|
||||
@ -1911,8 +1893,6 @@ pub trait Iterator {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let mut words = ["hello", "world", "of", "Rust"].into_iter();
|
||||
///
|
||||
@ -2221,8 +2201,6 @@ pub trait Iterator {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let a = [1, 2, 3];
|
||||
///
|
||||
@ -3193,8 +3171,6 @@ pub trait Iterator {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let a = [1, 2, 3];
|
||||
/// let b: Vec<u32> = Vec::new();
|
||||
@ -3232,8 +3208,6 @@ pub trait Iterator {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let a = [1, 2, 3];
|
||||
/// let b: Vec<u32> = Vec::new();
|
||||
@ -3420,8 +3394,6 @@ pub trait Iterator {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let a = [(1, 2), (3, 4), (5, 6)];
|
||||
///
|
||||
@ -3458,8 +3430,6 @@ pub trait Iterator {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let a = [1, 2, 3];
|
||||
///
|
||||
@ -3538,8 +3508,6 @@ pub trait Iterator {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let a = [1, 2, 3];
|
||||
///
|
||||
@ -3624,8 +3592,6 @@ pub trait Iterator {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let a = [1, 2, 3];
|
||||
/// let sum: i32 = a.iter().sum();
|
||||
@ -3703,8 +3669,6 @@ pub trait Iterator {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(iter_order_by)]
|
||||
///
|
||||
@ -3790,8 +3754,6 @@ pub trait Iterator {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(iter_order_by)]
|
||||
///
|
||||
@ -3863,8 +3825,6 @@ pub trait Iterator {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(iter_order_by)]
|
||||
///
|
||||
|
22
tests/ui/async-await/missing-return-in-async-block.fixed
Normal file
22
tests/ui/async-await/missing-return-in-async-block.fixed
Normal file
@ -0,0 +1,22 @@
|
||||
// run-rustfix
|
||||
// edition:2021
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
pub struct S;
|
||||
pub fn foo() {
|
||||
let _ = Box::pin(async move {
|
||||
if true {
|
||||
return Ok(S); //~ ERROR mismatched types
|
||||
}
|
||||
Err(())
|
||||
});
|
||||
}
|
||||
pub fn bar() -> Pin<Box<dyn Future<Output = Result<S, ()>> + 'static>> {
|
||||
Box::pin(async move {
|
||||
if true {
|
||||
return Ok(S); //~ ERROR mismatched types
|
||||
}
|
||||
Err(())
|
||||
})
|
||||
}
|
||||
fn main() {}
|
22
tests/ui/async-await/missing-return-in-async-block.rs
Normal file
22
tests/ui/async-await/missing-return-in-async-block.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// run-rustfix
|
||||
// edition:2021
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
pub struct S;
|
||||
pub fn foo() {
|
||||
let _ = Box::pin(async move {
|
||||
if true {
|
||||
Ok(S) //~ ERROR mismatched types
|
||||
}
|
||||
Err(())
|
||||
});
|
||||
}
|
||||
pub fn bar() -> Pin<Box<dyn Future<Output = Result<S, ()>> + 'static>> {
|
||||
Box::pin(async move {
|
||||
if true {
|
||||
Ok(S) //~ ERROR mismatched types
|
||||
}
|
||||
Err(())
|
||||
})
|
||||
}
|
||||
fn main() {}
|
35
tests/ui/async-await/missing-return-in-async-block.stderr
Normal file
35
tests/ui/async-await/missing-return-in-async-block.stderr
Normal file
@ -0,0 +1,35 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/missing-return-in-async-block.rs:9:13
|
||||
|
|
||||
LL | / if true {
|
||||
LL | | Ok(S)
|
||||
| | ^^^^^ expected `()`, found `Result<S, _>`
|
||||
LL | | }
|
||||
| |_________- expected this to be `()`
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found enum `Result<S, _>`
|
||||
help: you might have meant to return this value
|
||||
|
|
||||
LL | return Ok(S);
|
||||
| ++++++ +
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/missing-return-in-async-block.rs:17:13
|
||||
|
|
||||
LL | / if true {
|
||||
LL | | Ok(S)
|
||||
| | ^^^^^ expected `()`, found `Result<S, _>`
|
||||
LL | | }
|
||||
| |_________- expected this to be `()`
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found enum `Result<S, _>`
|
||||
help: you might have meant to return this value
|
||||
|
|
||||
LL | return Ok(S);
|
||||
| ++++++ +
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -1,6 +1,7 @@
|
||||
// normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
|
||||
// normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP"
|
||||
#![feature(const_refs_to_static)]
|
||||
#![allow(static_mut_ref)]
|
||||
|
||||
fn invalid() {
|
||||
static S: i8 = 10;
|
||||
@ -38,7 +39,6 @@ fn mutable() {
|
||||
const C: &i32 = unsafe { &S_MUT };
|
||||
//~^ERROR: undefined behavior
|
||||
//~| encountered reference to mutable memory
|
||||
//~| WARN shared reference of mutable static is discouraged
|
||||
|
||||
// This *must not build*, the constant we are matching against
|
||||
// could change its value!
|
||||
|
@ -1,20 +1,5 @@
|
||||
warning: shared reference of mutable static is discouraged
|
||||
--> $DIR/const_refs_to_static_fail_invalid.rs:38:30
|
||||
|
|
||||
LL | const C: &i32 = unsafe { &S_MUT };
|
||||
| ^^^^^^ shared reference of mutable static
|
||||
|
|
||||
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
|
||||
= note: reference of mutable static is a hard error from 2024 edition
|
||||
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
|
||||
= note: `#[warn(static_mut_ref)]` on by default
|
||||
help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
|
||||
|
|
||||
LL | const C: &i32 = unsafe { addr_of!(S_MUT) };
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/const_refs_to_static_fail_invalid.rs:8:5
|
||||
--> $DIR/const_refs_to_static_fail_invalid.rs:9:5
|
||||
|
|
||||
LL | const C: &bool = unsafe { std::mem::transmute(&S) };
|
||||
| ^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered 0x0a, but expected a boolean
|
||||
@ -25,13 +10,13 @@ LL | const C: &bool = unsafe { std::mem::transmute(&S) };
|
||||
}
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/const_refs_to_static_fail_invalid.rs:14:9
|
||||
--> $DIR/const_refs_to_static_fail_invalid.rs:15:9
|
||||
|
|
||||
LL | C => {}
|
||||
| ^
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/const_refs_to_static_fail_invalid.rs:24:5
|
||||
--> $DIR/const_refs_to_static_fail_invalid.rs:25:5
|
||||
|
|
||||
LL | const C: &i8 = unsafe { &S };
|
||||
| ^^^^^^^^^^^^ constructing invalid value: encountered reference to `extern` static in `const`
|
||||
@ -42,13 +27,13 @@ LL | const C: &i8 = unsafe { &S };
|
||||
}
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/const_refs_to_static_fail_invalid.rs:30:9
|
||||
--> $DIR/const_refs_to_static_fail_invalid.rs:31:9
|
||||
|
|
||||
LL | C => {}
|
||||
| ^
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/const_refs_to_static_fail_invalid.rs:38:5
|
||||
--> $DIR/const_refs_to_static_fail_invalid.rs:39:5
|
||||
|
|
||||
LL | const C: &i32 = unsafe { &S_MUT };
|
||||
| ^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
|
||||
@ -64,6 +49,6 @@ error: could not evaluate constant pattern
|
||||
LL | C => {},
|
||||
| ^
|
||||
|
||||
error: aborting due to 6 previous errors; 1 warning emitted
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
||||
|
@ -1,9 +1,10 @@
|
||||
#![allow(static_mut_ref)]
|
||||
|
||||
const C1: &'static mut [usize] = &mut [];
|
||||
//~^ ERROR: mutable references are not allowed
|
||||
|
||||
static mut S: usize = 3;
|
||||
const C2: &'static mut usize = unsafe { &mut S };
|
||||
//~^ ERROR: referencing statics in constants
|
||||
//~| WARN mutable reference of mutable static is discouraged [static_mut_ref]
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,26 +1,11 @@
|
||||
warning: mutable reference of mutable static is discouraged
|
||||
--> $DIR/issue-17718-const-bad-values.rs:5:41
|
||||
|
|
||||
LL | const C2: &'static mut usize = unsafe { &mut S };
|
||||
| ^^^^^^ mutable reference of mutable static
|
||||
|
|
||||
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
|
||||
= note: reference of mutable static is a hard error from 2024 edition
|
||||
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
|
||||
= note: `#[warn(static_mut_ref)]` on by default
|
||||
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
||||
|
|
||||
LL | const C2: &'static mut usize = unsafe { addr_of_mut!(S) };
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error[E0764]: mutable references are not allowed in the final value of constants
|
||||
--> $DIR/issue-17718-const-bad-values.rs:1:34
|
||||
--> $DIR/issue-17718-const-bad-values.rs:3:34
|
||||
|
|
||||
LL | const C1: &'static mut [usize] = &mut [];
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0658]: referencing statics in constants is unstable
|
||||
--> $DIR/issue-17718-const-bad-values.rs:5:46
|
||||
--> $DIR/issue-17718-const-bad-values.rs:7:46
|
||||
|
|
||||
LL | const C2: &'static mut usize = unsafe { &mut S };
|
||||
| ^
|
||||
@ -31,7 +16,7 @@ LL | const C2: &'static mut usize = unsafe { &mut S };
|
||||
= note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.
|
||||
= help: to fix this, the value can be extracted to a `const` and then used.
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0658, E0764.
|
||||
For more information about an error, try `rustc --explain E0658`.
|
||||
|
@ -1,20 +1,5 @@
|
||||
warning: shared reference of mutable static is discouraged
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:12:14
|
||||
|
|
||||
LL | unsafe { &static_cross_crate::ZERO }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ shared reference of mutable static
|
||||
|
|
||||
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
|
||||
= note: reference of mutable static is a hard error from 2024 edition
|
||||
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
|
||||
= note: `#[warn(static_mut_ref)]` on by default
|
||||
help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
|
||||
|
|
||||
LL | unsafe { addr_of!(static_cross_crate::ZERO) }
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:10:1
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:11:1
|
||||
|
|
||||
LL | const SLICE_MUT: &[u8; 1] = {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
|
||||
@ -79,7 +64,7 @@ LL | U8_MUT3 => true,
|
||||
warning: skipping const checks
|
||||
|
|
||||
help: skipping check for `const_refs_to_static` feature
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:12:15
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:13:15
|
||||
|
|
||||
LL | unsafe { &static_cross_crate::ZERO }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -99,6 +84,6 @@ help: skipping check for `const_refs_to_static` feature
|
||||
LL | match static_cross_crate::OPT_ZERO {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 8 previous errors; 2 warnings emitted
|
||||
error: aborting due to 8 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
||||
|
@ -1,20 +1,5 @@
|
||||
warning: shared reference of mutable static is discouraged
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:12:14
|
||||
|
|
||||
LL | unsafe { &static_cross_crate::ZERO }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ shared reference of mutable static
|
||||
|
|
||||
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
|
||||
= note: reference of mutable static is a hard error from 2024 edition
|
||||
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
|
||||
= note: `#[warn(static_mut_ref)]` on by default
|
||||
help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
|
||||
|
|
||||
LL | unsafe { addr_of!(static_cross_crate::ZERO) }
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:10:1
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:11:1
|
||||
|
|
||||
LL | const SLICE_MUT: &[u8; 1] = {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
|
||||
@ -79,7 +64,7 @@ LL | U8_MUT3 => true,
|
||||
warning: skipping const checks
|
||||
|
|
||||
help: skipping check for `const_refs_to_static` feature
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:12:15
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:13:15
|
||||
|
|
||||
LL | unsafe { &static_cross_crate::ZERO }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -99,6 +84,6 @@ help: skipping check for `const_refs_to_static` feature
|
||||
LL | match static_cross_crate::OPT_ZERO {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 8 previous errors; 2 warnings emitted
|
||||
error: aborting due to 8 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
||||
|
@ -2,6 +2,7 @@
|
||||
// aux-build:static_cross_crate.rs
|
||||
// stderr-per-bitwidth
|
||||
#![feature(exclusive_range_pattern, half_open_range_patterns_in_slices)]
|
||||
#![allow(static_mut_ref)]
|
||||
|
||||
extern crate static_cross_crate;
|
||||
|
||||
@ -10,7 +11,6 @@ extern crate static_cross_crate;
|
||||
const SLICE_MUT: &[u8; 1] = { //~ ERROR undefined behavior
|
||||
//~| encountered reference to mutable memory
|
||||
unsafe { &static_cross_crate::ZERO }
|
||||
//~^ WARN shared reference of mutable static is discouraged [static_mut_ref]
|
||||
};
|
||||
|
||||
const U8_MUT: &u8 = { //~ ERROR undefined behavior
|
||||
|
@ -1,8 +1,8 @@
|
||||
// build-pass (FIXME(62277): could be check-pass?)
|
||||
#![allow(static_mut_ref)]
|
||||
|
||||
static mut STDERR_BUFFER_SPACE: [u8; 42] = [0u8; 42];
|
||||
|
||||
pub static mut STDERR_BUFFER: *mut [u8] = unsafe { &mut STDERR_BUFFER_SPACE };
|
||||
//~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,17 +0,0 @@
|
||||
warning: mutable reference of mutable static is discouraged
|
||||
--> $DIR/static_mut_containing_mut_ref.rs:5:52
|
||||
|
|
||||
LL | pub static mut STDERR_BUFFER: *mut [u8] = unsafe { &mut STDERR_BUFFER_SPACE };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ mutable reference of mutable static
|
||||
|
|
||||
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
|
||||
= note: reference of mutable static is a hard error from 2024 edition
|
||||
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
|
||||
= note: `#[warn(static_mut_ref)]` on by default
|
||||
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
||||
|
|
||||
LL | pub static mut STDERR_BUFFER: *mut [u8] = unsafe { addr_of_mut!(STDERR_BUFFER_SPACE) };
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
@ -1,24 +1,9 @@
|
||||
warning: mutable reference of mutable static is discouraged
|
||||
--> $DIR/static_mut_containing_mut_ref2.rs:8:6
|
||||
|
|
||||
LL | *(&mut STDERR_BUFFER_SPACE) = 42;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable reference of mutable static
|
||||
|
|
||||
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
|
||||
= note: reference of mutable static is a hard error from 2024 edition
|
||||
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
|
||||
= note: `#[warn(static_mut_ref)]` on by default
|
||||
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
||||
|
|
||||
LL | *addr_of_mut!(STDERR_BUFFER_SPACE) = 42;
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error[E0080]: could not evaluate static initializer
|
||||
--> $DIR/static_mut_containing_mut_ref2.rs:8:5
|
||||
|
|
||||
LL | *(&mut STDERR_BUFFER_SPACE) = 42;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ modifying a static's initial value from another static's initializer
|
||||
|
||||
error: aborting due to 1 previous error; 1 warning emitted
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
||||
|
@ -1,5 +1,5 @@
|
||||
// revisions: stock mut_refs
|
||||
|
||||
#![allow(static_mut_ref)]
|
||||
#![cfg_attr(mut_refs, feature(const_mut_refs))]
|
||||
|
||||
static mut STDERR_BUFFER_SPACE: u8 = 0;
|
||||
@ -8,8 +8,6 @@ pub static mut STDERR_BUFFER: () = unsafe {
|
||||
*(&mut STDERR_BUFFER_SPACE) = 42;
|
||||
//[mut_refs]~^ ERROR could not evaluate static initializer
|
||||
//[stock]~^^ ERROR mutation through a reference is not allowed in statics
|
||||
//[mut_refs]~^^^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
|
||||
//[stock]~^^^^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
|
||||
};
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,18 +1,3 @@
|
||||
warning: mutable reference of mutable static is discouraged
|
||||
--> $DIR/static_mut_containing_mut_ref2.rs:8:6
|
||||
|
|
||||
LL | *(&mut STDERR_BUFFER_SPACE) = 42;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable reference of mutable static
|
||||
|
|
||||
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
|
||||
= note: reference of mutable static is a hard error from 2024 edition
|
||||
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
|
||||
= note: `#[warn(static_mut_ref)]` on by default
|
||||
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
||||
|
|
||||
LL | *addr_of_mut!(STDERR_BUFFER_SPACE) = 42;
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error[E0658]: mutation through a reference is not allowed in statics
|
||||
--> $DIR/static_mut_containing_mut_ref2.rs:8:5
|
||||
|
|
||||
@ -23,6 +8,6 @@ LL | *(&mut STDERR_BUFFER_SPACE) = 42;
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error: aborting due to 1 previous error; 1 warning emitted
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
20
tests/ui/drop/drop_elaboration_with_errors.rs
Normal file
20
tests/ui/drop/drop_elaboration_with_errors.rs
Normal file
@ -0,0 +1,20 @@
|
||||
// can't use build-fail, because this also fails check-fail, but
|
||||
// the ICE from #120787 only reproduces on build-fail.
|
||||
// compile-flags: --emit=mir
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
struct Foo {
|
||||
field: String,
|
||||
}
|
||||
|
||||
type Tait = impl Sized;
|
||||
|
||||
fn ice_cold(beverage: Tait) {
|
||||
let Foo { field } = beverage;
|
||||
_ = field;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
Ok(()) //~ ERROR mismatched types
|
||||
}
|
14
tests/ui/drop/drop_elaboration_with_errors.stderr
Normal file
14
tests/ui/drop/drop_elaboration_with_errors.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/drop_elaboration_with_errors.rs:19:5
|
||||
|
|
||||
LL | fn main() {
|
||||
| - expected `()` because of default return type
|
||||
LL | Ok(())
|
||||
| ^^^^^^ expected `()`, found `Result<(), _>`
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found enum `Result<(), _>`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -12,4 +12,71 @@ fn sum3<J: Iterator>(i: J) -> i32 where I::Item = i32 {
|
||||
panic!()
|
||||
}
|
||||
|
||||
use std::iter::FromIterator;
|
||||
|
||||
struct X {}
|
||||
|
||||
impl FromIterator<bool> for X {
|
||||
fn from_iter<T>(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A,
|
||||
//~^ ERROR equality constraints are not yet supported in `where` clauses
|
||||
//~| ERROR cannot find type `A` in this scope
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
struct Y {}
|
||||
|
||||
impl FromIterator<bool> for Y {
|
||||
fn from_iter<T>(_: T) -> Self where T: IntoIterator, T::Item = A,
|
||||
//~^ ERROR equality constraints are not yet supported in `where` clauses
|
||||
//~| ERROR cannot find type `A` in this scope
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
struct Z {}
|
||||
|
||||
impl FromIterator<bool> for Z {
|
||||
fn from_iter<T: IntoIterator>(_: T) -> Self where IntoIterator::Item = A,
|
||||
//~^ ERROR equality constraints are not yet supported in `where` clauses
|
||||
//~| ERROR cannot find type `A` in this scope
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
struct K {}
|
||||
|
||||
impl FromIterator<bool> for K {
|
||||
fn from_iter<T: IntoIterator>(_: T) -> Self where T::Item = A,
|
||||
//~^ ERROR equality constraints are not yet supported in `where` clauses
|
||||
//~| ERROR cannot find type `A` in this scope
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
struct L {}
|
||||
|
||||
impl FromIterator<bool> for L {
|
||||
fn from_iter<T>(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator,
|
||||
//~^ ERROR equality constraints are not yet supported in `where` clauses
|
||||
//~| ERROR cannot find type `A` in this scope
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
struct M {}
|
||||
|
||||
impl FromIterator<bool> for M {
|
||||
fn from_iter<T>(_: T) -> Self where T::Item = A, T: IntoIterator,
|
||||
//~^ ERROR equality constraints are not yet supported in `where` clauses
|
||||
//~| ERROR cannot find type `A` in this scope
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
fn main() {}
|
||||
|
@ -8,7 +8,7 @@ LL | fn sum<I: Iterator<Item = ()>>(i: I) -> i32 where I::Item = i32 {
|
||||
help: if `Iterator::Item` is an associated type you're trying to set, use the associated type binding syntax
|
||||
|
|
||||
LL - fn sum<I: Iterator<Item = ()>>(i: I) -> i32 where I::Item = i32 {
|
||||
LL + fn sum<I: Iterator<Item = (), Item = i32>>(i: I) -> i32 where {
|
||||
LL + fn sum<I: Iterator<Item = (), Item = i32>>(i: I) -> i32 {
|
||||
|
|
||||
|
||||
error: equality constraints are not yet supported in `where` clauses
|
||||
@ -21,7 +21,7 @@ LL | fn sum2<I: Iterator>(i: I) -> i32 where I::Item = i32 {
|
||||
help: if `Iterator::Item` is an associated type you're trying to set, use the associated type binding syntax
|
||||
|
|
||||
LL - fn sum2<I: Iterator>(i: I) -> i32 where I::Item = i32 {
|
||||
LL + fn sum2<I: Iterator<Item = i32>>(i: I) -> i32 where {
|
||||
LL + fn sum2<I: Iterator<Item = i32>>(i: I) -> i32 {
|
||||
|
|
||||
|
||||
error: equality constraints are not yet supported in `where` clauses
|
||||
@ -32,6 +32,138 @@ LL | fn sum3<J: Iterator>(i: J) -> i32 where I::Item = i32 {
|
||||
|
|
||||
= note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
|
||||
|
||||
error: equality constraints are not yet supported in `where` clauses
|
||||
--> $DIR/equality-bound.rs:20:58
|
||||
|
|
||||
LL | fn from_iter<T>(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ not supported
|
||||
|
|
||||
= note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
|
||||
help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax
|
||||
|
|
||||
LL - fn from_iter<T>(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A,
|
||||
LL + fn from_iter<T>(_: T) -> Self where T: IntoIterator<Item = A>,
|
||||
|
|
||||
|
||||
error: equality constraints are not yet supported in `where` clauses
|
||||
--> $DIR/equality-bound.rs:31:58
|
||||
|
|
||||
LL | fn from_iter<T>(_: T) -> Self where T: IntoIterator, T::Item = A,
|
||||
| ^^^^^^^^^^^ not supported
|
||||
|
|
||||
= note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
|
||||
help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax
|
||||
|
|
||||
LL - fn from_iter<T>(_: T) -> Self where T: IntoIterator, T::Item = A,
|
||||
LL + fn from_iter<T>(_: T) -> Self where T: IntoIterator<Item = A>,
|
||||
|
|
||||
|
||||
error: equality constraints are not yet supported in `where` clauses
|
||||
--> $DIR/equality-bound.rs:42:55
|
||||
|
|
||||
LL | fn from_iter<T: IntoIterator>(_: T) -> Self where IntoIterator::Item = A,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ not supported
|
||||
|
|
||||
= note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
|
||||
help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax
|
||||
|
|
||||
LL - fn from_iter<T: IntoIterator>(_: T) -> Self where IntoIterator::Item = A,
|
||||
LL + fn from_iter<T: IntoIterator<Item = A>>(_: T) -> Self
|
||||
|
|
||||
|
||||
error: equality constraints are not yet supported in `where` clauses
|
||||
--> $DIR/equality-bound.rs:53:55
|
||||
|
|
||||
LL | fn from_iter<T: IntoIterator>(_: T) -> Self where T::Item = A,
|
||||
| ^^^^^^^^^^^ not supported
|
||||
|
|
||||
= note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
|
||||
help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax
|
||||
|
|
||||
LL - fn from_iter<T: IntoIterator>(_: T) -> Self where T::Item = A,
|
||||
LL + fn from_iter<T: IntoIterator<Item = A>>(_: T) -> Self
|
||||
|
|
||||
|
||||
error: equality constraints are not yet supported in `where` clauses
|
||||
--> $DIR/equality-bound.rs:64:41
|
||||
|
|
||||
LL | fn from_iter<T>(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ not supported
|
||||
|
|
||||
= note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
|
||||
help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax
|
||||
|
|
||||
LL - fn from_iter<T>(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator,
|
||||
LL + fn from_iter<T>(_: T) -> Self where T: IntoIterator<Item = A>,
|
||||
|
|
||||
|
||||
error: equality constraints are not yet supported in `where` clauses
|
||||
--> $DIR/equality-bound.rs:75:41
|
||||
|
|
||||
LL | fn from_iter<T>(_: T) -> Self where T::Item = A, T: IntoIterator,
|
||||
| ^^^^^^^^^^^ not supported
|
||||
|
|
||||
= note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
|
||||
help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax
|
||||
|
|
||||
LL - fn from_iter<T>(_: T) -> Self where T::Item = A, T: IntoIterator,
|
||||
LL + fn from_iter<T>(_: T) -> Self where T: IntoIterator<Item = A>,
|
||||
|
|
||||
|
||||
error[E0412]: cannot find type `A` in this scope
|
||||
--> $DIR/equality-bound.rs:20:79
|
||||
|
|
||||
LL | fn from_iter<T>(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A,
|
||||
| ^ help: a struct with a similar name exists: `K`
|
||||
...
|
||||
LL | struct K {}
|
||||
| -------- similarly named struct `K` defined here
|
||||
|
||||
error[E0412]: cannot find type `A` in this scope
|
||||
--> $DIR/equality-bound.rs:31:68
|
||||
|
|
||||
LL | fn from_iter<T>(_: T) -> Self where T: IntoIterator, T::Item = A,
|
||||
| ^ help: a struct with a similar name exists: `K`
|
||||
...
|
||||
LL | struct K {}
|
||||
| -------- similarly named struct `K` defined here
|
||||
|
||||
error[E0412]: cannot find type `A` in this scope
|
||||
--> $DIR/equality-bound.rs:42:76
|
||||
|
|
||||
LL | fn from_iter<T: IntoIterator>(_: T) -> Self where IntoIterator::Item = A,
|
||||
| ^ help: a struct with a similar name exists: `K`
|
||||
...
|
||||
LL | struct K {}
|
||||
| -------- similarly named struct `K` defined here
|
||||
|
||||
error[E0412]: cannot find type `A` in this scope
|
||||
--> $DIR/equality-bound.rs:53:65
|
||||
|
|
||||
LL | struct K {}
|
||||
| -------- similarly named struct `K` defined here
|
||||
...
|
||||
LL | fn from_iter<T: IntoIterator>(_: T) -> Self where T::Item = A,
|
||||
| ^ help: a struct with a similar name exists: `K`
|
||||
|
||||
error[E0412]: cannot find type `A` in this scope
|
||||
--> $DIR/equality-bound.rs:64:62
|
||||
|
|
||||
LL | struct K {}
|
||||
| -------- similarly named struct `K` defined here
|
||||
...
|
||||
LL | fn from_iter<T>(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator,
|
||||
| ^ help: a struct with a similar name exists: `K`
|
||||
|
||||
error[E0412]: cannot find type `A` in this scope
|
||||
--> $DIR/equality-bound.rs:75:51
|
||||
|
|
||||
LL | struct K {}
|
||||
| -------- similarly named struct `K` defined here
|
||||
...
|
||||
LL | fn from_iter<T>(_: T) -> Self where T::Item = A, T: IntoIterator,
|
||||
| ^ help: a struct with a similar name exists: `K`
|
||||
|
||||
error[E0433]: failed to resolve: use of undeclared type `I`
|
||||
--> $DIR/equality-bound.rs:9:41
|
||||
|
|
||||
@ -41,6 +173,7 @@ LL | fn sum3<J: Iterator>(i: J) -> i32 where I::Item = i32 {
|
||||
| use of undeclared type `I`
|
||||
| help: a type parameter with a similar name exists: `J`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 16 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0433`.
|
||||
Some errors have detailed explanations: E0412, E0433.
|
||||
For more information about an error, try `rustc --explain E0412`.
|
||||
|
@ -1,6 +1,8 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/default-body-type-err-2.rs:7:9
|
||||
|
|
||||
LL | async fn woopsie_async(&self) -> String {
|
||||
| ------ expected `String` because of return type
|
||||
LL | 42
|
||||
| ^^- help: try using a conversion method: `.to_string()`
|
||||
| |
|
||||
|
@ -8,6 +8,7 @@ fn closure() {
|
||||
if true {
|
||||
Err(1)
|
||||
//~^ ERROR mismatched types
|
||||
//~| HELP you might have meant to return this value
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -21,6 +22,7 @@ fn async_block() {
|
||||
if true {
|
||||
Err(1)
|
||||
//~^ ERROR mismatched types
|
||||
//~| HELP you might have meant to return this value
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -5,14 +5,37 @@ LL | / if true {
|
||||
LL | | Err(1)
|
||||
| | ^^^^^^ expected `()`, found `Result<_, {integer}>`
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_____________- expected this to be `()`
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found enum `Result<_, {integer}>`
|
||||
help: you might have meant to return this value
|
||||
|
|
||||
LL | return Err(1);
|
||||
| ++++++ +
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/dont-suggest-break-thru-item.rs:22:17
|
||||
--> $DIR/dont-suggest-break-thru-item.rs:23:17
|
||||
|
|
||||
LL | / if true {
|
||||
LL | | Err(1)
|
||||
| | ^^^^^^ expected `()`, found `Result<_, {integer}>`
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_____________- expected this to be `()`
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found enum `Result<_, {integer}>`
|
||||
help: you might have meant to return this value
|
||||
|
|
||||
LL | return Err(1);
|
||||
| ++++++ +
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/dont-suggest-break-thru-item.rs:37:17
|
||||
|
|
||||
LL | / if true {
|
||||
LL | | Err(1)
|
||||
@ -25,20 +48,7 @@ LL | | }
|
||||
found enum `Result<_, {integer}>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/dont-suggest-break-thru-item.rs:35:17
|
||||
|
|
||||
LL | / if true {
|
||||
LL | | Err(1)
|
||||
| | ^^^^^^ expected `()`, found `Result<_, {integer}>`
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_____________- expected this to be `()`
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found enum `Result<_, {integer}>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/dont-suggest-break-thru-item.rs:47:17
|
||||
--> $DIR/dont-suggest-break-thru-item.rs:49:17
|
||||
|
|
||||
LL | / if true {
|
||||
LL | | Err(1)
|
||||
|
@ -2,14 +2,14 @@
|
||||
|
||||
#![feature(thread_local)]
|
||||
#![feature(const_swap)]
|
||||
#![allow(static_mut_ref)]
|
||||
|
||||
#[thread_local]
|
||||
static mut STATIC_VAR_2: [u32; 8] = [4; 8];
|
||||
const fn g(x: &mut [u32; 8]) {
|
||||
//~^ ERROR mutable references are not allowed
|
||||
std::mem::swap(x, &mut STATIC_VAR_2)
|
||||
//~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
|
||||
//~^^ ERROR thread-local statics cannot be accessed
|
||||
//~^ ERROR thread-local statics cannot be accessed
|
||||
//~| ERROR mutable references are not allowed
|
||||
//~| ERROR use of mutable static is unsafe
|
||||
}
|
||||
|
@ -1,20 +1,5 @@
|
||||
warning: mutable reference of mutable static is discouraged
|
||||
--> $DIR/thread-local-static.rs:10:23
|
||||
|
|
||||
LL | std::mem::swap(x, &mut STATIC_VAR_2)
|
||||
| ^^^^^^^^^^^^^^^^^ mutable reference of mutable static
|
||||
|
|
||||
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
|
||||
= note: reference of mutable static is a hard error from 2024 edition
|
||||
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
|
||||
= note: `#[warn(static_mut_ref)]` on by default
|
||||
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
||||
|
|
||||
LL | std::mem::swap(x, addr_of_mut!(STATIC_VAR_2))
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error[E0133]: use of mutable static is unsafe and requires unsafe function or block
|
||||
--> $DIR/thread-local-static.rs:10:28
|
||||
--> $DIR/thread-local-static.rs:11:28
|
||||
|
|
||||
LL | std::mem::swap(x, &mut STATIC_VAR_2)
|
||||
| ^^^^^^^^^^^^ use of mutable static
|
||||
@ -22,7 +7,7 @@ LL | std::mem::swap(x, &mut STATIC_VAR_2)
|
||||
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
|
||||
|
||||
error[E0658]: mutable references are not allowed in constant functions
|
||||
--> $DIR/thread-local-static.rs:8:12
|
||||
--> $DIR/thread-local-static.rs:9:12
|
||||
|
|
||||
LL | const fn g(x: &mut [u32; 8]) {
|
||||
| ^
|
||||
@ -32,13 +17,13 @@ LL | const fn g(x: &mut [u32; 8]) {
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0625]: thread-local statics cannot be accessed at compile-time
|
||||
--> $DIR/thread-local-static.rs:10:28
|
||||
--> $DIR/thread-local-static.rs:11:28
|
||||
|
|
||||
LL | std::mem::swap(x, &mut STATIC_VAR_2)
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error[E0658]: mutable references are not allowed in constant functions
|
||||
--> $DIR/thread-local-static.rs:10:23
|
||||
--> $DIR/thread-local-static.rs:11:23
|
||||
|
|
||||
LL | std::mem::swap(x, &mut STATIC_VAR_2)
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
@ -47,7 +32,7 @@ LL | std::mem::swap(x, &mut STATIC_VAR_2)
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error: aborting due to 4 previous errors; 1 warning emitted
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0133, E0625, E0658.
|
||||
For more information about an error, try `rustc --explain E0133`.
|
||||
|
@ -1,59 +0,0 @@
|
||||
warning: mutable reference of mutable static is discouraged
|
||||
--> $DIR/thread-local-static.rs:12:23
|
||||
|
|
||||
LL | std::mem::swap(x, &mut STATIC_VAR_2)
|
||||
| ^^^^^^^^^^^^^^^^^ mutable reference of mutable static
|
||||
|
|
||||
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
|
||||
= note: reference of mutable static is a hard error from 2024 edition
|
||||
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
|
||||
= note: `#[warn(static_mut_ref)]` on by default
|
||||
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
||||
|
|
||||
LL | std::mem::swap(x, addr_of_mut!(STATIC_VAR_2))
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error[E0658]: mutable references are not allowed in constant functions
|
||||
--> $DIR/thread-local-static.rs:10:12
|
||||
|
|
||||
LL | const fn g(x: &mut [u32; 8]) {
|
||||
| ^
|
||||
|
|
||||
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0625]: thread-local statics cannot be accessed at compile-time
|
||||
--> $DIR/thread-local-static.rs:12:28
|
||||
|
|
||||
LL | std::mem::swap(x, &mut STATIC_VAR_2)
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error[E0013]: constant functions cannot refer to statics
|
||||
--> $DIR/thread-local-static.rs:12:28
|
||||
|
|
||||
LL | std::mem::swap(x, &mut STATIC_VAR_2)
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider extracting the value of the `static` to a `const`, and referring to that
|
||||
|
||||
error[E0658]: mutable references are not allowed in constant functions
|
||||
--> $DIR/thread-local-static.rs:12:23
|
||||
|
|
||||
LL | std::mem::swap(x, &mut STATIC_VAR_2)
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0133]: use of mutable static is unsafe and requires unsafe function or block
|
||||
--> $DIR/thread-local-static.rs:12:23
|
||||
|
|
||||
LL | std::mem::swap(x, &mut STATIC_VAR_2)
|
||||
| ^^^^^^^^^^^^^^^^^ use of mutable static
|
||||
|
|
||||
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
|
||||
|
||||
error: aborting due to 5 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0013, E0133, E0625, E0658.
|
||||
For more information about an error, try `rustc --explain E0013`.
|
Loading…
Reference in New Issue
Block a user