Merge from rustc

This commit is contained in:
The Miri Conjob Bot 2023-07-18 07:04:44 +00:00
commit 0c27c2e605
978 changed files with 22593 additions and 12886 deletions

View file

@ -513,16 +513,25 @@ checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b"
[[package]]
name = "clippy"
version = "0.1.72"
version = "0.1.73"
dependencies = [
"clippy_lints",
"clippy_utils",
"derive-new",
"filetime",
"futures",
"if_chain",
"itertools",
"parking_lot 0.12.1",
"quote",
"regex",
"rustc_tools_util",
"serde",
"syn 2.0.8",
"tempfile",
"termize",
"tester",
"tokio",
"toml 0.7.5",
"ui_test",
"walkdir",
@ -543,7 +552,7 @@ dependencies = [
[[package]]
name = "clippy_lints"
version = "0.1.72"
version = "0.1.73"
dependencies = [
"arrayvec",
"cargo_metadata",
@ -566,27 +575,9 @@ dependencies = [
"url",
]
[[package]]
name = "clippy_test_deps"
version = "0.1.0"
dependencies = [
"clippy_lints",
"clippy_utils",
"derive-new",
"futures",
"if_chain",
"itertools",
"parking_lot 0.12.1",
"quote",
"regex",
"serde",
"syn 2.0.8",
"tokio",
]
[[package]]
name = "clippy_utils"
version = "0.1.72"
version = "0.1.73"
dependencies = [
"arrayvec",
"if_chain",
@ -847,7 +838,7 @@ checksum = "a0afaad2b26fa326569eb264b1363e8ae3357618c43982b3f285f0774ce76b69"
[[package]]
name = "declare_clippy_lint"
version = "0.1.72"
version = "0.1.73"
dependencies = [
"itertools",
"quote",
@ -3665,6 +3656,7 @@ name = "rustc_hir_typeck"
version = "0.1.0"
dependencies = [
"rustc_ast",
"rustc_attr",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",

View file

@ -9,7 +9,6 @@ members = [
"src/tools/cargotest",
"src/tools/clippy",
"src/tools/clippy/clippy_dev",
"src/tools/clippy/clippy_test_deps",
"src/tools/compiletest",
"src/tools/error_index_generator",
"src/tools/linkchecker",

View file

@ -1217,3 +1217,20 @@ pub fn parse_alignment(node: &ast::LitKind) -> Result<u32, &'static str> {
Err("not an unsuffixed integer")
}
}
/// Read the content of a `rustc_confusables` attribute, and return the list of candidate names.
pub fn parse_confusables(attr: &Attribute) -> Option<Vec<Symbol>> {
let meta = attr.meta()?;
let MetaItem { kind: MetaItemKind::List(ref metas), .. } = meta else { return None };
let mut candidates = Vec::new();
for meta in metas {
let NestedMetaItem::Lit(meta_lit) = meta else {
return None;
};
candidates.push(meta_lit.symbol);
}
return Some(candidates);
}

View file

@ -1134,9 +1134,14 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef<'b>,
enum_def: &'b EnumDef,
type_ident: Ident,
selflike_args: ThinVec<P<Expr>>,
mut selflike_args: ThinVec<P<Expr>>,
nonselflike_args: &[P<Expr>],
) -> BlockOrExpr {
assert!(
!selflike_args.is_empty(),
"static methods must use `expand_static_enum_method_body`",
);
let span = trait_.span;
let variants = &enum_def.variants;
@ -1144,10 +1149,15 @@ impl<'a> MethodDef<'a> {
let unify_fieldless_variants =
self.fieldless_variants_strategy == FieldlessVariantsStrategy::Unify;
// There is no sensible code to be generated for *any* deriving on a
// zero-variant enum. So we just generate a failing expression.
// For zero-variant enum, this function body is unreachable. Generate
// `match *self {}`. This produces machine code identical to `unsafe {
// core::intrinsics::unreachable() }` while being safe and stable.
if variants.is_empty() {
return BlockOrExpr(ThinVec::new(), Some(deriving::call_unreachable(cx, span)));
selflike_args.truncate(1);
let match_arg = cx.expr_deref(span, selflike_args.pop().unwrap());
let match_arms = ThinVec::new();
let expr = cx.expr_match(span, match_arg, match_arms);
return BlockOrExpr(ThinVec::new(), Some(expr));
}
let prefixes = iter::once("__self".to_string())

View file

@ -44,20 +44,29 @@ pub fn inject(
// .rev() to preserve ordering above in combination with insert(0, ...)
for &name in names.iter().rev() {
let ident = if edition >= Edition2018 {
Ident::new(name, span)
} else {
Ident::new(name, call_site)
};
krate.items.insert(
0,
let ident_span = if edition >= Edition2018 { span } else { call_site };
let item = if name == sym::compiler_builtins {
// compiler_builtins is a private implementation detail. We only
// need to insert it into the crate graph for linking and should not
// expose any of its public API.
//
// FIXME(#113634) We should inject this during post-processing like
// we do for the panic runtime, profiler runtime, etc.
cx.item(
span,
ident,
Ident::new(kw::Underscore, ident_span),
thin_vec![],
ast::ItemKind::ExternCrate(Some(name)),
)
} else {
cx.item(
span,
Ident::new(name, ident_span),
thin_vec![cx.attr_word(sym::macro_use, span)],
ast::ItemKind::ExternCrate(None),
),
);
)
};
krate.items.insert(0, item);
}
// The crates have been injected, the assumption is that the first one is

View file

@ -5,7 +5,7 @@
//! [`codegen_static`]: crate::constant::codegen_static
use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_middle::mir::mono::{Linkage as RLinkage, MonoItem, Visibility};
use rustc_middle::mir::mono::{MonoItem, MonoItemData};
use crate::prelude::*;
@ -16,11 +16,11 @@ pub(crate) mod jit;
fn predefine_mono_items<'tcx>(
tcx: TyCtxt<'tcx>,
module: &mut dyn Module,
mono_items: &[(MonoItem<'tcx>, (RLinkage, Visibility))],
mono_items: &[(MonoItem<'tcx>, MonoItemData)],
) {
tcx.prof.generic_activity("predefine functions").run(|| {
let is_compiler_builtins = tcx.is_compiler_builtins(LOCAL_CRATE);
for &(mono_item, (linkage, visibility)) in mono_items {
for &(mono_item, data) in mono_items {
match mono_item {
MonoItem::Fn(instance) => {
let name = tcx.symbol_name(instance).name;
@ -29,8 +29,8 @@ fn predefine_mono_items<'tcx>(
get_function_sig(tcx, module.target_config().default_call_conv, instance);
let linkage = crate::linkage::get_clif_linkage(
mono_item,
linkage,
visibility,
data.linkage,
data.visibility,
is_compiler_builtins,
);
module.declare_function(name, linkage, &sig).unwrap();

View file

@ -159,8 +159,8 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol, supports_128bit_i
let cx = CodegenCx::new(&context, cgu, tcx, supports_128bit_integers);
let mono_items = cgu.items_in_deterministic_order(tcx);
for &(mono_item, (linkage, visibility)) in &mono_items {
mono_item.predefine::<Builder<'_, '_, '_>>(&cx, linkage, visibility);
for &(mono_item, data) in &mono_items {
mono_item.predefine::<Builder<'_, '_, '_>>(&cx, data.linkage, data.visibility);
}
// ... and now that we have everything pre-defined, fill out those definitions.

View file

@ -86,8 +86,8 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen
{
let cx = CodegenCx::new(tcx, cgu, &llvm_module);
let mono_items = cx.codegen_unit.items_in_deterministic_order(cx.tcx);
for &(mono_item, (linkage, visibility)) in &mono_items {
mono_item.predefine::<Builder<'_, '_, '_>>(&cx, linkage, visibility);
for &(mono_item, data) in &mono_items {
mono_item.predefine::<Builder<'_, '_, '_>>(&cx, data.linkage, data.visibility);
}
// ... and now that we have everything pre-defined, fill out those definitions.

View file

@ -1392,6 +1392,11 @@ fn print_native_static_libs(
let mut lib_args: Vec<_> = all_native_libs
.iter()
.filter(|l| relevant_lib(sess, l))
// Deduplication of successive repeated libraries, see rust-lang/rust#113209
//
// note: we don't use PartialEq/Eq because NativeLib transitively depends on local
// elements like spans, which we don't care about and would make the deduplication impossible
.dedup_by(|l1, l2| l1.name == l2.name && l1.kind == l2.kind && l1.verbatim == l2.verbatim)
.filter_map(|lib| {
let name = lib.name;
match lib.kind {

View file

@ -328,14 +328,14 @@ fn exported_symbols_provider_local(
let (_, cgus) = tcx.collect_and_partition_mono_items(());
for (mono_item, &(linkage, visibility)) in cgus.iter().flat_map(|cgu| cgu.items().iter()) {
if linkage != Linkage::External {
for (mono_item, data) in cgus.iter().flat_map(|cgu| cgu.items().iter()) {
if data.linkage != Linkage::External {
// We can only re-use things with external linkage, otherwise
// we'll get a linker error
continue;
}
if need_visibility && visibility == Visibility::Hidden {
if need_visibility && data.visibility == Visibility::Hidden {
// If we potentially share things from Rust dylibs, they must
// not be hidden
continue;

View file

@ -399,6 +399,9 @@ const_eval_unallowed_mutable_refs_raw =
const_eval_unallowed_op_in_const_context =
{$msg}
const_eval_unavailable_target_features_for_fn =
calling a function that requires unavailable target features: {$unavailable_feats}
const_eval_undefined_behavior =
it is undefined behavior to use this value

View file

@ -503,6 +503,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
}
// Check that all target features required by the callee (i.e., from
// the attribute `#[target_feature(enable = ...)]`) are enabled at
// compile time.
self.check_fn_target_features(instance)?;
if !callee_fn_abi.can_unwind {
// The callee cannot unwind, so force the `Unreachable` unwind handling.
unwind = mir::UnwindAction::Unreachable;
@ -786,6 +791,31 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
}
fn check_fn_target_features(&self, instance: ty::Instance<'tcx>) -> InterpResult<'tcx, ()> {
let attrs = self.tcx.codegen_fn_attrs(instance.def_id());
if attrs
.target_features
.iter()
.any(|feature| !self.tcx.sess.target_features.contains(feature))
{
throw_ub_custom!(
fluent::const_eval_unavailable_target_features_for_fn,
unavailable_feats = attrs
.target_features
.iter()
.filter(|&feature| !self.tcx.sess.target_features.contains(feature))
.fold(String::new(), |mut s, feature| {
if !s.is_empty() {
s.push_str(", ");
}
s.push_str(feature.as_str());
s
}),
);
}
Ok(())
}
fn drop_in_place(
&mut self,
place: &PlaceTy<'tcx, M::Provenance>,

View file

@ -625,6 +625,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
ErrorFollowing,
INTERNAL_UNSTABLE
),
rustc_attr!(
rustc_confusables, Normal,
template!(List: r#""name1", "name2", ..."#),
ErrorFollowing,
INTERNAL_UNSTABLE,
),
// Enumerates "identity-like" conversion methods to suggest on type mismatch.
rustc_attr!(
rustc_conversion_suggestion, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE

View file

@ -8,7 +8,7 @@ use rustc_attr as attr;
use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
use rustc_hir::intravisit::Visitor;
use rustc_hir::{ItemKind, Node, PathSegment};
use rustc_infer::infer::opaque_types::ConstrainOpaqueTypeRegionVisitor;
@ -1378,6 +1378,9 @@ pub(super) fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
for id in module.items() {
check_item_type(tcx, id);
}
if module_def_id == CRATE_DEF_ID {
super::entry::check_for_entry_fn(tcx);
}
}
fn async_opaque_type_cycle_error(tcx: TyCtxt<'_>, span: Span) -> ErrorGuaranteed {

View file

@ -0,0 +1,277 @@
use rustc_hir as hir;
use rustc_hir::Node;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_session::config::EntryFnType;
use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
use rustc_span::{symbol::sym, Span};
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode};
use std::ops::Not;
use crate::errors;
use crate::require_same_types;
pub(crate) fn check_for_entry_fn(tcx: TyCtxt<'_>) {
match tcx.entry_fn(()) {
Some((def_id, EntryFnType::Main { .. })) => check_main_fn_ty(tcx, def_id),
Some((def_id, EntryFnType::Start)) => check_start_fn_ty(tcx, def_id),
_ => {}
}
}
fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
let main_fnsig = tcx.fn_sig(main_def_id).instantiate_identity();
let main_span = tcx.def_span(main_def_id);
fn main_fn_diagnostics_def_id(tcx: TyCtxt<'_>, def_id: DefId, sp: Span) -> LocalDefId {
if let Some(local_def_id) = def_id.as_local() {
let hir_type = tcx.type_of(local_def_id).instantiate_identity();
if !matches!(hir_type.kind(), ty::FnDef(..)) {
span_bug!(sp, "main has a non-function type: found `{}`", hir_type);
}
local_def_id
} else {
CRATE_DEF_ID
}
}
fn main_fn_generics_params_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> {
if !def_id.is_local() {
return None;
}
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
match tcx.hir().find(hir_id) {
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => {
generics.params.is_empty().not().then_some(generics.span)
}
_ => {
span_bug!(tcx.def_span(def_id), "main has a non-function type");
}
}
}
fn main_fn_where_clauses_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> {
if !def_id.is_local() {
return None;
}
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
match tcx.hir().find(hir_id) {
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => {
Some(generics.where_clause_span)
}
_ => {
span_bug!(tcx.def_span(def_id), "main has a non-function type");
}
}
}
fn main_fn_asyncness_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> {
if !def_id.is_local() {
return None;
}
Some(tcx.def_span(def_id))
}
fn main_fn_return_type_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> {
if !def_id.is_local() {
return None;
}
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
match tcx.hir().find(hir_id) {
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(fn_sig, _, _), .. })) => {
Some(fn_sig.decl.output.span())
}
_ => {
span_bug!(tcx.def_span(def_id), "main has a non-function type");
}
}
}
let mut error = false;
let main_diagnostics_def_id = main_fn_diagnostics_def_id(tcx, main_def_id, main_span);
let main_fn_generics = tcx.generics_of(main_def_id);
let main_fn_predicates = tcx.predicates_of(main_def_id);
if main_fn_generics.count() != 0 || !main_fnsig.bound_vars().is_empty() {
let generics_param_span = main_fn_generics_params_span(tcx, main_def_id);
tcx.sess.emit_err(errors::MainFunctionGenericParameters {
span: generics_param_span.unwrap_or(main_span),
label_span: generics_param_span,
});
error = true;
} else if !main_fn_predicates.predicates.is_empty() {
// generics may bring in implicit predicates, so we skip this check if generics is present.
let generics_where_clauses_span = main_fn_where_clauses_span(tcx, main_def_id);
tcx.sess.emit_err(errors::WhereClauseOnMain {
span: generics_where_clauses_span.unwrap_or(main_span),
generics_span: generics_where_clauses_span,
});
error = true;
}
let main_asyncness = tcx.asyncness(main_def_id);
if let hir::IsAsync::Async = main_asyncness {
let asyncness_span = main_fn_asyncness_span(tcx, main_def_id);
tcx.sess.emit_err(errors::MainFunctionAsync { span: main_span, asyncness: asyncness_span });
error = true;
}
for attr in tcx.get_attrs(main_def_id, sym::track_caller) {
tcx.sess.emit_err(errors::TrackCallerOnMain { span: attr.span, annotated: main_span });
error = true;
}
if !tcx.codegen_fn_attrs(main_def_id).target_features.is_empty()
// Calling functions with `#[target_feature]` is not unsafe on WASM, see #84988
&& !tcx.sess.target.is_like_wasm
&& !tcx.sess.opts.actually_rustdoc
{
tcx.sess.emit_err(errors::TargetFeatureOnMain { main: main_span });
error = true;
}
if error {
return;
}
// Main should have no WC, so empty param env is OK here.
let param_env = ty::ParamEnv::empty();
let expected_return_type;
if let Some(term_did) = tcx.lang_items().termination() {
let return_ty = main_fnsig.output();
let return_ty_span = main_fn_return_type_span(tcx, main_def_id).unwrap_or(main_span);
if !return_ty.bound_vars().is_empty() {
tcx.sess.emit_err(errors::MainFunctionReturnTypeGeneric { span: return_ty_span });
error = true;
}
let return_ty = return_ty.skip_binder();
let infcx = tcx.infer_ctxt().build();
let cause = traits::ObligationCause::new(
return_ty_span,
main_diagnostics_def_id,
ObligationCauseCode::MainFunctionType,
);
let ocx = traits::ObligationCtxt::new(&infcx);
let norm_return_ty = ocx.normalize(&cause, param_env, return_ty);
ocx.register_bound(cause, param_env, norm_return_ty, term_did);
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
infcx.err_ctxt().report_fulfillment_errors(&errors);
error = true;
}
// now we can take the return type of the given main function
expected_return_type = main_fnsig.output();
} else {
// standard () main return type
expected_return_type = ty::Binder::dummy(Ty::new_unit(tcx));
}
if error {
return;
}
let se_ty = Ty::new_fn_ptr(
tcx,
expected_return_type.map_bound(|expected_return_type| {
tcx.mk_fn_sig([], expected_return_type, false, hir::Unsafety::Normal, Abi::Rust)
}),
);
require_same_types(
tcx,
&ObligationCause::new(
main_span,
main_diagnostics_def_id,
ObligationCauseCode::MainFunctionType,
),
param_env,
se_ty,
Ty::new_fn_ptr(tcx, main_fnsig),
);
}
fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
let start_def_id = start_def_id.expect_local();
let start_id = tcx.hir().local_def_id_to_hir_id(start_def_id);
let start_span = tcx.def_span(start_def_id);
let start_t = tcx.type_of(start_def_id).instantiate_identity();
match start_t.kind() {
ty::FnDef(..) => {
if let Some(Node::Item(it)) = tcx.hir().find(start_id) {
if let hir::ItemKind::Fn(sig, generics, _) = &it.kind {
let mut error = false;
if !generics.params.is_empty() {
tcx.sess.emit_err(errors::StartFunctionParameters { span: generics.span });
error = true;
}
if generics.has_where_clause_predicates {
tcx.sess.emit_err(errors::StartFunctionWhere {
span: generics.where_clause_span,
});
error = true;
}
if let hir::IsAsync::Async = sig.header.asyncness {
let span = tcx.def_span(it.owner_id);
tcx.sess.emit_err(errors::StartAsync { span: span });
error = true;
}
let attrs = tcx.hir().attrs(start_id);
for attr in attrs {
if attr.has_name(sym::track_caller) {
tcx.sess.emit_err(errors::StartTrackCaller {
span: attr.span,
start: start_span,
});
error = true;
}
if attr.has_name(sym::target_feature)
// Calling functions with `#[target_feature]` is
// not unsafe on WASM, see #84988
&& !tcx.sess.target.is_like_wasm
&& !tcx.sess.opts.actually_rustdoc
{
tcx.sess.emit_err(errors::StartTargetFeature {
span: attr.span,
start: start_span,
});
error = true;
}
}
if error {
return;
}
}
}
let se_ty = Ty::new_fn_ptr(
tcx,
ty::Binder::dummy(tcx.mk_fn_sig(
[tcx.types.isize, Ty::new_imm_ptr(tcx, Ty::new_imm_ptr(tcx, tcx.types.u8))],
tcx.types.isize,
false,
hir::Unsafety::Normal,
Abi::Rust,
)),
);
require_same_types(
tcx,
&ObligationCause::new(
start_span,
start_def_id,
ObligationCauseCode::StartFunctionType,
),
ty::ParamEnv::empty(), // start should not have any where bounds.
se_ty,
Ty::new_fn_ptr(tcx, tcx.fn_sig(start_def_id).instantiate_identity()),
);
}
_ => {
span_bug!(start_span, "start has a non-function type: found `{}`", start_t);
}
}
}

View file

@ -65,6 +65,7 @@ a type parameter).
mod check;
mod compare_impl_item;
pub mod dropck;
mod entry;
pub mod intrinsic;
pub mod intrinsicck;
mod region;

View file

@ -99,20 +99,16 @@ use rustc_errors::ErrorGuaranteed;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_fluent_macro::fluent_messages;
use rustc_hir as hir;
use rustc_hir::Node;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::middle;
use rustc_middle::query::Providers;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::util;
use rustc_session::{config::EntryFnType, parse::feature_err};
use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
use rustc_session::parse::feature_err;
use rustc_span::{symbol::sym, Span, DUMMY_SP};
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, ObligationCtxt};
use std::ops::Not;
use rustc_trait_selection::traits::{self, ObligationCause, ObligationCtxt};
use astconv::{AstConv, OnlySelfBounds};
use bounds::Bounds;
@ -177,267 +173,6 @@ fn require_same_types<'tcx>(
}
}
fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
let main_fnsig = tcx.fn_sig(main_def_id).instantiate_identity();
let main_span = tcx.def_span(main_def_id);
fn main_fn_diagnostics_def_id(tcx: TyCtxt<'_>, def_id: DefId, sp: Span) -> LocalDefId {
if let Some(local_def_id) = def_id.as_local() {
let hir_type = tcx.type_of(local_def_id).instantiate_identity();
if !matches!(hir_type.kind(), ty::FnDef(..)) {
span_bug!(sp, "main has a non-function type: found `{}`", hir_type);
}
local_def_id
} else {
CRATE_DEF_ID
}
}
fn main_fn_generics_params_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> {
if !def_id.is_local() {
return None;
}
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
match tcx.hir().find(hir_id) {
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => {
generics.params.is_empty().not().then_some(generics.span)
}
_ => {
span_bug!(tcx.def_span(def_id), "main has a non-function type");
}
}
}
fn main_fn_where_clauses_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> {
if !def_id.is_local() {
return None;
}
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
match tcx.hir().find(hir_id) {
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => {
Some(generics.where_clause_span)
}
_ => {
span_bug!(tcx.def_span(def_id), "main has a non-function type");
}
}
}
fn main_fn_asyncness_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> {
if !def_id.is_local() {
return None;
}
Some(tcx.def_span(def_id))
}
fn main_fn_return_type_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> {
if !def_id.is_local() {
return None;
}
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
match tcx.hir().find(hir_id) {
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(fn_sig, _, _), .. })) => {
Some(fn_sig.decl.output.span())
}
_ => {
span_bug!(tcx.def_span(def_id), "main has a non-function type");
}
}
}
let mut error = false;
let main_diagnostics_def_id = main_fn_diagnostics_def_id(tcx, main_def_id, main_span);
let main_fn_generics = tcx.generics_of(main_def_id);
let main_fn_predicates = tcx.predicates_of(main_def_id);
if main_fn_generics.count() != 0 || !main_fnsig.bound_vars().is_empty() {
let generics_param_span = main_fn_generics_params_span(tcx, main_def_id);
tcx.sess.emit_err(errors::MainFunctionGenericParameters {
span: generics_param_span.unwrap_or(main_span),
label_span: generics_param_span,
});
error = true;
} else if !main_fn_predicates.predicates.is_empty() {
// generics may bring in implicit predicates, so we skip this check if generics is present.
let generics_where_clauses_span = main_fn_where_clauses_span(tcx, main_def_id);
tcx.sess.emit_err(errors::WhereClauseOnMain {
span: generics_where_clauses_span.unwrap_or(main_span),
generics_span: generics_where_clauses_span,
});
error = true;
}
let main_asyncness = tcx.asyncness(main_def_id);
if let hir::IsAsync::Async = main_asyncness {
let asyncness_span = main_fn_asyncness_span(tcx, main_def_id);
tcx.sess.emit_err(errors::MainFunctionAsync { span: main_span, asyncness: asyncness_span });
error = true;
}
for attr in tcx.get_attrs(main_def_id, sym::track_caller) {
tcx.sess.emit_err(errors::TrackCallerOnMain { span: attr.span, annotated: main_span });
error = true;
}
if !tcx.codegen_fn_attrs(main_def_id).target_features.is_empty()
// Calling functions with `#[target_feature]` is not unsafe on WASM, see #84988
&& !tcx.sess.target.is_like_wasm
&& !tcx.sess.opts.actually_rustdoc
{
tcx.sess.emit_err(errors::TargetFeatureOnMain { main: main_span });
error = true;
}
if error {
return;
}
// Main should have no WC, so empty param env is OK here.
let param_env = ty::ParamEnv::empty();
let expected_return_type;
if let Some(term_did) = tcx.lang_items().termination() {
let return_ty = main_fnsig.output();
let return_ty_span = main_fn_return_type_span(tcx, main_def_id).unwrap_or(main_span);
if !return_ty.bound_vars().is_empty() {
tcx.sess.emit_err(errors::MainFunctionReturnTypeGeneric { span: return_ty_span });
error = true;
}
let return_ty = return_ty.skip_binder();
let infcx = tcx.infer_ctxt().build();
let cause = traits::ObligationCause::new(
return_ty_span,
main_diagnostics_def_id,
ObligationCauseCode::MainFunctionType,
);
let ocx = traits::ObligationCtxt::new(&infcx);
let norm_return_ty = ocx.normalize(&cause, param_env, return_ty);
ocx.register_bound(cause, param_env, norm_return_ty, term_did);
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
infcx.err_ctxt().report_fulfillment_errors(&errors);
error = true;
}
// now we can take the return type of the given main function
expected_return_type = main_fnsig.output();
} else {
// standard () main return type
expected_return_type = ty::Binder::dummy(Ty::new_unit(tcx));
}
if error {
return;
}
let se_ty = Ty::new_fn_ptr(
tcx,
expected_return_type.map_bound(|expected_return_type| {
tcx.mk_fn_sig([], expected_return_type, false, hir::Unsafety::Normal, Abi::Rust)
}),
);
require_same_types(
tcx,
&ObligationCause::new(
main_span,
main_diagnostics_def_id,
ObligationCauseCode::MainFunctionType,
),
param_env,
se_ty,
Ty::new_fn_ptr(tcx, main_fnsig),
);
}
fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
let start_def_id = start_def_id.expect_local();
let start_id = tcx.hir().local_def_id_to_hir_id(start_def_id);
let start_span = tcx.def_span(start_def_id);
let start_t = tcx.type_of(start_def_id).instantiate_identity();
match start_t.kind() {
ty::FnDef(..) => {
if let Some(Node::Item(it)) = tcx.hir().find(start_id) {
if let hir::ItemKind::Fn(sig, generics, _) = &it.kind {
let mut error = false;
if !generics.params.is_empty() {
tcx.sess.emit_err(errors::StartFunctionParameters { span: generics.span });
error = true;
}
if generics.has_where_clause_predicates {
tcx.sess.emit_err(errors::StartFunctionWhere {
span: generics.where_clause_span,
});
error = true;
}
if let hir::IsAsync::Async = sig.header.asyncness {
let span = tcx.def_span(it.owner_id);
tcx.sess.emit_err(errors::StartAsync { span: span });
error = true;
}
let attrs = tcx.hir().attrs(start_id);
for attr in attrs {
if attr.has_name(sym::track_caller) {
tcx.sess.emit_err(errors::StartTrackCaller {
span: attr.span,
start: start_span,
});
error = true;
}
if attr.has_name(sym::target_feature)
// Calling functions with `#[target_feature]` is
// not unsafe on WASM, see #84988
&& !tcx.sess.target.is_like_wasm
&& !tcx.sess.opts.actually_rustdoc
{
tcx.sess.emit_err(errors::StartTargetFeature {
span: attr.span,
start: start_span,
});
error = true;
}
}
if error {
return;
}
}
}
let se_ty = Ty::new_fn_ptr(
tcx,
ty::Binder::dummy(tcx.mk_fn_sig(
[tcx.types.isize, Ty::new_imm_ptr(tcx, Ty::new_imm_ptr(tcx, tcx.types.u8))],
tcx.types.isize,
false,
hir::Unsafety::Normal,
Abi::Rust,
)),
);
require_same_types(
tcx,
&ObligationCause::new(
start_span,
start_def_id,
ObligationCauseCode::StartFunctionType,
),
ty::ParamEnv::empty(), // start should not have any where bounds.
se_ty,
Ty::new_fn_ptr(tcx, tcx.fn_sig(start_def_id).instantiate_identity()),
);
}
_ => {
span_bug!(start_span, "start has a non-function type: found `{}`", start_t);
}
}
}
fn check_for_entry_fn(tcx: TyCtxt<'_>) {
match tcx.entry_fn(()) {
Some((def_id, EntryFnType::Main { .. })) => check_main_fn_ty(tcx, def_id),
Some((def_id, EntryFnType::Start)) => check_start_fn_ty(tcx, def_id),
_ => {}
}
}
pub fn provide(providers: &mut Providers) {
collect::provide(providers);
coherence::provide(providers);
@ -513,7 +248,6 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
});
check_unused::check_crate(tcx);
check_for_entry_fn(tcx);
if let Some(reported) = tcx.sess.has_errors() { Err(reported) } else { Ok(()) }
}

View file

@ -9,6 +9,7 @@ edition = "2021"
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
tracing = "0.1"
rustc_ast = { path = "../rustc_ast" }
rustc_attr = { path = "../rustc_attr" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_graphviz = { path = "../rustc_graphviz" }

View file

@ -2,7 +2,7 @@ use crate::FnCtxt;
use rustc_hir as hir;
use rustc_hir::def::Res;
use rustc_hir::def_id::DefId;
use rustc_infer::traits::ObligationCauseCode;
use rustc_infer::{infer::type_variable::TypeVariableOriginKind, traits::ObligationCauseCode};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
use rustc_span::{self, symbol::kw, Span};
use rustc_trait_selection::traits;
@ -267,8 +267,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
type BreakTy = ty::GenericArg<'tcx>;
fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow<Self::BreakTy> {
if let Some(origin) = self.0.type_var_origin(ty)
&& let rustc_infer::infer::type_variable::TypeVariableOriginKind::TypeParameterDefinition(_, def_id) =
origin.kind
&& let TypeVariableOriginKind::TypeParameterDefinition(_, def_id) = origin.kind
&& let generics = self.0.tcx.generics_of(self.1)
&& let Some(index) = generics.param_def_id_to_index(self.0.tcx, def_id)
&& let Some(subst) = ty::GenericArgs::identity_for_item(self.0.tcx, self.1)

View file

@ -302,7 +302,9 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
match ty.kind() {
ty::Adt(adt_def, _) => Some(*adt_def),
// FIXME(#104767): Should we handle bound regions here?
ty::Alias(ty::Projection | ty::Inherent, _) if !ty.has_escaping_bound_vars() => {
ty::Alias(ty::Projection | ty::Inherent | ty::Weak, _)
if !ty.has_escaping_bound_vars() =>
{
self.normalize(span, ty).ty_adt_def()
}
_ => None,

View file

@ -2,13 +2,12 @@
//! found or is otherwise invalid.
use crate::errors;
use crate::errors::CandidateTraitNote;
use crate::errors::NoAssociatedItem;
use crate::errors::{CandidateTraitNote, NoAssociatedItem};
use crate::Expectation;
use crate::FnCtxt;
use rustc_ast::ast::Mutability;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::fx::FxIndexSet;
use rustc_attr::parse_confusables;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::unord::UnordSet;
use rustc_errors::StashKey;
use rustc_errors::{
@ -1038,6 +1037,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
"the {item_kind} was found for\n{}{}",
type_candidates, additional_types
));
} else {
'outer: for inherent_impl_did in self.tcx.inherent_impls(adt.did()) {
for inherent_method in
self.tcx.associated_items(inherent_impl_did).in_definition_order()
{
if let Some(attr) = self.tcx.get_attr(inherent_method.def_id, sym::rustc_confusables)
&& let Some(candidates) = parse_confusables(attr)
&& candidates.contains(&item_name.name)
{
err.span_suggestion_verbose(
item_name.span,
format!(
"you might have meant to use `{}`",
inherent_method.name.as_str()
),
inherent_method.name.as_str(),
Applicability::MaybeIncorrect,
);
break 'outer;
}
}
}
}
}
} else {

View file

@ -163,7 +163,7 @@ fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinte
let ty_vars = infcx_inner.type_variables();
let var_origin = ty_vars.var_origin(ty_vid);
if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) = var_origin.kind
&& !var_origin.span.from_expansion()
&& name != kw::SelfUpper && !var_origin.span.from_expansion()
{
let generics = infcx.tcx.generics_of(infcx.tcx.parent(def_id));
let idx = generics.param_def_id_to_index(infcx.tcx, def_id).unwrap();

View file

@ -251,8 +251,11 @@ fn main() {
} else if target.contains("windows-gnu") {
println!("cargo:rustc-link-lib=shell32");
println!("cargo:rustc-link-lib=uuid");
} else if target.contains("netbsd") || target.contains("haiku") || target.contains("darwin") {
} else if target.contains("haiku") || target.contains("darwin") {
println!("cargo:rustc-link-lib=z");
} else if target.contains("netbsd") {
println!("cargo:rustc-link-lib=z");
println!("cargo:rustc-link-lib=execinfo");
}
cmd.args(&components);

View file

@ -608,7 +608,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
trace!("encoding {} further alloc ids", new_n - n);
for idx in n..new_n {
let id = self.interpret_allocs[idx];
let pos = self.position() as u32;
let pos = self.position() as u64;
interpret_alloc_index.push(pos);
interpret::specialized_encode_alloc_id(self, tcx, id);
}

View file

@ -264,7 +264,7 @@ pub(crate) struct CrateRoot {
traits: LazyArray<DefIndex>,
impls: LazyArray<TraitImpls>,
incoherent_impls: LazyArray<IncoherentImpls>,
interpret_alloc_index: LazyArray<u32>,
interpret_alloc_index: LazyArray<u64>,
proc_macro_data: Option<ProcMacroData>,
tables: LazyTables,

View file

@ -274,7 +274,7 @@ pub struct AllocDecodingState {
// For each `AllocId`, we keep track of which decoding state it's currently in.
decoding_state: Vec<Lock<State>>,
// The offsets of each allocation in the data stream.
data_offsets: Vec<u32>,
data_offsets: Vec<u64>,
}
impl AllocDecodingState {
@ -289,7 +289,7 @@ impl AllocDecodingState {
AllocDecodingSession { state: self, session_id }
}
pub fn new(data_offsets: Vec<u32>) -> Self {
pub fn new(data_offsets: Vec<u64>) -> Self {
let decoding_state =
std::iter::repeat_with(|| Lock::new(State::Empty)).take(data_offsets.len()).collect();

View file

@ -59,12 +59,19 @@ impl<'tcx> MonoItem<'tcx> {
pub fn size_estimate(&self, tcx: TyCtxt<'tcx>) -> usize {
match *self {
MonoItem::Fn(instance) => {
// Estimate the size of a function based on how many statements
// it contains.
tcx.instance_def_size_estimate(instance.def)
match instance.def {
// "Normal" functions size estimate: the number of
// statements, plus one for the terminator.
InstanceDef::Item(..) | InstanceDef::DropGlue(..) => {
let mir = tcx.instance_mir(instance.def);
mir.basic_blocks.iter().map(|bb| bb.statements.len() + 1).sum()
}
// Other compiler-generated shims size estimate: 1
_ => 1,
}
}
// Conservatively estimate the size of a static declaration
// or assembly to be 1.
// Conservatively estimate the size of a static declaration or
// assembly item to be 1.
MonoItem::Static(_) | MonoItem::GlobalAsm(_) => 1,
}
}
@ -230,7 +237,7 @@ pub struct CodegenUnit<'tcx> {
/// contain something unique to this crate (e.g., a module path)
/// as well as the crate name and disambiguator.
name: Symbol,
items: FxHashMap<MonoItem<'tcx>, (Linkage, Visibility)>,
items: FxHashMap<MonoItem<'tcx>, MonoItemData>,
size_estimate: usize,
primary: bool,
/// True if this is CGU is used to hold code coverage information for dead code,
@ -238,6 +245,14 @@ pub struct CodegenUnit<'tcx> {
is_code_coverage_dead_code_cgu: bool,
}
/// Auxiliary info about a `MonoItem`.
#[derive(Copy, Clone, PartialEq, Debug, HashStable)]
pub struct MonoItemData {
pub linkage: Linkage,
pub visibility: Visibility,
pub size_estimate: usize,
}
/// Specifies the linkage type for a `MonoItem`.
///
/// See <https://llvm.org/docs/LangRef.html#linkage-types> for more details about these variants.
@ -292,12 +307,12 @@ impl<'tcx> CodegenUnit<'tcx> {
}
/// The order of these items is non-determinstic.
pub fn items(&self) -> &FxHashMap<MonoItem<'tcx>, (Linkage, Visibility)> {
pub fn items(&self) -> &FxHashMap<MonoItem<'tcx>, MonoItemData> {
&self.items
}
/// The order of these items is non-determinstic.
pub fn items_mut(&mut self) -> &mut FxHashMap<MonoItem<'tcx>, (Linkage, Visibility)> {
pub fn items_mut(&mut self) -> &mut FxHashMap<MonoItem<'tcx>, MonoItemData> {
&mut self.items
}
@ -320,16 +335,16 @@ impl<'tcx> CodegenUnit<'tcx> {
base_n::encode(hash, base_n::CASE_INSENSITIVE)
}
pub fn compute_size_estimate(&mut self, tcx: TyCtxt<'tcx>) {
// Estimate the size of a codegen unit as (approximately) the number of MIR
// statements it corresponds to.
self.size_estimate = self.items.keys().map(|mi| mi.size_estimate(tcx)).sum();
pub fn compute_size_estimate(&mut self) {
// The size of a codegen unit as the sum of the sizes of the items
// within it.
self.size_estimate = self.items.values().map(|data| data.size_estimate).sum();
}
#[inline]
/// Should only be called if [`compute_size_estimate`] has previously been called.
///
/// [`compute_size_estimate`]: Self::compute_size_estimate
#[inline]
pub fn size_estimate(&self) -> usize {
// Items are never zero-sized, so if we have items the estimate must be
// non-zero, unless we forgot to call `compute_size_estimate` first.
@ -355,7 +370,7 @@ impl<'tcx> CodegenUnit<'tcx> {
pub fn items_in_deterministic_order(
&self,
tcx: TyCtxt<'tcx>,
) -> Vec<(MonoItem<'tcx>, (Linkage, Visibility))> {
) -> Vec<(MonoItem<'tcx>, MonoItemData)> {
// The codegen tests rely on items being process in the same order as
// they appear in the file, so for local items, we sort by node_id first
#[derive(PartialEq, Eq, PartialOrd, Ord)]
@ -390,7 +405,7 @@ impl<'tcx> CodegenUnit<'tcx> {
)
}
let mut items: Vec<_> = self.items().iter().map(|(&i, &l)| (i, l)).collect();
let mut items: Vec<_> = self.items().iter().map(|(&i, &data)| (i, data)).collect();
items.sort_by_cached_key(|&(i, _)| item_sort_key(tcx, i));
items
}

View file

@ -2080,12 +2080,6 @@ rustc_queries! {
desc { "looking up supported target features" }
}
/// Get an estimate of the size of an InstanceDef based on its MIR for CGU partitioning.
query instance_def_size_estimate(def: ty::InstanceDef<'tcx>)
-> usize {
desc { |tcx| "estimating size for `{}`", tcx.def_path_str(def.def_id()) }
}
query features_query(_: ()) -> &'tcx rustc_feature::Features {
feedable
desc { "looking up enabled feature gates" }

View file

@ -104,7 +104,9 @@ struct Footer {
query_result_index: EncodedDepNodeIndex,
side_effects_index: EncodedDepNodeIndex,
// The location of all allocations.
interpret_alloc_index: Vec<u32>,
// Most uses only need values up to u32::MAX, but benchmarking indicates that we can use a u64
// without measurable overhead. This permits larger const allocations without ICEing.
interpret_alloc_index: Vec<u64>,
// See `OnDiskCache.syntax_contexts`
syntax_contexts: FxHashMap<u32, AbsoluteBytePos>,
// See `OnDiskCache.expn_data`
@ -301,7 +303,7 @@ impl<'sess> OnDiskCache<'sess> {
interpret_alloc_index.reserve(new_n - n);
for idx in n..new_n {
let id = encoder.interpret_allocs[idx];
let pos: u32 = encoder.position().try_into().unwrap();
let pos: u64 = encoder.position().try_into().unwrap();
interpret_alloc_index.push(pos);
interpret::specialized_encode_alloc_id(&mut encoder, tcx, id);
}

View file

@ -24,7 +24,7 @@ pub enum ValTree<'tcx> {
Leaf(ScalarInt),
//SliceOrStr(ValSlice<'tcx>),
// dont use SliceOrStr for now
// don't use SliceOrStr for now
/// The fields of any kind of aggregate. Structs, tuples and arrays are represented by
/// listing their fields' values in order.
///

View file

@ -52,6 +52,7 @@ trivially_parameterized_over_tcx! {
usize,
(),
u32,
u64,
bool,
std::string::String,
crate::metadata::ModChild,

View file

@ -1313,7 +1313,7 @@ impl<'tcx> AliasTy<'tcx> {
/// I_i impl subst
/// P_j GAT subst
/// ```
pub fn rebase_args_onto_impl(
pub fn rebase_inherent_args_onto_impl(
self,
impl_args: ty::GenericArgsRef<'tcx>,
tcx: TyCtxt<'tcx>,

View file

@ -107,7 +107,8 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel};
use rustc_middle::mir;
use rustc_middle::mir::mono::{
CodegenUnit, CodegenUnitNameBuilder, InstantiationMode, Linkage, MonoItem, Visibility,
CodegenUnit, CodegenUnitNameBuilder, InstantiationMode, Linkage, MonoItem, MonoItemData,
Visibility,
};
use rustc_middle::query::Providers;
use rustc_middle::ty::print::{characteristic_def_id_of_type, with_no_trimmed_paths};
@ -130,11 +131,6 @@ struct PlacedMonoItems<'tcx> {
codegen_units: Vec<CodegenUnit<'tcx>>,
internalization_candidates: FxHashSet<MonoItem<'tcx>>,
/// These must be obtained when the iterator in `partition` runs. They
/// can't be obtained later because some inlined functions might not be
/// reachable.
unique_inlined_stats: (usize, usize),
}
// The output CGUs are sorted by name.
@ -152,11 +148,11 @@ where
// Place all mono items into a codegen unit. `place_mono_items` is
// responsible for initializing the CGU size estimates.
let PlacedMonoItems { mut codegen_units, internalization_candidates, unique_inlined_stats } = {
let PlacedMonoItems { mut codegen_units, internalization_candidates } = {
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_items");
let placed = place_mono_items(cx, mono_items);
debug_dump(tcx, "PLACE", &placed.codegen_units, placed.unique_inlined_stats);
debug_dump(tcx, "PLACE", &placed.codegen_units);
placed
};
@ -167,7 +163,7 @@ where
{
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_merge_cgus");
merge_codegen_units(cx, &mut codegen_units);
debug_dump(tcx, "MERGE", &codegen_units, unique_inlined_stats);
debug_dump(tcx, "MERGE", &codegen_units);
}
// Make as many symbols "internal" as possible, so LLVM has more freedom to
@ -176,7 +172,7 @@ where
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_internalize_symbols");
internalize_symbols(cx, &mut codegen_units, internalization_candidates);
debug_dump(tcx, "INTERNALIZE", &codegen_units, unique_inlined_stats);
debug_dump(tcx, "INTERNALIZE", &codegen_units);
}
// Mark one CGU for dead code, if necessary.
@ -216,18 +212,12 @@ where
let cgu_name_builder = &mut CodegenUnitNameBuilder::new(cx.tcx);
let cgu_name_cache = &mut FxHashMap::default();
let mut num_unique_inlined_items = 0;
let mut unique_inlined_items_size = 0;
for mono_item in mono_items {
// Handle only root items directly here. Inlined items are handled at
// the bottom of the loop based on reachability.
match mono_item.instantiation_mode(cx.tcx) {
InstantiationMode::GloballyShared { .. } => {}
InstantiationMode::LocalCopy => {
num_unique_inlined_items += 1;
unique_inlined_items_size += mono_item.size_estimate(cx.tcx);
continue;
}
InstantiationMode::LocalCopy => continue,
}
let characteristic_def_id = characteristic_def_id_of_mono_item(cx.tcx, mono_item);
@ -256,8 +246,9 @@ where
if visibility == Visibility::Hidden && can_be_internalized {
internalization_candidates.insert(mono_item);
}
let size_estimate = mono_item.size_estimate(cx.tcx);
cgu.items_mut().insert(mono_item, (linkage, visibility));
cgu.items_mut().insert(mono_item, MonoItemData { linkage, visibility, size_estimate });
// Get all inlined items that are reachable from `mono_item` without
// going via another root item. This includes drop-glue, functions from
@ -271,7 +262,11 @@ where
// the `insert` will be a no-op.
for inlined_item in reachable_inlined_items {
// This is a CGU-private copy.
cgu.items_mut().insert(inlined_item, (Linkage::Internal, Visibility::Default));
cgu.items_mut().entry(inlined_item).or_insert_with(|| MonoItemData {
linkage: Linkage::Internal,
visibility: Visibility::Default,
size_estimate: inlined_item.size_estimate(cx.tcx),
});
}
}
@ -286,14 +281,10 @@ where
codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str()));
for cgu in codegen_units.iter_mut() {
cgu.compute_size_estimate(cx.tcx);
cgu.compute_size_estimate();
}
return PlacedMonoItems {
codegen_units,
internalization_candidates,
unique_inlined_stats: (num_unique_inlined_items, unique_inlined_items_size),
};
return PlacedMonoItems { codegen_units, internalization_candidates };
fn get_reachable_inlined_items<'tcx>(
tcx: TyCtxt<'tcx>,
@ -349,7 +340,7 @@ fn merge_codegen_units<'tcx>(
&& codegen_units.iter().any(|cgu| cgu.size_estimate() < NON_INCR_MIN_CGU_SIZE))
{
// Sort small cgus to the back.
codegen_units.sort_by_cached_key(|cgu| cmp::Reverse(cgu.size_estimate()));
codegen_units.sort_by_key(|cgu| cmp::Reverse(cgu.size_estimate()));
let mut smallest = codegen_units.pop().unwrap();
let second_smallest = codegen_units.last_mut().unwrap();
@ -358,7 +349,7 @@ fn merge_codegen_units<'tcx>(
// may be duplicate inlined items, in which case the destination CGU is
// unaffected. Recalculate size estimates afterwards.
second_smallest.items_mut().extend(smallest.items_mut().drain());
second_smallest.compute_size_estimate(cx.tcx);
second_smallest.compute_size_estimate();
// Record that `second_smallest` now contains all the stuff that was
// in `smallest` before.
@ -492,7 +483,7 @@ fn internalize_symbols<'tcx>(
for cgu in codegen_units {
let home_cgu = MonoItemPlacement::SingleCgu(cgu.name());
for (item, linkage_and_visibility) in cgu.items_mut() {
for (item, data) in cgu.items_mut() {
if !internalization_candidates.contains(item) {
// This item is no candidate for internalizing, so skip it.
continue;
@ -520,7 +511,8 @@ fn internalize_symbols<'tcx>(
// If we got here, we did not find any uses from other CGUs, so
// it's fine to make this monomorphization internal.
*linkage_and_visibility = (Linkage::Internal, Visibility::Default);
data.linkage = Linkage::Internal;
data.visibility = Visibility::Default;
}
}
}
@ -537,7 +529,7 @@ fn mark_code_coverage_dead_code_cgu<'tcx>(codegen_units: &mut [CodegenUnit<'tcx>
// function symbols to be included via `-u` or `/include` linker args.
let dead_code_cgu = codegen_units
.iter_mut()
.filter(|cgu| cgu.items().iter().any(|(_, (linkage, _))| *linkage == Linkage::External))
.filter(|cgu| cgu.items().iter().any(|(_, data)| data.linkage == Linkage::External))
.min_by_key(|cgu| cgu.size_estimate());
// If there are no CGUs that have externally linked items, then we just
@ -851,12 +843,7 @@ fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibilit
}
}
fn debug_dump<'a, 'tcx: 'a>(
tcx: TyCtxt<'tcx>,
label: &str,
cgus: &[CodegenUnit<'tcx>],
(unique_inlined_items, unique_inlined_size): (usize, usize),
) {
fn debug_dump<'a, 'tcx: 'a>(tcx: TyCtxt<'tcx>, label: &str, cgus: &[CodegenUnit<'tcx>]) {
let dump = move || {
use std::fmt::Write;
@ -865,28 +852,36 @@ fn debug_dump<'a, 'tcx: 'a>(
// Note: every unique root item is placed exactly once, so the number
// of unique root items always equals the number of placed root items.
//
// Also, unreached inlined items won't be counted here. This is fine.
let mut inlined_items = FxHashSet::default();
let mut root_items = 0;
// unique_inlined_items is passed in above.
let mut unique_inlined_items = 0;
let mut placed_inlined_items = 0;
let mut root_size = 0;
// unique_inlined_size is passed in above.
let mut unique_inlined_size = 0;
let mut placed_inlined_size = 0;
for cgu in cgus.iter() {
num_cgus += 1;
all_cgu_sizes.push(cgu.size_estimate());
for (item, _) in cgu.items() {
for (item, data) in cgu.items() {
match item.instantiation_mode(tcx) {
InstantiationMode::GloballyShared { .. } => {
root_items += 1;
root_size += item.size_estimate(tcx);
root_size += data.size_estimate;
}
InstantiationMode::LocalCopy => {
if inlined_items.insert(item) {
unique_inlined_items += 1;
unique_inlined_size += data.size_estimate;
}
placed_inlined_items += 1;
placed_inlined_size += item.size_estimate(tcx);
placed_inlined_size += data.size_estimate;
}
}
}
@ -928,7 +923,7 @@ fn debug_dump<'a, 'tcx: 'a>(
let mean_size = size as f64 / num_items as f64;
let mut placed_item_sizes: Vec<_> =
cgu.items().iter().map(|(item, _)| item.size_estimate(tcx)).collect();
cgu.items().values().map(|data| data.size_estimate).collect();
placed_item_sizes.sort_unstable_by_key(|&n| cmp::Reverse(n));
let sizes = list(&placed_item_sizes);
@ -937,15 +932,16 @@ fn debug_dump<'a, 'tcx: 'a>(
let _ =
writeln!(s, " - items: {num_items}, mean size: {mean_size:.1}, sizes: {sizes}",);
for (item, linkage) in cgu.items_in_deterministic_order(tcx) {
for (item, data) in cgu.items_in_deterministic_order(tcx) {
let linkage = data.linkage;
let symbol_name = item.symbol_name(tcx).name;
let symbol_hash_start = symbol_name.rfind('h');
let symbol_hash = symbol_hash_start.map_or("<no hash>", |i| &symbol_name[i..]);
let size = item.size_estimate(tcx);
let kind = match item.instantiation_mode(tcx) {
InstantiationMode::GloballyShared { .. } => "root",
InstantiationMode::LocalCopy => "inlined",
};
let size = data.size_estimate;
let _ = with_no_trimmed_paths!(writeln!(
s,
" - {item} [{linkage:?}] [{symbol_hash}] ({kind}, size: {size})"
@ -1100,8 +1096,8 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co
let mut item_to_cgus: FxHashMap<_, Vec<_>> = Default::default();
for cgu in codegen_units {
for (&mono_item, &linkage) in cgu.items() {
item_to_cgus.entry(mono_item).or_default().push((cgu.name(), linkage));
for (&mono_item, &data) in cgu.items() {
item_to_cgus.entry(mono_item).or_default().push((cgu.name(), data.linkage));
}
}
@ -1114,7 +1110,7 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co
let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
cgus.sort_by_key(|(name, _)| *name);
cgus.dedup();
for &(ref cgu_name, (linkage, _)) in cgus.iter() {
for &(ref cgu_name, linkage) in cgus.iter() {
output.push(' ');
output.push_str(cgu_name.as_str());

View file

@ -98,6 +98,9 @@ passes_collapse_debuginfo =
`collapse_debuginfo` attribute should be applied to macro definitions
.label = not a macro definition
passes_confusables = attribute should be applied to an inherent method
.label = not an inherent method
passes_const_impl_const_trait =
const `impl`s must be for traits marked with `#[const_trait]`
.note = this trait must be annotated with `#[const_trait]`
@ -266,6 +269,9 @@ passes_duplicate_lang_item_crate_depends =
.first_definition_path = first definition in `{$orig_crate_name}` loaded from {$orig_path}
.second_definition_path = second definition in `{$crate_name}` loaded from {$path}
passes_empty_confusables =
expected at least one confusable name
passes_export_name =
attribute should be applied to a free function, impl method or static
.label = not a free function, impl method or static
@ -326,6 +332,9 @@ passes_implied_feature_not_exist =
passes_incorrect_do_not_recommend_location =
`#[do_not_recommend]` can only be placed on trait implementations
passes_incorrect_meta_item = expected a quoted string literal
passes_incorrect_meta_item_suggestion = consider surrounding this with quotes
passes_incorrect_target =
`{$name}` language item must be applied to a {$kind} with {$at_least ->
[true] at least {$num}

View file

@ -183,6 +183,7 @@ impl CheckAttrVisitor<'_> {
| sym::rustc_allowed_through_unstable_modules
| sym::rustc_promotable => self.check_stability_promotable(&attr, span, target),
sym::link_ordinal => self.check_link_ordinal(&attr, span, target),
sym::rustc_confusables => self.check_confusables(&attr, target),
_ => true,
};
@ -1985,6 +1986,46 @@ impl CheckAttrVisitor<'_> {
}
}
fn check_confusables(&self, attr: &Attribute, target: Target) -> bool {
match target {
Target::Method(MethodKind::Inherent) => {
let Some(meta) = attr.meta() else {
return false;
};
let ast::MetaItem { kind: MetaItemKind::List(ref metas), .. } = meta else {
return false;
};
let mut candidates = Vec::new();
for meta in metas {
let NestedMetaItem::Lit(meta_lit) = meta else {
self.tcx.sess.emit_err(errors::IncorrectMetaItem {
span: meta.span(),
suggestion: errors::IncorrectMetaItemSuggestion {
lo: meta.span().shrink_to_lo(),
hi: meta.span().shrink_to_hi(),
},
});
return false;
};
candidates.push(meta_lit.symbol);
}
if candidates.is_empty() {
self.tcx.sess.emit_err(errors::EmptyConfusables { span: attr.span });
return false;
}
true
}
_ => {
self.tcx.sess.emit_err(errors::Confusables { attr_span: attr.span });
false
}
}
}
fn check_deprecated(&self, hir_id: HirId, attr: &Attribute, _span: Span, target: Target) {
match target {
Target::Closure | Target::Expression | Target::Statement | Target::Arm => {

View file

@ -617,6 +617,38 @@ pub struct LinkOrdinal {
pub attr_span: Span,
}
#[derive(Diagnostic)]
#[diag(passes_confusables)]
pub struct Confusables {
#[primary_span]
pub attr_span: Span,
}
#[derive(Diagnostic)]
#[diag(passes_empty_confusables)]
pub(crate) struct EmptyConfusables {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(passes_incorrect_meta_item, code = "E0539")]
pub(crate) struct IncorrectMetaItem {
#[primary_span]
pub span: Span,
#[subdiagnostic]
pub suggestion: IncorrectMetaItemSuggestion,
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(passes_incorrect_meta_item_suggestion, applicability = "maybe-incorrect")]
pub(crate) struct IncorrectMetaItemSuggestion {
#[suggestion_part(code = "\"")]
pub lo: Span,
#[suggestion_part(code = "\"")]
pub hi: Span,
}
#[derive(Diagnostic)]
#[diag(passes_stability_promotable)]
pub struct StabilityPromotable {

View file

@ -1265,6 +1265,7 @@ symbols! {
rustc_clean,
rustc_coherence_is_core,
rustc_coinductive,
rustc_confusables,
rustc_const_stable,
rustc_const_unstable,
rustc_conversion_suggestion,

View file

@ -3,9 +3,7 @@ use crate::spec::{Target, TargetOptions};
use super::SanitizerSet;
pub fn target() -> Target {
let mut base = super::linux_musl_base::opts();
base.env = "ohos".into();
base.crt_static_default = false;
let mut base = super::linux_ohos_base::opts();
base.max_atomic_width = Some(128);
Target {
@ -17,8 +15,6 @@ pub fn target() -> Target {
options: TargetOptions {
features: "+reserve-x18".into(),
mcount: "\u{1}_mcount".into(),
force_emulated_tls: true,
has_thread_local: false,
supported_sanitizers: SanitizerSet::ADDRESS
| SanitizerSet::CFI
| SanitizerSet::LEAK

View file

@ -17,12 +17,8 @@ pub fn target() -> Target {
abi: "eabi".into(),
features: "+v7,+thumb2,+soft-float,-neon".into(),
max_atomic_width: Some(64),
env: "ohos".into(),
crt_static_default: false,
mcount: "\u{1}mcount".into(),
force_emulated_tls: true,
has_thread_local: false,
..super::linux_musl_base::opts()
..super::linux_ohos_base::opts()
},
}
}

View file

@ -0,0 +1,12 @@
use crate::spec::TargetOptions;
pub fn opts() -> TargetOptions {
let mut base = super::linux_base::opts();
base.env = "ohos".into();
base.crt_static_default = false;
base.force_emulated_tls = true;
base.has_thread_local = false;
base
}

View file

@ -74,6 +74,7 @@ mod l4re_base;
mod linux_base;
mod linux_gnu_base;
mod linux_musl_base;
mod linux_ohos_base;
mod linux_uclibc_base;
mod msvc_base;
mod netbsd_base;
@ -1433,6 +1434,8 @@ supported_targets! {
("riscv64gc-unknown-linux-gnu", riscv64gc_unknown_linux_gnu),
("riscv64gc-unknown-linux-musl", riscv64gc_unknown_linux_musl),
("sparc-unknown-none-elf", sparc_unknown_none_elf),
("loongarch64-unknown-none", loongarch64_unknown_none),
("loongarch64-unknown-none-softfloat", loongarch64_unknown_none_softfloat),
@ -1493,6 +1496,7 @@ supported_targets! {
("aarch64-unknown-linux-ohos", aarch64_unknown_linux_ohos),
("armv7-unknown-linux-ohos", armv7_unknown_linux_ohos),
("x86_64-unknown-linux-ohos", x86_64_unknown_linux_ohos),
}
/// Cow-Vec-Str: Cow<'static, [Cow<'static, str>]>

View file

@ -0,0 +1,27 @@
use crate::abi::Endian;
use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
pub fn target() -> Target {
let options = TargetOptions {
linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No),
linker: Some("sparc-elf-gcc".into()),
endian: Endian::Big,
cpu: "v7".into(),
abi: "elf".into(),
max_atomic_width: Some(32),
atomic_cas: true,
panic_strategy: PanicStrategy::Abort,
relocation_model: RelocModel::Static,
no_default_libraries: false,
emit_debug_gdb_scripts: false,
eh_frame_header: false,
..Default::default()
};
Target {
data_layout: "E-m:e-p:32:32-i64:64-f128:64-n32-S64".into(),
llvm_target: "sparc-unknown-none-elf".into(),
pointer_width: 32,
arch: "sparc".into(),
options,
}
}

View file

@ -0,0 +1,26 @@
use crate::spec::{Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target};
pub fn target() -> Target {
let mut base = super::linux_ohos_base::opts();
base.cpu = "x86-64".into();
base.max_atomic_width = Some(64);
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]);
base.stack_probes = StackProbeType::X86;
base.static_position_independent_executables = true;
base.supported_sanitizers = SanitizerSet::ADDRESS
| SanitizerSet::CFI
| SanitizerSet::LEAK
| SanitizerSet::MEMORY
| SanitizerSet::THREAD;
base.supports_xray = true;
Target {
// LLVM 15 doesn't support OpenHarmony yet, use a linux target instead.
llvm_target: "x86_64-unknown-linux-musl".into(),
pointer_width: 64,
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
.into(),
arch: "x86_64".into(),
options: base,
}
}

View file

@ -0,0 +1,44 @@
use rustc_middle::traits::solve::{Certainty, Goal, QueryResult};
use rustc_middle::ty;
use super::EvalCtxt;
impl<'tcx> EvalCtxt<'_, 'tcx> {
pub(super) fn normalize_inherent_associated_type(
&mut self,
goal: Goal<'tcx, ty::ProjectionPredicate<'tcx>>,
) -> QueryResult<'tcx> {
let tcx = self.tcx();
let inherent = goal.predicate.projection_ty;
let expected = goal.predicate.term.ty().expect("inherent consts are treated separately");
let impl_def_id = tcx.parent(inherent.def_id);
let impl_substs = self.fresh_args_for_item(impl_def_id);
// Equate impl header and add impl where clauses
self.eq(
goal.param_env,
inherent.self_ty(),
tcx.type_of(impl_def_id).instantiate(tcx, impl_substs),
)?;
// Equate IAT with the RHS of the project goal
let inherent_substs = inherent.rebase_inherent_args_onto_impl(impl_substs, tcx);
self.eq(
goal.param_env,
expected,
tcx.type_of(inherent.def_id).instantiate(tcx, inherent_substs),
)
.expect("expected goal term to be fully unconstrained");
// Check both where clauses on the impl and IAT
self.add_goals(
tcx.predicates_of(inherent.def_id)
.instantiate(tcx, inherent_substs)
.into_iter()
.map(|(pred, _)| goal.with(tcx, pred)),
);
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}
}

View file

@ -25,6 +25,7 @@ mod assembly;
mod canonicalize;
mod eval_ctxt;
mod fulfill;
mod inherent_projection;
pub mod inspect;
mod normalize;
mod opaques;

View file

@ -48,7 +48,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
self.merge_candidates(candidates)
}
ty::AssocItemContainer::ImplContainer => {
bug!("IATs not supported here yet")
self.normalize_inherent_associated_type(goal)
}
}
} else {
@ -112,6 +112,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
) -> QueryResult<'tcx> {
if let Some(projection_pred) = assumption.as_projection_clause() {
if projection_pred.projection_def_id() == goal.predicate.def_id() {
let tcx = ecx.tcx();
ecx.probe_candidate("assumption").enter(|ecx| {
let assumption_projection_pred =
ecx.instantiate_binder_with_infer(projection_pred);
@ -122,6 +123,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
)?;
ecx.eq(goal.param_env, goal.predicate.term, assumption_projection_pred.term)
.expect("expected goal term to be fully unconstrained");
// Add GAT where clauses from the trait's definition
ecx.add_goals(
tcx.predicates_of(goal.predicate.def_id())
.instantiate_own(tcx, goal.predicate.projection_ty.args)
.map(|(pred, _)| goal.with(tcx, pred)),
);
then(ecx)
})
} else {
@ -160,6 +169,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
.map(|pred| goal.with(tcx, pred));
ecx.add_goals(where_clause_bounds);
// Add GAT where clauses from the trait's definition
ecx.add_goals(
tcx.predicates_of(goal.predicate.def_id())
.instantiate_own(tcx, goal.predicate.projection_ty.args)
.map(|(pred, _)| goal.with(tcx, pred)),
);
// In case the associated item is hidden due to specialization, we have to
// return ambiguity this would otherwise be incomplete, resulting in
// unsoundness during coherence (#105782).

View file

@ -14,6 +14,16 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
let actual = tcx.type_of(weak_ty.def_id).instantiate(tcx, weak_ty.args);
self.eq(goal.param_env, expected, actual)?;
// Check where clauses
self.add_goals(
tcx.predicates_of(weak_ty.def_id)
.instantiate(tcx, weak_ty.args)
.predicates
.into_iter()
.map(|pred| goal.with(tcx, pred)),
);
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}
}

View file

@ -2388,14 +2388,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// If there is only one implementation of the trait, suggest using it.
// Otherwise, use a placeholder comment for the implementation.
let (message, impl_suggestion) = if non_blanket_impl_count == 1 {(
"use the fully-qualified path to the only available implementation".to_string(),
"use the fully-qualified path to the only available implementation",
format!("<{} as ", self.tcx.type_of(impl_def_id).instantiate_identity())
)} else {(
format!(
"use a fully-qualified path to a specific available implementation ({} found)",
non_blanket_impl_count
),
"</* self type */ as ".to_string()
)} else {
("use a fully-qualified path to a specific available implementation",
"</* self type */ as ".to_string()
)};
let mut suggestions = vec![(
path.span.shrink_to_lo(),

View file

@ -670,7 +670,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
stalled_on: &mut Vec<TyOrConstInferVar<'tcx>>,
) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
let infcx = self.selcx.infcx;
if obligation.predicate.is_global() {
if obligation.predicate.is_global() && !self.selcx.is_intercrate() {
// no type variables present, can use evaluation for better caching.
// FIXME: consider caching errors too.
if infcx.predicate_must_hold_considering_regions(obligation) {
@ -724,7 +724,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
let tcx = self.selcx.tcx();
if obligation.predicate.is_global() {
if obligation.predicate.is_global() && !self.selcx.is_intercrate() {
// no type variables present, can use evaluation for better caching.
// FIXME: consider caching errors too.
if self.selcx.infcx.predicate_must_hold_considering_regions(obligation) {

View file

@ -1402,9 +1402,17 @@ pub fn compute_inherent_assoc_ty_args<'a, 'b, 'tcx>(
let impl_def_id = tcx.parent(alias_ty.def_id);
let impl_args = selcx.infcx.fresh_args_for_item(cause.span, impl_def_id);
let impl_ty = tcx.type_of(impl_def_id).instantiate(tcx, impl_args);
let impl_ty =
normalize_with_depth_to(selcx, param_env, cause.clone(), depth + 1, impl_ty, obligations);
let mut impl_ty = tcx.type_of(impl_def_id).instantiate(tcx, impl_args);
if !selcx.infcx.next_trait_solver() {
impl_ty = normalize_with_depth_to(
selcx,
param_env,
cause.clone(),
depth + 1,
impl_ty,
obligations,
);
}
// Infer the generic parameters of the impl by unifying the
// impl type with the self type of the projection.
@ -1421,7 +1429,7 @@ pub fn compute_inherent_assoc_ty_args<'a, 'b, 'tcx>(
}
}
alias_ty.rebase_args_onto_impl(impl_args, tcx)
alias_ty.rebase_inherent_args_onto_impl(impl_args, tcx)
}
enum Projected<'tcx> {

View file

@ -570,7 +570,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
));
}
ty::ConstKind::Expr(_) => {
// FIXME(generic_const_exprs): this doesnt verify that given `Expr(N + 1)` the
// FIXME(generic_const_exprs): this doesn't verify that given `Expr(N + 1)` the
// trait bound `typeof(N): Add<typeof(1)>` holds. This is currently unnecessary
// as `ConstKind::Expr` is only produced via normalization of `ConstKind::Unevaluated`
// which means that the `DefId` would have been typeck'd elsewhere. However in

View file

@ -174,7 +174,7 @@ fn recurse_build<'tcx>(
}
// `ExprKind::Use` happens when a `hir::ExprKind::Cast` is a
// "coercion cast" i.e. using a coercion or is a no-op.
// This is important so that `N as usize as usize` doesnt unify with `N as usize`. (untested)
// This is important so that `N as usize as usize` doesn't unify with `N as usize`. (untested)
&ExprKind::Use { source } => {
let arg = recurse_build(tcx, body, source, root_span)?;
ty::Const::new_expr(tcx, Expr::Cast(CastKind::Use, arg, node.ty), node.ty)

View file

@ -311,22 +311,6 @@ fn param_env_reveal_all_normalized(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamE
tcx.param_env(def_id).with_reveal_all_normalized(tcx)
}
fn instance_def_size_estimate<'tcx>(
tcx: TyCtxt<'tcx>,
instance_def: ty::InstanceDef<'tcx>,
) -> usize {
use ty::InstanceDef;
match instance_def {
InstanceDef::Item(..) | InstanceDef::DropGlue(..) => {
let mir = tcx.instance_mir(instance_def);
mir.basic_blocks.iter().map(|bb| bb.statements.len() + 1).sum()
}
// Estimate the size of other compiler-generated shims to be 1.
_ => 1,
}
}
/// If `def_id` is an issue 33140 hack impl, returns its self type; otherwise, returns `None`.
///
/// See [`ty::ImplOverlapKind::Issue33140`] for more details.
@ -432,7 +416,6 @@ pub fn provide(providers: &mut Providers) {
adt_sized_constraint,
param_env,
param_env_reveal_all_normalized,
instance_def_size_estimate,
issue33140_self_ty,
defaultness,
unsizing_params_for_adt,

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -138,8 +138,6 @@ pub trait FromIterator<A>: Sized {
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let five_fives = std::iter::repeat(5).take(5);
///
@ -255,8 +253,6 @@ pub trait IntoIterator {
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let v = [1, 2, 3];
/// let mut iter = v.into_iter();
@ -363,8 +359,6 @@ pub trait Extend<A> {
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// // You can extend a String with some chars:
/// let mut message = String::from("abc");

View file

@ -749,7 +749,7 @@ impl<T, E> Result<T, E> {
}
/// Returns the provided default (if [`Err`]), or
/// applies a function to the contained value (if [`Ok`]),
/// applies a function to the contained value (if [`Ok`]).
///
/// Arguments passed to `map_or` are eagerly evaluated; if you are passing
/// the result of a function call, it is recommended to use [`map_or_else`],

View file

@ -2957,7 +2957,7 @@ impl<T> [T] {
/// elements.
///
/// This sort is unstable (i.e., may reorder equal elements), in-place
/// (i.e., does not allocate), and *O*(m \* *n* \* log(*n*)) worst-case, where the key function is
/// (i.e., does not allocate), and *O*(*m* \* *n* \* log(*n*)) worst-case, where the key function is
/// *O*(*m*).
///
/// # Current implementation

View file

@ -1056,6 +1056,9 @@ fn supported_sanitizers(
"s390x-unknown-linux-musl" => {
common_libs("linux", "s390x", &["asan", "lsan", "msan", "tsan"])
}
"x86_64-unknown-linux-ohos" => {
common_libs("linux", "x86_64", &["asan", "lsan", "msan", "tsan"])
}
_ => Vec::new(),
}
}

View file

@ -17,6 +17,9 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-ins
xz-utils \
&& rm -rf /var/lib/apt/lists/*
COPY scripts/cmake.sh /scripts/
RUN /scripts/cmake.sh
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

View file

@ -13,6 +13,7 @@ RUN apt-get update -y && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-
git \
libc6-dev \
libc6-dev-armhf-cross \
libssl-dev \
make \
ninja-build \
python3 \
@ -75,6 +76,9 @@ RUN arm-linux-gnueabihf-gcc addentropy.c -o rootfs/addentropy -static
# Source of the file: https://github.com/vfdev-5/qemu-rpi2-vexpress/raw/master/vexpress-v2p-ca15-tc1.dtb
RUN curl -O https://ci-mirrors.rust-lang.org/rustc/vexpress-v2p-ca15-tc1.dtb
COPY scripts/cmake.sh /scripts/
RUN /scripts/cmake.sh
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

View file

@ -16,6 +16,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
libssl-dev \
pkg-config
COPY scripts/cmake.sh /scripts/
RUN /scripts/cmake.sh
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

View file

@ -19,6 +19,7 @@ RUN apt-get update -y && apt-get install -y --no-install-recommends \
g++ \
libc6-dev \
libc6-dev-riscv64-cross \
libssl-dev \
make \
ninja-build \
patch \
@ -94,6 +95,9 @@ RUN mkdir build && cd build && \
WORKDIR /tmp
RUN rm -rf /tmp/riscv-pk
COPY scripts/cmake.sh /scripts/
RUN /scripts/cmake.sh
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

View file

@ -48,6 +48,9 @@ COPY host-x86_64/dist-x86_64-linux/shared.sh /tmp/
COPY host-x86_64/dist-x86_64-linux/build-gcc.sh /tmp/
RUN ./build-gcc.sh && yum remove -y gcc gcc-c++
COPY scripts/cmake.sh /tmp/
RUN ./cmake.sh
# Now build LLVM+Clang, afterwards configuring further compilations to use the
# clang/clang++ compilers.
COPY host-x86_64/dist-x86_64-linux/build-clang.sh /tmp/

View file

@ -14,6 +14,9 @@ RUN apt-get install -y --no-install-recommends rpm2cpio cpio
COPY host-x86_64/dist-powerpc64le-linux/shared.sh host-x86_64/dist-powerpc64le-linux/build-powerpc64le-toolchain.sh /tmp/
RUN ./build-powerpc64le-toolchain.sh
COPY scripts/cmake.sh /scripts/
RUN /scripts/cmake.sh
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

View file

@ -186,6 +186,9 @@ ENV SCRIPT \
python3 ../x.py --stage 2 test --host='' --target $RUN_MAKE_TARGETS tests/run-make && \
python3 ../x.py dist --host='' --target $TARGETS
COPY scripts/cmake.sh /scripts/
RUN /scripts/cmake.sh
# sccache
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

View file

@ -96,6 +96,9 @@ RUN /tmp/build-wasi-toolchain.sh
COPY scripts/freebsd-toolchain.sh /tmp/
RUN /tmp/freebsd-toolchain.sh i686
COPY scripts/cmake.sh /scripts/
RUN /scripts/cmake.sh
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

View file

@ -48,6 +48,10 @@ COPY host-x86_64/dist-x86_64-linux/shared.sh /tmp/
COPY host-x86_64/dist-x86_64-linux/build-gcc.sh /tmp/
RUN ./build-gcc.sh && yum remove -y gcc gcc-c++
# LLVM 17 needs cmake 3.20 or higher.
COPY scripts/cmake.sh /tmp/
RUN ./cmake.sh
# Now build LLVM+Clang, afterwards configuring further compilations to use the
# clang/clang++ compilers.
COPY host-x86_64/dist-x86_64-linux/build-clang.sh /tmp/

View file

@ -7,6 +7,9 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get install -y zlib1g-dev
COPY host-x86_64/dist-x86_64-netbsd/build-netbsd-toolchain.sh /tmp/
RUN /tmp/build-netbsd-toolchain.sh
COPY scripts/cmake.sh /scripts/
RUN /scripts/cmake.sh
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

View file

@ -37,6 +37,9 @@ COPY scripts/musl-toolchain.sh /build/
RUN bash musl-toolchain.sh x86_64 && rm -rf build
WORKDIR /
COPY scripts/cmake.sh /scripts/
RUN /scripts/cmake.sh
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

View file

@ -13,12 +13,16 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-ins
sudo \
gdb \
xz-utils \
libssl-dev \
bzip2 \
&& rm -rf /var/lib/apt/lists/*
COPY scripts/emscripten.sh /scripts/
RUN bash /scripts/emscripten.sh
COPY scripts/cmake.sh /scripts/
RUN /scripts/cmake.sh
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

View file

@ -26,6 +26,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
clang \
&& rm -rf /var/lib/apt/lists/*
COPY scripts/cmake.sh /scripts/
RUN /scripts/cmake.sh
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

View file

@ -18,6 +18,9 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-ins
xz-utils \
&& rm -rf /var/lib/apt/lists/*
COPY scripts/cmake.sh /scripts/
RUN /scripts/cmake.sh
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

View file

@ -19,6 +19,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
mingw-w64 \
&& rm -rf /var/lib/apt/lists/*
COPY scripts/cmake.sh /scripts/
RUN /scripts/cmake.sh
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

View file

@ -18,9 +18,9 @@ exit 1
set -x
}
# LLVM 12 requires CMake 3.13.4 or higher.
# This script is not necessary for images using Ubuntu 20.04 or newer.
CMAKE=3.13.4
# LLVM 17 requires CMake 3.20 or higher.
# This script is not necessary for images using Ubuntu 22.04 or newer.
CMAKE=3.20.3
curl -L https://github.com/Kitware/CMake/releases/download/v$CMAKE/cmake-$CMAKE.tar.gz | tar xzf -
mkdir cmake-build

View file

@ -36,8 +36,10 @@
- [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md)
- [mips64-openwrt-linux-musl](platform-support/mips64-openwrt-linux-musl.md)
- [mipsel-sony-psx](platform-support/mipsel-sony-psx.md)
- [mipsisa\*r6\*-unknown-linux-gnu\*](platform-support/mips-release-6.md)
- [nvptx64-nvidia-cuda](platform-support/nvptx64-nvidia-cuda.md)
- [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md)
- [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md)
- [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md)
- [\*-nto-qnx-\*](platform-support/nto-qnx.md)
- [\*-unknown-netbsd\*](platform-support/netbsd.md)

View file

@ -176,6 +176,7 @@ target | std | notes
`thumbv8m.base-none-eabi` | * | Bare ARMv8-M Baseline
`thumbv8m.main-none-eabi` | * | Bare ARMv8-M Mainline
`thumbv8m.main-none-eabihf` | * | Bare ARMv8-M Mainline, hardfloat
[`sparc-unknown-none-elf`](./platform-support/sparc-unknown-none-elf.md) | * | Bare 32-bit SPARC V7+
`wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten
`wasm32-unknown-unknown` | ✓ | WebAssembly
`wasm32-wasi` | ✓ | WebAssembly with WASI
@ -277,10 +278,10 @@ target | std | host | notes
[`mipsel-sony-psx`](platform-support/mipsel-sony-psx.md) | * | | MIPS (LE) Sony PlayStation 1 (PSX)
`mipsel-unknown-linux-uclibc` | ✓ | | MIPS (LE) Linux with uClibc
`mipsel-unknown-none` | * | | Bare MIPS (LE) softfloat
`mipsisa32r6-unknown-linux-gnu` | ? | |
`mipsisa32r6el-unknown-linux-gnu` | ? | |
`mipsisa64r6-unknown-linux-gnuabi64` | ? | |
`mipsisa64r6el-unknown-linux-gnuabi64` | ? | |
[`mipsisa32r6-unknown-linux-gnu`](platform-support/mips-release-6.md) | ? | | 32-bit MIPS Release 6 Big Endian
[`mipsisa32r6el-unknown-linux-gnu`](platform-support/mips-release-6.md) | ? | | 32-bit MIPS Release 6 Little Endian
[`mipsisa64r6-unknown-linux-gnuabi64`](platform-support/mips-release-6.md) | ? | | 64-bit MIPS Release 6 Big Endian
[`mipsisa64r6el-unknown-linux-gnuabi64`](platform-support/mips-release-6.md) | ✓ | ✓ | 64-bit MIPS Release 6 Little Endian
`msp430-none-elf` | * | | 16-bit MSP430 microcontrollers
`powerpc-unknown-linux-gnuspe` | ✓ | | PowerPC SPE Linux
`powerpc-unknown-linux-musl` | ? | |
@ -305,7 +306,7 @@ target | std | host | notes
`riscv64gc-unknown-freebsd` | | | RISC-V FreeBSD
`riscv64gc-unknown-fuchsia` | | | RISC-V Fuchsia
`riscv64gc-unknown-linux-musl` | | | RISC-V Linux (kernel 4.20, musl 1.2.0)
[`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ? | RISC-V NetBSD
[`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | | RISC-V NetBSD
[`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64
`s390x-unknown-linux-musl` | | | S390x Linux (kernel 3.2, MUSL)
`sparc-unknown-linux-gnu` | ✓ | | 32-bit SPARC Linux
@ -328,6 +329,7 @@ target | std | host | notes
`x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku
`x86_64-unknown-hermit` | ✓ | | HermitCore
`x86_64-unknown-l4re-uclibc` | ? | |
[`x86_64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | | x86_64 OpenHarmony |
[`x86_64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 64-bit OpenBSD
`x86_64-uwp-windows-gnu` | ✓ | |
`x86_64-uwp-windows-msvc` | ✓ | |

View file

@ -0,0 +1,181 @@
# mipsisa\*r6\*-unknown-linux-gnu\*
**Tier: 3**
[MIPS Release 6](https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00083-2B-MIPS64INT-AFP-06.01.pdf), or simply MIPS R6, is the latest iteration of the MIPS instruction set architecture (ISA).
MIPS R6 is experimental in nature, as there is not yet real hardware. However, Qemu emulation is available and we have two Linux distros maintained for development and evaluation purposes. This documentation describes the Rust support for MIPS R6 targets under `mipsisa*r6*-unknown-linux-gnu*`.
The target name follow this format: `<machine>-<vendor>-<os><abi_suffix>`, where `<machine>` specifies the CPU family/model, `<vendor>` specifies the vendor and `<os>` the operating system name. The `<abi_suffix>` denotes the base ABI (32/n32/64/o64).
| ABI suffix | Description |
|------------|------------------------------------|
| abi64 | Uses the 64-bit (64) ABI |
| abin32 | Uses the n32 ABI |
| N/A | Uses the (assumed) 32-bit (32) ABI |
## Target Maintainers
- [Xuan Chen](https://github.com/chenx97) <henry.chen@oss.cipunited.com>
- [Walter Ji](https://github.com/709924470) <walter.ji@oss.cipunited.com>
- [Xinhui Yang](https://github.com/Cyanoxygen) <cyan@oss.cipunited.com>
- [Lain Yang](https://github.com/Fearyncess) <lain.yang@oss.cipunited.com>
## Requirements
### C/C++ Toolchain
A GNU toolchain for one of the MIPS R6 target is required. [AOSC OS](https://aosc.io/) provides working native and cross-compiling build environments. You may also supply your own a toolchain consisting of recent versions of GCC and Binutils.
### Target libraries
A minimum set of libraries is required to perform dynamic linking:
- GNU glibc
- OpenSSL
- Zlib
- Linux API Headers
This set of libraries should be installed to make up minimal target sysroot.
For AOSC OS, You may install such a sysroot with the following commands:
```sh
cd /tmp
# linux+api, glibc, and file system structure are included in the toolchain.
sudo apt install gcc+cross-mips64r6el binutils+cross-mips64r6el
# Download and extract required libraries.
wget https://repo.aosc.io/debs/pool/stable/main/z/zlib_1.2.13-0_mips64r6el.deb -O zlib.deb
wget https://repo.aosc.io/debs/pool/stable/main/o/openssl_1.1.1q-1_mips64r6el.deb -O openssl.deb
# Extract them to your desired location.
for i in zlib openssl ; do
sudo dpkg-deb -vx $i.deb /var/ab/cross-root/mips64r6el
done
# Workaround a possible ld bug when using -Wl,-Bdynamic.
sudo sed -i 's|/usr|=/usr|g' /var/ab/cross-root/mips64r6el/usr/lib/libc.so
```
For other distros, you may build them manually.
## Building
The following procedure outlines the build process for the MIPS64 R6 target with 64-bit (64) ABI (`mipsisa64r6el-unknown-linux-gnuabi64`).
### Prerequisite: Disable debuginfo
A LLVM bug makes rustc crash if debug or debug info generation is enabled. You need to edit `config.toml` to disable this:
```toml
[rust]
debug = false
debug-info-level = 0
```
### Prerequisite: Enable rustix's libc backend
The crate `rustix` may try to link itself against MIPS R2 assembly, resulting in linkage error. To avoid this, you may force `rustix` to use its fallback `libc` backend by setting relevant `RUSTFLAGS`:
```sh
export RUSTFLAGS="--cfg rustix_use_libc"
```
This will trigger warnings during build, as `-D warnings` is enabled by default. Disable `-D warnings` by editing `config.toml` to append the following:
```toml
[rust]
deny-warnings = false
```
### Prerequisite: Supplying OpenSSL
As a Tier 3 target, `openssl_sys` lacks the vendored OpenSSL library for this target. You will need to provide a prebuilt OpenSSL library to link `cargo`. Since we have a pre-configured sysroot, we can point to it directly:
```sh
export MIPSISA64R6EL_UNKNOWN_LINUX_GNUABI64_OPENSSL_NO_VENDOR=y
export MIPSISA64R6EL_UNKNOWN_LINUX_GNUABI64_OPENSSL_DIR="/var/ab/cross-root/mips64r6el/usr"
```
On Debian, you may need to provide library path and include path separately:
```sh
export MIPSISA64R6EL_UNKNOWN_LINUX_GNUABI64_OPENSSL_NO_VENDOR=y
export MIPSISA64R6EL_UNKNOWN_LINUX_GNUABI64_OPENSSL_LIB_DIR="/usr/lib/mipsisa64r6el-linux-gnuabi64/"
export MIPSISA64R6EL_UNKNOWN_LINUX_GNUABI64_OPENSSL_INCLUDE_DIR="/usr/include"
```
### Launching `x.py`
```toml
[build]
target = ["mipsisa64r6el-unknown-linux-gnuabi64"]
```
Make sure that `mipsisa64r6el-unknown-linux-gnuabi64-gcc` is available from your executable search path (`$PATH`).
Alternatively, you can specify the directories to all necessary toolchain executables in `config.toml`:
```toml
[target.mipsisa64r6el-unknown-linux-gnuabi64]
# Adjust the paths below to point to your toolchain installation prefix.
cc = "/toolchain_prefix/bin/mipsisa64r6el-unknown-linux-gnuabi64-gcc"
cxx = "/toolchain_prefix/bin/mipsisa64r6el-unknown-linux-gnuabi64-g++"
ar = "/toolchain_prefix/bin/mipsisa64r6el-unknown-linux-gnuabi64-gcc-ar"
ranlib = "/toolchain_prefix/bin/mipsisa64r6el-unknown-linux-gnuabi64-ranlib"
linker = "/toolchain_prefix/bin/mipsisa64r6el-unknown-linux-gnuabi64-gcc"
```
Or, you can specify your cross compiler toolchain with an environment variable:
```sh
export CROSS_COMPILE="/opt/abcross/mips64r6el/bin/mipsisa64r6el-aosc-linux-gnuabi64-"
```
Finally, launch the build script:
```sh
./x.py build
```
### Tips
- Avoid setting `cargo-native-static` to `false`, as this will result in a redundant artifact error while building clippy:
```text
duplicate artifacts found when compiling a tool, this typically means that something was recompiled because a transitive dependency has different features activated than in a previous build:
the following dependencies have different features:
syn 2.0.8 (registry+https://github.com/rust-lang/crates.io-index)
`clippy-driver` additionally enabled features {"full"} at ...
`cargo` additionally enabled features {} at ...
to fix this you will probably want to edit the local src/tools/rustc-workspace-hack/Cargo.toml crate, as that will update the dependency graph to ensure that these crates all share the same feature set
thread 'main' panicked at 'tools should not compile multiple copies of the same crate', tool.rs:250:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```
## Building Rust programs
To build Rust programs for MIPS R6 targets, for instance, the `mipsisa64r6el-unknown-linux-gnuabi64` target:
```bash
cargo build --target mipsisa64r6el-unknown-linux-gnuabi64
```
## Testing
To test a cross-compiled binary on your build system, install the Qemu user emulator that support the MIPS R6 architecture (`qemu-user-mipsel` or `qemu-user-mips64el`). GCC runtime libraries (`libgcc_s`) for the target architecture should be present in target sysroot to run the program.
```sh
env \
CARGO_TARGET_MIPSISA64R6EL_UNKNOWN_LINUX_GNUABI64_LINKER="/opt/abcross/mips64r6el/bin/mipsisa64r6el-aosc-linux-gnuabi64-gcc" \
CARGO_TARGET_MIPSISA64R6EL_UNKNOWN_LINUX_GNUABI64_RUNNER="qemu-mips64el-static -L /var/ab/cross-root/mips64r6el" \
cargo run --release \
--target mipsisa64r6el-unknown-linux-gnuabi64
```
## Tips for building Rust programs for MIPS R6
- Until we finalize a fix, please make sure the aforementioned workarounds for `rustix` crate and LLVM are always applied. This can be achieved by setting the relevant environment variables, and editing `Cargo.toml` before building.

View file

@ -71,6 +71,28 @@ exec /path/to/ohos-sdk/linux/native/llvm/bin/clang++ \
"$@"
```
`x86_64-unknown-linux-ohos-clang.sh`
```sh
#!/bin/sh
exec /path/to/ohos-sdk/linux/native/llvm/bin/clang \
-target x86_64-linux-ohos \
--sysroot=/path/to/ohos-sdk/linux/native/sysroot \
-D__MUSL__ \
"$@"
```
`x86_64-unknown-linux-ohos-clang++.sh`
```sh
#!/bin/sh
exec /path/to/ohos-sdk/linux/native/llvm/bin/clang++ \
-target x86_64-linux-ohos \
--sysroot=/path/to/ohos-sdk/linux/native/sysroot \
-D__MUSL__ \
"$@"
```
Future versions of the OpenHarmony SDK will avoid the need for this process.
## Building the target
@ -98,6 +120,13 @@ cxx = "/path/to/armv7-unknown-linux-ohos-clang++.sh"
ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar"
ranlib = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ranlib"
linker = "/path/to/armv7-unknown-linux-ohos-clang.sh"
[target.x86_64-unknown-linux-ohos]
cc = "/path/to/x86_64-unknown-linux-ohos-clang.sh"
cxx = "/path/to/x86_64-unknown-linux-ohos-clang++.sh"
ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar"
ranlib = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ranlib"
linker = "/path/to/x86_64-unknown-linux-ohos-clang.sh"
```
## Building Rust programs
@ -116,6 +145,10 @@ linker = "/path/to/aarch64-unknown-linux-ohos-clang.sh"
[target.armv7-unknown-linux-ohos]
ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar"
linker = "/path/to/armv7-unknown-linux-ohos-clang.sh"
[target.x86_64-unknown-linux-ohos]
ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar"
linker = "/path/to/x86_64-unknown-linux-ohos-clang.sh"
```
## Testing

View file

@ -0,0 +1,164 @@
# `sparc-unknown-none-elf`
**Tier: 3**
Rust for bare-metal 32-bit SPARC V7 and V8 systems, e.g. the Gaisler LEON3.
| Target | Descriptions |
| ---------------------- | ----------------------------------------- |
| sparc-unknown-none-elf | SPARC V7 32-bit (freestanding, hardfloat) |
## Target maintainers
- Jonathan Pallant, <jonathan.pallant@ferrous-systems.com>, https://ferrous-systems.com
## Requirements
This target is cross-compiled. There is no support for `std`. There is no
default allocator, but it's possible to use `alloc` by supplying an allocator.
This allows the generated code to run in environments, such as kernels, which
may need to avoid the use of such registers or which may have special
considerations about the use of such registers (e.g. saving and restoring them
to avoid breaking userspace code using the same registers). You can change code
generation to use additional CPU features via the `-C target-feature=` codegen
options to rustc, or via the `#[target_feature]` mechanism within Rust code.
By default, code generated with this target should run on any `SPARC` hardware;
enabling additional target features may raise this baseline.
- `-Ctarget-cpu=v8` adds the extra SPARC V8 instructions.
- `-Ctarget-cpu=leon3` adds the SPARC V8 instructions and sets up scheduling to
suit the Gaisler Leon3.
Functions marked `extern "C"` use the [standard SPARC architecture calling
convention](https://sparc.org/technical-documents/).
This target generates ELF binaries. Any alternate formats or special
considerations for binary layout will require linker options or linker scripts.
## Building the target
You can build Rust with support for the target by adding it to the `target`
list in `config.toml`:
```toml
[build]
build-stage = 1
target = ["sparc-unknown-none-elf"]
```
## Building Rust programs
```text
cargo build --target sparc-unknown-none-elf
```
This target uses GCC as a linker, and so you will need an appropriate GCC
compatible `sparc-unknown-none` toolchain.
The default linker name is `sparc-elf-gcc`, but you can override this in your
project configuration.
## Testing
As `sparc-unknown-none-elf` supports a variety of different environments and does
not support `std`, this target does not support running the Rust test suite.
## Cross-compilation toolchains and C code
This target was initially tested using [BCC2] from Gaisler, along with the TSIM
Leon3 processor simulator. Both [BCC2] GCC and [BCC2] Clang have been shown to
work. To work with these tools, your project configuration should contain
something like:
[BCC2]: https://www.gaisler.com/index.php/downloads/compilers
`.cargo/config.toml`:
```toml
[target.sparc-unknown-none-elf]
linker = "sparc-gaisler-elf-gcc"
runner = "tsim-leon3"
[build]
target = ["sparc-unknown-none-elf"]
rustflags = "-Ctarget-cpu=leon3"
[unstable]
build-std = ["core"]
```
With this configuration, running `cargo run` will compile your code for the
SPARC V8 compatible Gaisler Leon3 processor and then start the `tsim-leon3`
simulator. Once the simulator is running, simply enter the command
`run` to start the code executing in the simulator.
The default C toolchain libraries are linked in, so with the Gaisler [BCC2]
toolchain, and using its default Leon3 BSP, you can use call the C `putchar`
function and friends to output to the simulator console.
Here's a complete example:
```rust,ignore (cannot-test-this-because-it-assumes-special-libc-functions)
#![no_std]
#![no_main]
extern "C" {
fn putchar(ch: i32);
fn _exit(code: i32) -> !;
}
#[no_mangle]
extern "C" fn main() -> i32 {
let message = "Hello, this is Rust!";
for b in message.bytes() {
unsafe {
putchar(b as i32);
}
}
0
}
#[panic_handler]
fn panic(_panic: &core::panic::PanicInfo) -> ! {
unsafe {
_exit(1);
}
}
```
```console
$ cargo run --target=sparc-unknown-none-elf
Compiling sparc-demo-rust v0.1.0 (/work/sparc-demo-rust)
Finished dev [unoptimized + debuginfo] target(s) in 3.44s
Running `tsim-leon3 target/sparc-unknown-none-elf/debug/sparc-demo-rust`
TSIM3 LEON3 SPARC simulator, version 3.1.9 (evaluation version)
Copyright (C) 2023, Frontgrade Gaisler - all rights reserved.
This software may only be used with a valid license.
For latest updates, go to https://www.gaisler.com/
Comments or bug-reports to support@gaisler.com
This TSIM evaluation version will expire 2023-11-28
Number of CPUs: 2
system frequency: 50.000 MHz
icache: 1 * 4 KiB, 16 bytes/line (4 KiB total)
dcache: 1 * 4 KiB, 16 bytes/line (4 KiB total)
Allocated 8192 KiB SRAM memory, in 1 bank at 0x40000000
Allocated 32 MiB SDRAM memory, in 1 bank at 0x60000000
Allocated 8192 KiB ROM memory at 0x00000000
section: .text, addr: 0x40000000, size: 20528 bytes
section: .rodata, addr: 0x40005030, size: 128 bytes
section: .data, addr: 0x400050b0, size: 1176 bytes
read 347 symbols
tsim> run
Initializing and starting from 0x40000000
Hello, this is Rust!
Program exited normally on CPU 0.
tsim>
```

View file

@ -37,7 +37,7 @@ top, with no contents.
## Configuring rustdoc
There are two problems with this: first, why does it
think that our package is named "lib"? Second, why does it not have any
think that our crate is named "lib"? Second, why does it not have any
contents?
The first problem is due to `rustdoc` trying to be helpful; like `rustc`,

View file

@ -66,7 +66,10 @@
dyn pointees.
Rc<[T]> and Arc<[T]> are handled separately altogether so we can actually show
the slice values.
the slice values. These visualizers have a second wildcard `foo&lt;slice2$&lt;*&gt;, *&gt;`
which accounts for the allocator parameter. This isn't needed for the other visualizers since
their inner `*` eats the type parameter but since the slice ones match part of the type params
it is necessary for them.
-->
<!-- alloc::rc::Rc<T> -->
<Type Name="alloc::rc::Rc&lt;*&gt;">
@ -84,7 +87,7 @@
</Type>
<!-- alloc::rc::Rc<[T]> -->
<Type Name="alloc::rc::Rc&lt;slice2$&lt;*&gt; &gt;">
<Type Name="alloc::rc::Rc&lt;slice2$&lt;*&gt;,*&gt;">
<DisplayString>{{ len={ptr.pointer.length} }}</DisplayString>
<Expand>
<Item Name="[Length]" ExcludeView="simple">ptr.pointer.length</Item>
@ -114,7 +117,7 @@
</Type>
<!-- alloc::rc::Weak<[T]> -->
<Type Name="alloc::rc::Weak&lt;slice2$&lt;*&gt; &gt;">
<Type Name="alloc::rc::Weak&lt;slice2$&lt;*&gt;,*&gt;">
<DisplayString>{{ len={ptr.pointer.length} }}</DisplayString>
<Expand>
<Item Name="[Length]" ExcludeView="simple">ptr.pointer.length</Item>
@ -143,7 +146,7 @@
</Type>
<!-- alloc::sync::Arc<[T]> -->
<Type Name="alloc::sync::Arc&lt;slice2$&lt;*&gt; &gt;">
<Type Name="alloc::sync::Arc&lt;slice2$&lt;*&gt;,*&gt;">
<DisplayString>{{ len={ptr.pointer.length} }}</DisplayString>
<Expand>
<Item Name="[Length]" ExcludeView="simple">ptr.pointer.length</Item>
@ -172,7 +175,7 @@
</Type>
<!-- alloc::sync::Weak<[T]> -->
<Type Name="alloc::sync::Weak&lt;slice2$&lt;*&gt; &gt;">
<Type Name="alloc::sync::Weak&lt;slice2$&lt;*&gt;,*&gt;">
<DisplayString>{{ len={ptr.pointer.length} }}</DisplayString>
<Expand>
<Item Name="[Length]" ExcludeView="simple">ptr.pointer.length</Item>

View file

@ -473,7 +473,7 @@ pub(crate) fn build_impl(
associated_trait.def_id,
)
.unwrap(); // corresponding associated item has to exist
!tcx.is_doc_hidden(trait_item.def_id)
document_hidden || !tcx.is_doc_hidden(trait_item.def_id)
} else {
item.visibility(tcx).is_public()
}
@ -496,7 +496,7 @@ pub(crate) fn build_impl(
let mut stack: Vec<&Type> = vec![&for_];
if let Some(did) = trait_.as_ref().map(|t| t.def_id()) {
if tcx.is_doc_hidden(did) {
if !document_hidden && tcx.is_doc_hidden(did) {
return;
}
}
@ -505,7 +505,7 @@ pub(crate) fn build_impl(
}
while let Some(ty) = stack.pop() {
if let Some(did) = ty.def_id(&cx.cache) && tcx.is_doc_hidden(did) {
if let Some(did) = ty.def_id(&cx.cache) && !document_hidden && tcx.is_doc_hidden(did) {
return;
}
if let Some(generics) = ty.generics() {

View file

@ -53,7 +53,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
let mut inserted = FxHashSet::default();
items.extend(doc.foreigns.iter().map(|(item, renamed)| {
let item = clean_maybe_renamed_foreign_item(cx, item, *renamed);
if let Some(name) = item.name && !item.is_doc_hidden() {
if let Some(name) = item.name && (cx.render_options.document_hidden || !item.is_doc_hidden()) {
inserted.insert((item.type_(), name));
}
item
@ -63,7 +63,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
return None;
}
let item = clean_doc_module(x, cx);
if item.is_doc_hidden() {
if !cx.render_options.document_hidden && item.is_doc_hidden() {
// Hidden modules are stripped at a later stage.
// If a hidden module has the same name as a visible one, we want
// to keep both of them around.
@ -84,7 +84,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
}
let v = clean_maybe_renamed_item(cx, item, *renamed, *import_id);
for item in &v {
if let Some(name) = item.name && !item.is_doc_hidden() {
if let Some(name) = item.name && (cx.render_options.document_hidden || !item.is_doc_hidden()) {
inserted.insert((item.type_(), name));
}
}
@ -2326,7 +2326,7 @@ fn get_all_import_attributes<'hir>(
attrs = import_attrs.iter().map(|attr| (Cow::Borrowed(attr), Some(def_id))).collect();
first = false;
// We don't add attributes of an intermediate re-export if it has `#[doc(hidden)]`.
} else if !cx.tcx.is_doc_hidden(def_id) {
} else if cx.render_options.document_hidden || !cx.tcx.is_doc_hidden(def_id) {
add_without_unwanted_attributes(&mut attrs, import_attrs, is_inline, Some(def_id));
}
}

View file

@ -73,7 +73,7 @@ fn should_not_trim() {
fn is_same_generic() {
use crate::clean::types::{PrimitiveType, Type};
use crate::formats::cache::Cache;
let cache = Cache::new(false);
let cache = Cache::new(false, false);
let generic = Type::Generic(rustc_span::symbol::sym::Any);
let unit = Type::Primitive(PrimitiveType::Unit);
assert!(!generic.is_doc_subtype_of(&unit, &cache));

View file

@ -345,7 +345,7 @@ pub(crate) fn run_global_ctxt(
impl_trait_bounds: Default::default(),
generated_synthetics: Default::default(),
auto_traits,
cache: Cache::new(render_options.document_private),
cache: Cache::new(render_options.document_private, render_options.document_hidden),
inlined: FxHashSet::default(),
output_format,
render_options,

View file

@ -86,6 +86,9 @@ pub(crate) struct Cache {
/// Whether to document private items.
/// This is stored in `Cache` so it doesn't need to be passed through all rustdoc functions.
pub(crate) document_private: bool,
/// Whether to document hidden items.
/// This is stored in `Cache` so it doesn't need to be passed through all rustdoc functions.
pub(crate) document_hidden: bool,
/// Crates marked with [`#[doc(masked)]`][doc_masked].
///
@ -137,8 +140,8 @@ struct CacheBuilder<'a, 'tcx> {
}
impl Cache {
pub(crate) fn new(document_private: bool) -> Self {
Cache { document_private, ..Cache::default() }
pub(crate) fn new(document_private: bool, document_hidden: bool) -> Self {
Cache { document_private, document_hidden, ..Cache::default() }
}
/// Populates the `Cache` with more data. The returned `Crate` will be missing some data that was

View file

@ -798,7 +798,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
if let Some(def_id) = item.def_id() && self.cache().inlined_items.contains(&def_id) {
self.is_inside_inlined_module = true;
}
} else if item.is_doc_hidden() {
} else if !self.cache().document_hidden && item.is_doc_hidden() {
// We're not inside an inlined module anymore since this one cannot be re-exported.
self.is_inside_inlined_module = false;
}

View file

@ -92,8 +92,8 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -
return false;
}
if cx.tcx.is_doc_hidden(def_id.to_def_id())
|| inherits_doc_hidden(cx.tcx, def_id, None)
if (!cx.render_options.document_hidden
&& (cx.tcx.is_doc_hidden(def_id.to_def_id()) || inherits_doc_hidden(cx.tcx, def_id, None)))
|| cx.tcx.def_span(def_id.to_def_id()).in_derive_expansion()
{
return false;

View file

@ -42,6 +42,7 @@ pub(crate) fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clea
cache: &cx.cache,
is_json_output,
document_private: cx.render_options.document_private,
document_hidden: cx.render_options.document_hidden,
};
stripper.fold_crate(krate)
}

View file

@ -13,5 +13,10 @@ pub(crate) const STRIP_PRIV_IMPORTS: Pass = Pass {
pub(crate) fn strip_priv_imports(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate {
let is_json_output = cx.output_format.is_json() && !cx.show_coverage;
ImportStripper { tcx: cx.tcx, is_json_output }.fold_crate(krate)
ImportStripper {
tcx: cx.tcx,
is_json_output,
document_hidden: cx.render_options.document_hidden,
}
.fold_crate(krate)
}

View file

@ -28,8 +28,12 @@ pub(crate) fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) ->
is_json_output,
tcx: cx.tcx,
};
krate =
ImportStripper { tcx: cx.tcx, is_json_output }.fold_crate(stripper.fold_crate(krate));
krate = ImportStripper {
tcx: cx.tcx,
is_json_output,
document_hidden: cx.render_options.document_hidden,
}
.fold_crate(stripper.fold_crate(krate));
}
// strip all impls referencing private items
@ -39,6 +43,7 @@ pub(crate) fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) ->
cache: &cx.cache,
is_json_output,
document_private: cx.render_options.document_private,
document_hidden: cx.render_options.document_hidden,
};
stripper.fold_crate(krate)
}

View file

@ -6,6 +6,7 @@ use std::mem;
use crate::clean::{self, Item, ItemId, ItemIdSet};
use crate::fold::{strip_item, DocFolder};
use crate::formats::cache::Cache;
use crate::visit_ast::inherits_doc_hidden;
use crate::visit_lib::RustdocEffectiveVisibilities;
pub(crate) struct Stripper<'a, 'tcx> {
@ -151,6 +152,7 @@ pub(crate) struct ImplStripper<'a, 'tcx> {
pub(crate) cache: &'a Cache,
pub(crate) is_json_output: bool,
pub(crate) document_private: bool,
pub(crate) document_hidden: bool,
}
impl<'a> ImplStripper<'a, '_> {
@ -162,7 +164,13 @@ impl<'a> ImplStripper<'a, '_> {
// If the "for" item is exported and the impl block isn't `#[doc(hidden)]`, then we
// need to keep it.
self.cache.effective_visibilities.is_exported(self.tcx, for_def_id)
&& !item.is_doc_hidden()
&& (self.document_hidden
|| ((!item.is_doc_hidden()
&& for_def_id
.as_local()
.map(|def_id| !inherits_doc_hidden(self.tcx, def_id, None))
.unwrap_or(true))
|| self.cache.inlined_items.contains(&for_def_id)))
} else {
false
}
@ -231,6 +239,7 @@ impl<'a> DocFolder for ImplStripper<'a, '_> {
pub(crate) struct ImportStripper<'tcx> {
pub(crate) tcx: TyCtxt<'tcx>,
pub(crate) is_json_output: bool,
pub(crate) document_hidden: bool,
}
impl<'tcx> ImportStripper<'tcx> {
@ -247,8 +256,12 @@ impl<'tcx> ImportStripper<'tcx> {
impl<'tcx> DocFolder for ImportStripper<'tcx> {
fn fold_item(&mut self, i: Item) -> Option<Item> {
match *i.kind {
clean::ImportItem(imp) if self.import_should_be_hidden(&i, &imp) => None,
clean::ImportItem(_) if i.is_doc_hidden() => None,
clean::ImportItem(imp)
if !self.document_hidden && self.import_should_be_hidden(&i, &imp) =>
{
None
}
// clean::ImportItem(_) if !self.document_hidden && i.is_doc_hidden() => None,
clean::ExternCrateItem { .. } | clean::ImportItem(..)
if i.visibility(self.tcx) != Some(Visibility::Public) =>
{

View file

@ -262,10 +262,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
return false;
};
let document_hidden = self.cx.render_options.document_hidden;
let use_attrs = tcx.hir().attrs(tcx.hir().local_def_id_to_hir_id(def_id));
// Don't inline `doc(hidden)` imports so they can be stripped at a later stage.
let is_no_inline = use_attrs.lists(sym::doc).has_word(sym::no_inline)
|| use_attrs.lists(sym::doc).has_word(sym::hidden);
|| (document_hidden && use_attrs.lists(sym::doc).has_word(sym::hidden));
if is_no_inline {
return false;
@ -285,11 +286,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
};
let is_private = !self.cx.cache.effective_visibilities.is_directly_public(tcx, ori_res_did);
let is_hidden = tcx.is_doc_hidden(ori_res_did);
let is_hidden = !document_hidden && tcx.is_doc_hidden(ori_res_did);
let item = tcx.hir().get_by_def_id(res_did);
if !please_inline {
let inherits_hidden = inherits_doc_hidden(tcx, res_did, None);
let inherits_hidden = !document_hidden && inherits_doc_hidden(tcx, res_did, None);
// Only inline if requested or if the item would otherwise be stripped.
if (!is_private && !inherits_hidden) || (
is_hidden &&
@ -359,6 +360,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
import_def_id: LocalDefId,
target_def_id: LocalDefId,
) -> bool {
if self.cx.render_options.document_hidden {
return true;
}
let tcx = self.cx.tcx;
let item_def_id = reexport_chain(tcx, import_def_id, target_def_id)
.iter()

View file

@ -33,6 +33,7 @@ pub(crate) fn lib_embargo_visit_item(cx: &mut DocContext<'_>, def_id: DefId) {
tcx: cx.tcx,
extern_public: &mut cx.cache.effective_visibilities.extern_public,
visited_mods: Default::default(),
document_hidden: cx.render_options.document_hidden,
}
.visit_item(def_id)
}
@ -45,6 +46,7 @@ struct LibEmbargoVisitor<'a, 'tcx> {
extern_public: &'a mut DefIdSet,
// Keeps track of already visited modules, in case a module re-exports its parent
visited_mods: DefIdSet,
document_hidden: bool,
}
impl LibEmbargoVisitor<'_, '_> {
@ -63,7 +65,7 @@ impl LibEmbargoVisitor<'_, '_> {
}
fn visit_item(&mut self, def_id: DefId) {
if !self.tcx.is_doc_hidden(def_id) {
if self.document_hidden || !self.tcx.is_doc_hidden(def_id) {
self.extern_public.insert(def_id);
if self.tcx.def_kind(def_id) == DefKind::Mod {
self.visit_mod(def_id);

View file

@ -127,6 +127,7 @@ static TARGETS: &[&str] = &[
"s390x-unknown-linux-gnu",
"sparc64-unknown-linux-gnu",
"sparcv9-sun-solaris",
"sparc-unknown-none-elf",
"thumbv6m-none-eabi",
"thumbv7em-none-eabi",
"thumbv7em-none-eabihf",

View file

@ -50,7 +50,7 @@ jobs:
echo "LD_LIBRARY_PATH=${SYSROOT}/lib${LD_LIBRARY_PATH+:${LD_LIBRARY_PATH}}" >> $GITHUB_ENV
- name: Build
run: cargo build --features deny-warnings,internal
run: cargo build --tests --features deny-warnings,internal
- name: Test
run: cargo test --features deny-warnings,internal

View file

@ -106,7 +106,7 @@ jobs:
echo "$SYSROOT/bin" >> $GITHUB_PATH
- name: Build
run: cargo build --features deny-warnings,internal
run: cargo build --tests --features deny-warnings,internal
- name: Test
if: runner.os == 'Linux'

View file

@ -6,13 +6,74 @@ document.
## Unreleased / Beta / In Rust Nightly
[83e42a23...master](https://github.com/rust-lang/rust-clippy/compare/83e42a23...master)
[435a8ad8...master](https://github.com/rust-lang/rust-clippy/compare/435a8ad8...master)
## Rust 1.71
Current stable, released 2023-07-13
<!-- FIXME: Remove the request for feedback, with the next changelog -->
We're trying out a new shorter changelog format, that only contains significant changes.
You can check out the list of merged pull requests for a list of all changes.
If you have any feedback related to the new format, please share it in
[#10847](https://github.com/rust-lang/rust-clippy/issues/10847)
[View all 78 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-04-11T20%3A05%3A26Z..2023-05-20T13%3A48%3A17Z+base%3Amaster)
### New Lints
* [`non_minimal_cfg`]
[#10763](https://github.com/rust-lang/rust-clippy/pull/10763)
* [`manual_next_back`]
[#10769](https://github.com/rust-lang/rust-clippy/pull/10769)
* [`ref_patterns`]
[#10736](https://github.com/rust-lang/rust-clippy/pull/10736)
* [`default_constructed_unit_structs`]
[#10716](https://github.com/rust-lang/rust-clippy/pull/10716)
* [`manual_while_let_some`]
[#10647](https://github.com/rust-lang/rust-clippy/pull/10647)
* [`needless_bool_assign`]
[#10432](https://github.com/rust-lang/rust-clippy/pull/10432)
* [`items_after_test_module`]
[#10578](https://github.com/rust-lang/rust-clippy/pull/10578)
### Moves and Deprecations
* Rename `integer_arithmetic` to `arithmetic_side_effects`
[#10674](https://github.com/rust-lang/rust-clippy/pull/10674)
* Moved [`redundant_clone`] to `nursery` (Now allow-by-default)
[#10873](https://github.com/rust-lang/rust-clippy/pull/10873)
### Enhancements
* [`invalid_regex`]: Now supports the new syntax introduced after regex v1.8.0
[#10682](https://github.com/rust-lang/rust-clippy/pull/10682)
* [`semicolon_outside_block`]: Added [`semicolon-outside-block-ignore-multiline`] as a new config value.
[#10656](https://github.com/rust-lang/rust-clippy/pull/10656)
* [`semicolon_inside_block`]: Added [`semicolon-inside-block-ignore-singleline`] as a new config value.
[#10656](https://github.com/rust-lang/rust-clippy/pull/10656)
* [`unnecessary_box_returns`]: Added [`unnecessary-box-size`] as a new config value to set the maximum
size of `T` in `Box<T>` to be linted.
[#10651](https://github.com/rust-lang/rust-clippy/pull/10651)
### Documentation Improvements
* `cargo clippy --explain LINT` now shows possible configuration options for the explained lint
[#10751](https://github.com/rust-lang/rust-clippy/pull/10751)
* New config values mentioned in this changelog will now be linked.
[#10889](https://github.com/rust-lang/rust-clippy/pull/10889)
* Several sections of [Clippy's book] have been reworked
[#10652](https://github.com/rust-lang/rust-clippy/pull/10652)
[#10622](https://github.com/rust-lang/rust-clippy/pull/10622)
[Clippy's book]: https://doc.rust-lang.org/clippy/
## Rust 1.70
Current stable, released 2023-06-01
Released 2023-06-01
[**View 85 PRs merged since 1.69**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2023-04-20..2023-06-01+base%3Amaster+sort%3Amerged-desc+)
[View all 91 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-02-26T01%3A05%3A43Z..2023-04-11T13%3A27%3A30Z+base%3Amaster)
### New Lints
@ -137,7 +198,7 @@ Current stable, released 2023-06-01
Released 2023-04-20
[**View 86 PRs merged since 1.68**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2023-03-09..2023-04-20+base%3Amaster+sort%3Amerged-desc+)
[View all 72 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-01-13T06%3A12%3A46Z..2023-02-25T23%3A48%3A10Z+base%3Amaster)
### New Lints
@ -252,7 +313,7 @@ Released 2023-04-20
Released 2023-03-09
[**View 85 PRs merged since 1.67**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2023-01-26..2023-03-09+base%3Amaster+sort%3Amerged-desc+)
[View all 76 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-12-01T20%3A40%3A04Z..2023-01-12T18%3A58%3A59Z+base%3Amaster)
### New Lints
@ -399,7 +460,7 @@ Released 2023-03-09
Released 2023-01-26
[**View 68 PRs merged since 1.66**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2022-12-15..2023-01-26+base%3Amaster+sort%3Amerged-desc+)
[View all 104 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-10-23T13%3A35%3A19Z..2022-12-01T13%3A34%3A39Z+base%3Amaster)
### New Lints
@ -590,8 +651,7 @@ Released 2023-01-26
Released 2022-12-15
[**View 93 PRs merged since 1.65**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2022-11-03..2022-12-15+base%3Amaster+sort%3Amerged-desc+)
[View all 116 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-09-09T17%3A32%3A39Z..2022-10-23T11%3A27%3A24Z+base%3Amaster)
### New Lints
@ -762,8 +822,7 @@ Released 2022-12-15
Released 2022-11-03
[**View 129 PRs merged since 1.64**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2022-09-22..2022-11-03+base%3Amaster+sort%3Amerged-desc+)
[View all 86 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-07-29T01%3A09%3A31Z..2022-09-09T00%3A01%3A54Z+base%3Amaster)
### Important Changes
@ -907,8 +966,7 @@ Released 2022-11-03
Released 2022-09-22
[**View 92 PRs merged since 1.63**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2022-08-11..2022-09-22+base%3Amaster+sort%3Amerged-desc+)
[View all 110 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-06-17T21%3A25%3A31Z..2022-07-28T17%3A11%3A18Z+base%3Amaster)
### New Lints
@ -1058,8 +1116,7 @@ Released 2022-09-22
Released 2022-08-11
[**View 100 PRs merged since 1.62**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2022-06-30..2022-08-11+base%3Amaster+sort%3Amerged-desc+)
[View all 91 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-05-05T17%3A24%3A22Z..2022-06-16T14%3A24%3A48Z+base%3Amaster)
### New Lints
@ -1205,8 +1262,7 @@ Released 2022-08-11
Released 2022-06-30
[**View 104 PRs merged since 1.61**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2022-05-19..2022-06-30+base%3Amaster+sort%3Amerged-desc+)
[View all 90 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-03-25T17%3A22%3A30Z..2022-05-05T13%3A29%3A44Z+base%3Amaster)
### New Lints
@ -1363,8 +1419,7 @@ Released 2022-06-30
Released 2022-05-19
[**View 93 PRs merged since 1.60**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2022-04-07..2022-05-19+base%3Amaster+sort%3Amerged-desc+)
[View all 60 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-02-11T16%3A54%3A41Z..2022-03-24T13%3A42%3A25Z+base%3Amaster)
### New Lints
@ -1465,8 +1520,7 @@ Released 2022-05-19
Released 2022-04-07
[**View 75 PRs merged since 1.59**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2022-02-24..2022-04-07+base%3Amaster+sort%3Amerged-desc+)
[View all 73 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-12-31T17%3A53%3A37Z..2022-02-10T17%3A31%3A37Z+base%3Amaster)
### New Lints
@ -1598,8 +1652,7 @@ Released 2022-04-07
Released 2022-02-24
[**View 63 PRs merged since 1.58**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2022-01-13..2022-02-24+base%3Amaster+sort%3Amerged-desc+)
[View all 94 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-11-04T12%3A40%3A18Z..2021-12-30T13%3A36%3A20Z+base%3Amaster)
### New Lints
@ -1763,8 +1816,7 @@ Released 2022-02-24
Released 2022-01-13
[**View 73 PRs merged since 1.57**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2021-12-02..2022-01-13+base%3Amaster+sort%3Amerged-desc+)
[View all 68 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-10-07T09%3A49%3A18Z..2021-11-04T12%3A20%3A12Z+base%3Amaster)
### Rust 1.58.1
@ -1885,8 +1937,7 @@ Released 2022-01-13
Released 2021-12-02
[**View 92 PRs merged since 1.56**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2021-10-21..2021-12-02+base%3Amaster+sort%3Amerged-desc+)
[View all 148 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-08-12T20%3A36%3A04Z..2021-11-03T17%3A57%3A59Z+base%3Amaster)
### New Lints
@ -2037,7 +2088,7 @@ Released 2021-12-02
Released 2021-10-21
[**View 92 PRs merged since 1.55**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2021-09-09..2021-10-21+base%3Amaster+sort%3Amerged-desc+)
[View all 38 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-07-19T14%3A33%3A33Z..2021-08-12T09%3A28%3A38Z+base%3Amaster)
### New Lints
@ -2103,7 +2154,7 @@ Released 2021-10-21
Released 2021-09-09
[**View 61 PRs merged since 1.54**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2021-07-29..2021-09-09+base%3Amaster+sort%3Amerged-desc+)
[View all 83 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-06-03T07%3A23%3A59Z..2021-07-29T11%3A47%3A32Z+base%3Amaster)
### Important Changes
@ -2221,8 +2272,7 @@ Released 2021-09-09
Released 2021-07-29
[**View 68 PRs merged since 1.53**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2021-06-17..2021-07-29+base%3Amaster+sort%3Amerged-desc+)
[View all 74 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-04-27T23%3A51%3A18Z..2021-06-03T06%3A54%3A07Z+base%3Amaster)
### New Lints
@ -2350,7 +2400,7 @@ Released 2021-07-29
Released 2021-06-17
[**View 80 PRs merged since 1.52**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2021-05-06..2021-06-17+base%3Amaster+sort%3Amerged-desc+)
[View all 126 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-03-12T22%3A49%3A20Z..2021-04-27T14%3A38%3A20Z+base%3Amaster)
### New Lints
@ -2534,8 +2584,7 @@ Released 2021-06-17
Released 2021-05-06
[**View 113 PRs merged since 1.51**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2021-03-25..2021-05-06+base%3Amaster+sort%3Amerged-desc+)
[View all 102 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-02-03T15%3A59%3A06Z..2021-03-11T20%3A06%3A43Z+base%3Amaster)
### New Lints
@ -2670,8 +2719,7 @@ Released 2021-05-06
Released 2021-03-25
[**View 117 PRs merged since 1.50**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2021-02-11..2021-03-25+base%3Amaster+sort%3Amerged-desc+)
[View all 78 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-12-21T15%3A43%3A04Z..2021-02-03T04%3A21%3A10Z+base%3Amaster)
### New Lints
@ -2786,8 +2834,7 @@ Released 2021-03-25
Released 2021-02-11
[**View 90 PRs merged since 1.49**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2020-12-31..2021-02-11+base%3Amaster+sort%3Amerged-desc+)
[View all 119 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-11-06T18%3A32%3A40Z..2021-01-03T14%3A51%3A18Z+base%3Amaster)
### New Lints
@ -2916,8 +2963,7 @@ Released 2021-02-11
Released 2020-12-31
[**View 85 PRs merged since 1.48**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2020-11-19..2020-12-31+base%3Amaster+sort%3Amerged-desc+)
[View all 107 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-09-24T14%3A05%3A12Z..2020-11-05T13%3A35%3A44Z+base%3Amaster)
### New Lints
@ -3023,7 +3069,7 @@ Released 2020-12-31
Released 2020-11-19
[**View 112 PRs merged since 1.47**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2020-10-08..2020-11-19+base%3Amaster+sort%3Amerged-desc+)
[View all 99 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-08-11T13%3A14%3A38Z..2020-09-23T18%3A55%3A22Z+base%3Amaster)
### New lints
@ -3141,8 +3187,7 @@ Released 2020-11-19
Released 2020-10-08
[**View 80 PRs merged since 1.46**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2020-08-27..2020-10-08+base%3Amaster+sort%3Amerged-desc+)
[View all 76 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-06-23T16%3A27%3A11Z..2020-08-11T12%3A52%3A41Z+base%3Amaster)
### New lints
@ -3244,8 +3289,7 @@ Released 2020-10-08
Released 2020-08-27
[**View 93 PRs merged since 1.45**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2020-07-16..2020-08-27+base%3Amaster+sort%3Amerged-desc+)
[View all 48 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-05-31T12%3A50%3A53Z..2020-06-23T15%3A00%3A32Z+base%3Amaster)
### New lints
@ -3307,8 +3351,7 @@ Released 2020-08-27
Released 2020-07-16
[**View 65 PRs merged since 1.44**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2020-06-04..2020-07-16+base%3Amaster+sort%3Amerged-desc+)
[View all 81 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-04-18T20%3A18%3A04Z..2020-05-27T19%3A25%3A04Z+base%3Amaster)
### New lints
@ -3385,8 +3428,7 @@ and [`similar_names`]. [#5651](https://github.com/rust-lang/rust-clippy/pull/565
Released 2020-06-04
[**View 88 PRs merged since 1.43**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2020-04-23..2020-06-04+base%3Amaster+sort%3Amerged-desc+)
[View all 124 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-03-05T17%3A30%3A53Z..2020-04-18T09%3A20%3A51Z+base%3Amaster)
### New lints
@ -3469,8 +3511,7 @@ Released 2020-06-04
Released 2020-04-23
[**View 121 PRs merged since 1.42**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2020-03-12..2020-04-23+base%3Amaster+sort%3Amerged-desc+)
[View all 91 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-01-26T16%3A01%3A11Z..2020-03-04T16%3A45%3A37Z+base%3Amaster)
### New lints
@ -3528,7 +3569,7 @@ Released 2020-04-23
Released 2020-03-12
[**View 106 PRs merged since 1.41**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2020-01-30..2020-03-12+base%3Amaster+sort%3Amerged-desc+)
[View all 101 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-12-15T01%3A40%3A34Z..2020-01-26T11%3A22%3A13Z+base%3Amaster)
### New lints
@ -3595,7 +3636,7 @@ Released 2020-03-12
Released 2020-01-30
[**View 107 PRs merged since 1.40**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2019-12-19..2020-01-30+base%3Amaster+sort%3Amerged-desc+)
[View all 74 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-10-28T20%3A50%3A24Z..2019-12-12T00%3A53%3A03Z+base%3Amaster)
* New Lints:
* [`exit`] [#4697](https://github.com/rust-lang/rust-clippy/pull/4697)
@ -3640,8 +3681,7 @@ Released 2020-01-30
Released 2019-12-19
[**View 69 😺 PRs merged since 1.39**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2019-11-07..2019-12-19+base%3Amaster+sort%3Amerged-desc+)
[View all 76 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-09-23T06%3A18%3A04Z..2019-10-28T17%3A34%3A55Z+base%3Amaster)
* New Lints:
* [`unneeded_wildcard_pattern`] [#4537](https://github.com/rust-lang/rust-clippy/pull/4537)
@ -3683,7 +3723,7 @@ Released 2019-12-19
Released 2019-11-07
[**View 84 PRs merged since 1.38**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2019-09-26..2019-11-07+base%3Amaster+sort%3Amerged-desc+)
[View all 100 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-08-11T19%3A21%3A38Z..2019-09-22T12%3A07%3A39Z+base%3Amaster)
* New Lints:
* [`uninit_assumed_init`] [#4479](https://github.com/rust-lang/rust-clippy/pull/4479)
@ -3727,7 +3767,7 @@ Released 2019-11-07
Released 2019-09-26
[**View 102 PRs merged since 1.37**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2019-08-15..2019-09-26+base%3Amaster+sort%3Amerged-desc+)
[View all 76 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-06-30T13%3A40%3A26Z..2019-08-11T09%3A47%3A27Z+base%3Amaster)
* New Lints:
* [`main_recursion`] [#4203](https://github.com/rust-lang/rust-clippy/pull/4203)
@ -3757,7 +3797,7 @@ Released 2019-09-26
Released 2019-08-15
[**View 83 PRs merged since 1.36**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2019-07-04..2019-08-15+base%3Amaster+sort%3Amerged-desc+)
[View all 72 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-05-19T08%3A11%3A23Z..2019-06-25T23%3A22%3A22Z+base%3Amaster)
* New Lints:
* [`checked_conversions`] [#4088](https://github.com/rust-lang/rust-clippy/pull/4088)
@ -3781,8 +3821,7 @@ Released 2019-08-15
Released 2019-07-04
[**View 75 PRs merged since 1.35**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2019-05-20..2019-07-04+base%3Amaster+sort%3Amerged-desc+)
[View all 81 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-04-10T09%3A41%3A56Z..2019-05-18T00%3A29%3A40Z+base%3Amaster)
* New lints: [`find_map`], [`filter_map_next`] [#4039](https://github.com/rust-lang/rust-clippy/pull/4039)
* New lint: [`path_buf_push_overwrite`] [#3954](https://github.com/rust-lang/rust-clippy/pull/3954)
@ -3813,8 +3852,7 @@ Released 2019-07-04
Released 2019-05-20
[**View 90 PRs merged since 1.34**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2019-04-10..2019-05-20+base%3Amaster+sort%3Amerged-desc+)
[1fac380..37f5c1e](https://github.com/rust-lang/rust-clippy/compare/1fac380...37f5c1e)
* New lint: `drop_bounds` to detect `T: Drop` bounds
* Split [`redundant_closure`] into [`redundant_closure`] and [`redundant_closure_for_method_calls`] [#4110](https://github.com/rust-lang/rust-clippy/pull/4101)
@ -3842,8 +3880,7 @@ Released 2019-05-20
Released 2019-04-10
[**View 66 PRs merged since 1.33**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2019-02-26..2019-04-10+base%3Amaster+sort%3Amerged-desc+)
[View all 61 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-01-17T17%3A45%3A39Z..2019-02-19T08%3A24%3A05Z+base%3Amaster)
* New lint: [`assertions_on_constants`] to detect for example `assert!(true)`
* New lint: [`dbg_macro`] to detect uses of the `dbg!` macro
@ -3873,7 +3910,7 @@ Released 2019-04-10
Released 2019-02-26
[**View 83 PRs merged since 1.32**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2019-01-17..2019-02-26+base%3Amaster+sort%3Amerged-desc+)
[View all 120 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2018-11-28T06%3A19%3A50Z..2019-01-15T09%3A27%3A02Z+base%3Amaster)
* New lints: [`implicit_return`], [`vec_box`], [`cast_ref_to_mut`]
* The `rust-clippy` repository is now part of the `rust-lang` org.
@ -3906,7 +3943,7 @@ Released 2019-02-26
Released 2019-01-17
[**View 106 PRs merged since 1.31**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2018-12-06..2019-01-17+base%3Amaster+sort%3Amerged-desc+)
[View all 71 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2018-10-24T05%3A02%3A21Z..2018-11-27T17%3A29%3A34Z+base%3Amaster)
* New lints: [`slow_vector_initialization`], `mem_discriminant_non_enum`,
[`redundant_clone`], [`wildcard_dependencies`],
@ -3936,8 +3973,7 @@ Released 2019-01-17
Released 2018-12-06
[**View 85 PRs merged since 1.30**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2018-10-25..2018-12-06+base%3Amaster+sort%3Amerged-desc+)
[125907ad..2e26fdc2](https://github.com/rust-lang/rust-clippy/compare/125907ad..2e26fdc2)
* Clippy has been relicensed under a dual MIT / Apache license.
See [#3093](https://github.com/rust-lang/rust-clippy/issues/3093) for more
@ -3977,9 +4013,7 @@ Released 2018-12-06
Released 2018-10-25
[**View 106 PRs merged since 1.29**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2018-09-13..2018-10-25+base%3Amaster+sort%3Amerged-desc+)
[View all 88 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2018-08-02T16%3A54%3A12Z..2018-09-17T09%3A44%3A06Z+base%3Amaster)
* Deprecate `assign_ops` lint
* New lints: [`mistyped_literal_suffixes`], [`ptr_offset_with_cast`],
[`needless_collect`], [`copy_iterator`]
@ -4861,6 +4895,7 @@ Released 2018-09-13
[`inconsistent_digit_grouping`]: https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_digit_grouping
[`inconsistent_struct_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_struct_constructor
[`incorrect_clone_impl_on_copy_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#incorrect_clone_impl_on_copy_type
[`incorrect_partial_ord_impl_on_ord_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#incorrect_partial_ord_impl_on_ord_type
[`index_refutable_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice
[`indexing_slicing`]: https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing
[`ineffective_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#ineffective_bit_mask
@ -4941,6 +4976,8 @@ Released 2018-09-13
[`manual_flatten`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_flatten
[`manual_instant_elapsed`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_instant_elapsed
[`manual_is_ascii_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check
[`manual_is_finite`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_finite
[`manual_is_infinite`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_infinite
[`manual_let_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else
[`manual_main_separator_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_main_separator_str
[`manual_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_map
@ -5047,6 +5084,7 @@ Released 2018-09-13
[`needless_option_as_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_option_as_deref
[`needless_option_take`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_option_take
[`needless_parens_on_range_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_parens_on_range_literals
[`needless_pass_by_ref_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
[`needless_pass_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_value
[`needless_pub_self`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pub_self
[`needless_question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_question_mark
@ -5134,6 +5172,7 @@ Released 2018-09-13
[`rc_buffer`]: https://rust-lang.github.io/rust-clippy/master/index.html#rc_buffer
[`rc_clone_in_vec_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#rc_clone_in_vec_init
[`rc_mutex`]: https://rust-lang.github.io/rust-clippy/master/index.html#rc_mutex
[`read_line_without_trim`]: https://rust-lang.github.io/rust-clippy/master/index.html#read_line_without_trim
[`read_zero_byte_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#read_zero_byte_vec
[`recursive_format_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#recursive_format_impl
[`redundant_allocation`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation
@ -5266,6 +5305,7 @@ Released 2018-09-13
[`try_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#try_err
[`tuple_array_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#tuple_array_conversions
[`type_complexity`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity
[`type_id_on_box`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_id_on_box
[`type_repetition_in_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds
[`unchecked_duration_subtraction`]: https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_duration_subtraction
[`undocumented_unsafe_blocks`]: https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks

View file

@ -1,6 +1,6 @@
[package]
name = "clippy"
version = "0.1.72"
version = "0.1.73"
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
repository = "https://github.com/rust-lang/rust-clippy"
readme = "README.md"
@ -36,6 +36,17 @@ walkdir = "2.3"
filetime = "0.2"
itertools = "0.10.1"
# UI test dependencies
clippy_utils = { path = "clippy_utils" }
derive-new = "0.5"
if_chain = "1.0"
quote = "1.0"
serde = { version = "1.0.125", features = ["derive"] }
syn = { version = "2.0", features = ["full"] }
futures = "0.3"
parking_lot = "0.12"
tokio = { version = "1", features = ["io-util"] }
[build-dependencies]
rustc_tools_util = "0.3.0"

Some files were not shown because too many files have changed in this diff Show more