Auto merge of #122113 - matthiaskrgr:rollup-5d1jnwi, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #121958 (Fix redundant import errors for preload extern crate) - #121976 (Add an option to have an external download/bootstrap cache) - #122022 (loongarch: add frecipe and relax target feature) - #122026 (Do not try to format removed files) - #122027 (Uplift some feeding out of `associated_type_for_impl_trait_in_impl` and into queries) - #122063 (Make the lowering of `thir::ExprKind::If` easier to follow) - #122074 (Add missing PartialOrd trait implementation doc for array) - #122082 (remove outdated fixme comment) - #122091 (Note why we're using a new thread in `test_get_os_named_thread`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
aa029ce4d8
31 changed files with 402 additions and 180 deletions
|
@ -14,6 +14,43 @@ use rustc_span::Span;
|
|||
pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||
use rustc_hir::*;
|
||||
|
||||
// For an RPITIT, synthesize generics which are equal to the opaque's generics
|
||||
// and parent fn's generics compressed into one list.
|
||||
if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id }) =
|
||||
tcx.opt_rpitit_info(def_id.to_def_id())
|
||||
{
|
||||
let trait_def_id = tcx.parent(fn_def_id);
|
||||
let opaque_ty_generics = tcx.generics_of(opaque_def_id);
|
||||
let opaque_ty_parent_count = opaque_ty_generics.parent_count;
|
||||
let mut params = opaque_ty_generics.params.clone();
|
||||
|
||||
let parent_generics = tcx.generics_of(trait_def_id);
|
||||
let parent_count = parent_generics.parent_count + parent_generics.params.len();
|
||||
|
||||
let mut trait_fn_params = tcx.generics_of(fn_def_id).params.clone();
|
||||
|
||||
for param in &mut params {
|
||||
param.index = param.index + parent_count as u32 + trait_fn_params.len() as u32
|
||||
- opaque_ty_parent_count as u32;
|
||||
}
|
||||
|
||||
trait_fn_params.extend(params);
|
||||
params = trait_fn_params;
|
||||
|
||||
let param_def_id_to_index =
|
||||
params.iter().map(|param| (param.def_id, param.index)).collect();
|
||||
|
||||
return ty::Generics {
|
||||
parent: Some(trait_def_id),
|
||||
parent_count,
|
||||
params,
|
||||
param_def_id_to_index,
|
||||
has_self: opaque_ty_generics.has_self,
|
||||
has_late_bound_regions: opaque_ty_generics.has_late_bound_regions,
|
||||
host_effect_index: parent_generics.host_effect_index,
|
||||
};
|
||||
}
|
||||
|
||||
let hir_id = tcx.local_def_id_to_hir_id(def_id);
|
||||
|
||||
let node = tcx.hir_node(hir_id);
|
||||
|
|
|
@ -5,7 +5,7 @@ use rustc_hir::HirId;
|
|||
use rustc_middle::query::plumbing::CyclePlaceholder;
|
||||
use rustc_middle::ty::print::with_forced_trimmed_paths;
|
||||
use rustc_middle::ty::util::IntTypeExt;
|
||||
use rustc_middle::ty::{self, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
|
@ -350,22 +350,31 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
|||
// If we are computing `type_of` the synthesized associated type for an RPITIT in the impl
|
||||
// side, use `collect_return_position_impl_trait_in_trait_tys` to infer the value of the
|
||||
// associated type in the impl.
|
||||
if let Some(ImplTraitInTraitData::Impl { fn_def_id, .. }) =
|
||||
tcx.opt_rpitit_info(def_id.to_def_id())
|
||||
{
|
||||
match tcx.collect_return_position_impl_trait_in_trait_tys(fn_def_id) {
|
||||
Ok(map) => {
|
||||
let assoc_item = tcx.associated_item(def_id);
|
||||
return map[&assoc_item.trait_item_def_id.unwrap()];
|
||||
}
|
||||
Err(_) => {
|
||||
return ty::EarlyBinder::bind(Ty::new_error_with_message(
|
||||
tcx,
|
||||
DUMMY_SP,
|
||||
"Could not collect return position impl trait in trait tys",
|
||||
));
|
||||
match tcx.opt_rpitit_info(def_id.to_def_id()) {
|
||||
Some(ty::ImplTraitInTraitData::Impl { fn_def_id }) => {
|
||||
match tcx.collect_return_position_impl_trait_in_trait_tys(fn_def_id) {
|
||||
Ok(map) => {
|
||||
let assoc_item = tcx.associated_item(def_id);
|
||||
return map[&assoc_item.trait_item_def_id.unwrap()];
|
||||
}
|
||||
Err(_) => {
|
||||
return ty::EarlyBinder::bind(Ty::new_error_with_message(
|
||||
tcx,
|
||||
DUMMY_SP,
|
||||
"Could not collect return position impl trait in trait tys",
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
// For an RPITIT in a trait, just return the corresponding opaque.
|
||||
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
|
||||
return ty::EarlyBinder::bind(Ty::new_opaque(
|
||||
tcx,
|
||||
opaque_def_id,
|
||||
ty::GenericArgs::identity_for_item(tcx, opaque_def_id),
|
||||
));
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
let hir_id = tcx.local_def_id_to_hir_id(def_id);
|
||||
|
|
|
@ -143,7 +143,11 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di
|
|||
BuiltinLintDiag::RedundantImport(spans, ident) => {
|
||||
for (span, is_imported) in spans {
|
||||
let introduced = if is_imported { "imported" } else { "defined" };
|
||||
diag.span_label(span, format!("the item `{ident}` is already {introduced} here"));
|
||||
let span_msg = if span.is_dummy() { "by prelude" } else { "here" };
|
||||
diag.span_label(
|
||||
span,
|
||||
format!("the item `{ident}` is already {introduced} {span_msg}"),
|
||||
);
|
||||
}
|
||||
}
|
||||
BuiltinLintDiag::DeprecatedMacro(suggestion, span) => {
|
||||
|
|
|
@ -826,7 +826,7 @@ rustc_queries! {
|
|||
/// creates and returns the associated items that correspond to each impl trait in return position
|
||||
/// of the implemented trait.
|
||||
query associated_types_for_impl_traits_in_associated_fn(fn_def_id: DefId) -> &'tcx [DefId] {
|
||||
desc { |tcx| "creating associated items for impl trait in trait returned by `{}`", tcx.def_path_str(fn_def_id) }
|
||||
desc { |tcx| "creating associated items for opaque types returned by `{}`", tcx.def_path_str(fn_def_id) }
|
||||
cache_on_disk_if { fn_def_id.is_local() }
|
||||
separate_provide_extern
|
||||
}
|
||||
|
@ -834,7 +834,7 @@ rustc_queries! {
|
|||
/// Given an impl trait in trait `opaque_ty_def_id`, create and return the corresponding
|
||||
/// associated item.
|
||||
query associated_type_for_impl_trait_in_trait(opaque_ty_def_id: LocalDefId) -> LocalDefId {
|
||||
desc { |tcx| "creates the associated item corresponding to the opaque type `{}`", tcx.def_path_str(opaque_ty_def_id.to_def_id()) }
|
||||
desc { |tcx| "creating the associated item corresponding to the opaque type `{}`", tcx.def_path_str(opaque_ty_def_id.to_def_id()) }
|
||||
cache_on_disk_if { true }
|
||||
}
|
||||
|
||||
|
|
|
@ -58,52 +58,61 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
this.thir[scrutinee].span,
|
||||
),
|
||||
ExprKind::If { cond, then, else_opt, if_then_scope } => {
|
||||
let then_blk;
|
||||
let then_span = this.thir[then].span;
|
||||
let then_source_info = this.source_info(then_span);
|
||||
let condition_scope = this.local_scope();
|
||||
|
||||
let mut else_blk = unpack!(
|
||||
then_blk = this.in_scope(
|
||||
(if_then_scope, then_source_info),
|
||||
LintLevel::Inherited,
|
||||
|this| {
|
||||
let source_info = if this.is_let(cond) {
|
||||
let variable_scope =
|
||||
this.new_source_scope(then_span, LintLevel::Inherited, None);
|
||||
this.source_scope = variable_scope;
|
||||
SourceInfo { span: then_span, scope: variable_scope }
|
||||
} else {
|
||||
this.source_info(then_span)
|
||||
};
|
||||
let (then_block, else_block) =
|
||||
this.in_if_then_scope(condition_scope, then_span, |this| {
|
||||
let then_blk = unpack!(this.then_else_break(
|
||||
block,
|
||||
cond,
|
||||
Some(condition_scope), // Temp scope
|
||||
condition_scope,
|
||||
source_info,
|
||||
true, // Declare `let` bindings normally
|
||||
));
|
||||
let then_and_else_blocks = this.in_scope(
|
||||
(if_then_scope, then_source_info),
|
||||
LintLevel::Inherited,
|
||||
|this| {
|
||||
// FIXME: Does this need extra logic to handle let-chains?
|
||||
let source_info = if this.is_let(cond) {
|
||||
let variable_scope =
|
||||
this.new_source_scope(then_span, LintLevel::Inherited, None);
|
||||
this.source_scope = variable_scope;
|
||||
SourceInfo { span: then_span, scope: variable_scope }
|
||||
} else {
|
||||
this.source_info(then_span)
|
||||
};
|
||||
|
||||
this.expr_into_dest(destination, then_blk, then)
|
||||
});
|
||||
then_block.and(else_block)
|
||||
},
|
||||
)
|
||||
// Lower the condition, and have it branch into `then` and `else` blocks.
|
||||
let (then_block, else_block) =
|
||||
this.in_if_then_scope(condition_scope, then_span, |this| {
|
||||
let then_blk = unpack!(this.then_else_break(
|
||||
block,
|
||||
cond,
|
||||
Some(condition_scope), // Temp scope
|
||||
condition_scope,
|
||||
source_info,
|
||||
true, // Declare `let` bindings normally
|
||||
));
|
||||
|
||||
// Lower the `then` arm into its block.
|
||||
this.expr_into_dest(destination, then_blk, then)
|
||||
});
|
||||
|
||||
// Pack `(then_block, else_block)` into `BlockAnd<BasicBlock>`.
|
||||
then_block.and(else_block)
|
||||
},
|
||||
);
|
||||
|
||||
else_blk = if let Some(else_opt) = else_opt {
|
||||
unpack!(this.expr_into_dest(destination, else_blk, else_opt))
|
||||
// Unpack `BlockAnd<BasicBlock>` into `(then_blk, else_blk)`.
|
||||
let (then_blk, mut else_blk);
|
||||
else_blk = unpack!(then_blk = then_and_else_blocks);
|
||||
|
||||
// If there is an `else` arm, lower it into `else_blk`.
|
||||
if let Some(else_expr) = else_opt {
|
||||
unpack!(else_blk = this.expr_into_dest(destination, else_blk, else_expr));
|
||||
} else {
|
||||
// Body of the `if` expression without an `else` clause must return `()`, thus
|
||||
// we implicitly generate an `else {}` if it is not specified.
|
||||
// There is no `else` arm, so we know both arms have type `()`.
|
||||
// Generate the implicit `else {}` by assigning unit.
|
||||
let correct_si = this.source_info(expr_span.shrink_to_hi());
|
||||
this.cfg.push_assign_unit(else_blk, correct_si, destination, this.tcx);
|
||||
else_blk
|
||||
};
|
||||
}
|
||||
|
||||
// The `then` and `else` arms have been lowered into their respective
|
||||
// blocks, so make both of them meet up in a new block.
|
||||
let join_block = this.cfg.start_new_block();
|
||||
this.cfg.goto(then_blk, source_info, join_block);
|
||||
this.cfg.goto(else_blk, source_info, join_block);
|
||||
|
|
|
@ -137,6 +137,81 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
|
|||
self.check_import_as_underscore(item, *id);
|
||||
}
|
||||
}
|
||||
|
||||
fn report_unused_extern_crate_items(
|
||||
&mut self,
|
||||
maybe_unused_extern_crates: FxHashMap<ast::NodeId, Span>,
|
||||
) {
|
||||
let tcx = self.r.tcx();
|
||||
for extern_crate in &self.extern_crate_items {
|
||||
let warn_if_unused = !extern_crate.ident.name.as_str().starts_with('_');
|
||||
|
||||
// If the crate is fully unused, we suggest removing it altogether.
|
||||
// We do this in any edition.
|
||||
if warn_if_unused {
|
||||
if let Some(&span) = maybe_unused_extern_crates.get(&extern_crate.id) {
|
||||
self.r.lint_buffer.buffer_lint_with_diagnostic(
|
||||
UNUSED_EXTERN_CRATES,
|
||||
extern_crate.id,
|
||||
span,
|
||||
"unused extern crate",
|
||||
BuiltinLintDiag::UnusedExternCrate {
|
||||
removal_span: extern_crate.span_with_attributes,
|
||||
},
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If we are not in Rust 2018 edition, then we don't make any further
|
||||
// suggestions.
|
||||
if !tcx.sess.at_least_rust_2018() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the extern crate has any attributes, they may have funky
|
||||
// semantics we can't faithfully represent using `use` (most
|
||||
// notably `#[macro_use]`). Ignore it.
|
||||
if extern_crate.has_attrs {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the extern crate is renamed, then we cannot suggest replacing it with a use as this
|
||||
// would not insert the new name into the prelude, where other imports in the crate may be
|
||||
// expecting it.
|
||||
if extern_crate.renames {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the extern crate isn't in the extern prelude,
|
||||
// there is no way it can be written as a `use`.
|
||||
if !self
|
||||
.r
|
||||
.extern_prelude
|
||||
.get(&extern_crate.ident)
|
||||
.is_some_and(|entry| !entry.introduced_by_item)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let vis_span = extern_crate
|
||||
.vis_span
|
||||
.find_ancestor_inside(extern_crate.span)
|
||||
.unwrap_or(extern_crate.vis_span);
|
||||
let ident_span = extern_crate
|
||||
.ident
|
||||
.span
|
||||
.find_ancestor_inside(extern_crate.span)
|
||||
.unwrap_or(extern_crate.ident.span);
|
||||
self.r.lint_buffer.buffer_lint_with_diagnostic(
|
||||
UNUSED_EXTERN_CRATES,
|
||||
extern_crate.id,
|
||||
extern_crate.span,
|
||||
"`extern crate` is not idiomatic in the new edition",
|
||||
BuiltinLintDiag::ExternCrateNotIdiomatic { vis_span, ident_span },
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
|
||||
|
@ -335,6 +410,8 @@ impl Resolver<'_, '_> {
|
|||
};
|
||||
visit::walk_crate(&mut visitor, krate);
|
||||
|
||||
visitor.report_unused_extern_crate_items(maybe_unused_extern_crates);
|
||||
|
||||
for unused in visitor.unused_imports.values() {
|
||||
let mut fixes = Vec::new();
|
||||
let spans = match calc_unused_spans(unused, &unused.use_tree, unused.use_tree_id) {
|
||||
|
@ -416,75 +493,6 @@ impl Resolver<'_, '_> {
|
|||
);
|
||||
}
|
||||
|
||||
for extern_crate in visitor.extern_crate_items {
|
||||
let warn_if_unused = !extern_crate.ident.name.as_str().starts_with('_');
|
||||
|
||||
// If the crate is fully unused, we suggest removing it altogether.
|
||||
// We do this in any edition.
|
||||
if warn_if_unused {
|
||||
if let Some(&span) = maybe_unused_extern_crates.get(&extern_crate.id) {
|
||||
visitor.r.lint_buffer.buffer_lint_with_diagnostic(
|
||||
UNUSED_EXTERN_CRATES,
|
||||
extern_crate.id,
|
||||
span,
|
||||
"unused extern crate",
|
||||
BuiltinLintDiag::UnusedExternCrate {
|
||||
removal_span: extern_crate.span_with_attributes,
|
||||
},
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If we are not in Rust 2018 edition, then we don't make any further
|
||||
// suggestions.
|
||||
if !tcx.sess.at_least_rust_2018() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the extern crate has any attributes, they may have funky
|
||||
// semantics we can't faithfully represent using `use` (most
|
||||
// notably `#[macro_use]`). Ignore it.
|
||||
if extern_crate.has_attrs {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the extern crate is renamed, then we cannot suggest replacing it with a use as this
|
||||
// would not insert the new name into the prelude, where other imports in the crate may be
|
||||
// expecting it.
|
||||
if extern_crate.renames {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the extern crate isn't in the extern prelude,
|
||||
// there is no way it can be written as a `use`.
|
||||
if !visitor
|
||||
.r
|
||||
.extern_prelude
|
||||
.get(&extern_crate.ident)
|
||||
.is_some_and(|entry| !entry.introduced_by_item)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let vis_span = extern_crate
|
||||
.vis_span
|
||||
.find_ancestor_inside(extern_crate.span)
|
||||
.unwrap_or(extern_crate.vis_span);
|
||||
let ident_span = extern_crate
|
||||
.ident
|
||||
.span
|
||||
.find_ancestor_inside(extern_crate.span)
|
||||
.unwrap_or(extern_crate.ident.span);
|
||||
visitor.r.lint_buffer.buffer_lint_with_diagnostic(
|
||||
UNUSED_EXTERN_CRATES,
|
||||
extern_crate.id,
|
||||
extern_crate.span,
|
||||
"`extern crate` is not idiomatic in the new edition",
|
||||
BuiltinLintDiag::ExternCrateNotIdiomatic { vis_span, ident_span },
|
||||
);
|
||||
}
|
||||
|
||||
let unused_imports = visitor.unused_imports;
|
||||
let mut check_redundant_imports = FxIndexSet::default();
|
||||
for module in self.arenas.local_modules().iter() {
|
||||
|
|
|
@ -1336,9 +1336,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
}
|
||||
|
||||
let mut is_redundant = true;
|
||||
|
||||
let mut redundant_span = PerNS { value_ns: None, type_ns: None, macro_ns: None };
|
||||
|
||||
self.per_ns(|this, ns| {
|
||||
if is_redundant && let Ok(binding) = source_bindings[ns].get() {
|
||||
if binding.res() == Res::Err {
|
||||
|
|
|
@ -377,10 +377,12 @@ const LOONGARCH_ALLOWED_FEATURES: &[(&str, Stability)] = &[
|
|||
// tidy-alphabetical-start
|
||||
("d", Unstable(sym::loongarch_target_feature)),
|
||||
("f", Unstable(sym::loongarch_target_feature)),
|
||||
("frecipe", Unstable(sym::loongarch_target_feature)),
|
||||
("lasx", Unstable(sym::loongarch_target_feature)),
|
||||
("lbt", Unstable(sym::loongarch_target_feature)),
|
||||
("lsx", Unstable(sym::loongarch_target_feature)),
|
||||
("lvz", Unstable(sym::loongarch_target_feature)),
|
||||
("relax", Unstable(sym::loongarch_target_feature)),
|
||||
("ual", Unstable(sym::loongarch_target_feature)),
|
||||
// tidy-alphabetical-end
|
||||
];
|
||||
|
|
|
@ -102,7 +102,6 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
|||
if trait_clause.def_id() == goal.predicate.def_id()
|
||||
&& trait_clause.polarity() == goal.predicate.polarity
|
||||
{
|
||||
// FIXME: Constness
|
||||
ecx.probe_misc_candidate("assumption").enter(|ecx| {
|
||||
let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause);
|
||||
ecx.eq(
|
||||
|
|
|
@ -4,7 +4,7 @@ use rustc_hir::def::DefKind;
|
|||
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::{self, GenericArgs, ImplTraitInTraitData, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt};
|
||||
use rustc_span::symbol::kw;
|
||||
|
||||
pub(crate) fn provide(providers: &mut Providers) {
|
||||
|
@ -284,48 +284,8 @@ fn associated_type_for_impl_trait_in_trait(
|
|||
// Copy defaultness of the containing function.
|
||||
trait_assoc_ty.defaultness(tcx.defaultness(fn_def_id));
|
||||
|
||||
// Copy type_of of the opaque.
|
||||
trait_assoc_ty.type_of(ty::EarlyBinder::bind(Ty::new_opaque(
|
||||
tcx,
|
||||
opaque_ty_def_id.to_def_id(),
|
||||
GenericArgs::identity_for_item(tcx, opaque_ty_def_id),
|
||||
)));
|
||||
|
||||
trait_assoc_ty.is_type_alias_impl_trait(false);
|
||||
|
||||
// Copy generics_of of the opaque type item but the trait is the parent.
|
||||
trait_assoc_ty.generics_of({
|
||||
let opaque_ty_generics = tcx.generics_of(opaque_ty_def_id);
|
||||
let opaque_ty_parent_count = opaque_ty_generics.parent_count;
|
||||
let mut params = opaque_ty_generics.params.clone();
|
||||
|
||||
let parent_generics = tcx.generics_of(trait_def_id);
|
||||
let parent_count = parent_generics.parent_count + parent_generics.params.len();
|
||||
|
||||
let mut trait_fn_params = tcx.generics_of(fn_def_id).params.clone();
|
||||
|
||||
for param in &mut params {
|
||||
param.index = param.index + parent_count as u32 + trait_fn_params.len() as u32
|
||||
- opaque_ty_parent_count as u32;
|
||||
}
|
||||
|
||||
trait_fn_params.extend(params);
|
||||
params = trait_fn_params;
|
||||
|
||||
let param_def_id_to_index =
|
||||
params.iter().map(|param| (param.def_id, param.index)).collect();
|
||||
|
||||
ty::Generics {
|
||||
parent: Some(trait_def_id.to_def_id()),
|
||||
parent_count,
|
||||
params,
|
||||
param_def_id_to_index,
|
||||
has_self: opaque_ty_generics.has_self,
|
||||
has_late_bound_regions: opaque_ty_generics.has_late_bound_regions,
|
||||
host_effect_index: parent_generics.host_effect_index,
|
||||
}
|
||||
});
|
||||
|
||||
// There are no inferred outlives for the synthesized associated type.
|
||||
trait_assoc_ty.inferred_outlives_of(&[]);
|
||||
|
||||
|
@ -382,8 +342,9 @@ fn associated_type_for_impl_trait_in_impl(
|
|||
impl_assoc_ty.defaultness(tcx.defaultness(impl_fn_def_id));
|
||||
|
||||
// Copy generics_of the trait's associated item but the impl as the parent.
|
||||
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) resolves to the trait instead of the impl
|
||||
// generics.
|
||||
// FIXME: This may be detrimental to diagnostics, as we resolve the early-bound vars
|
||||
// here to paramswhose parent are items in the trait. We could synthesize new params
|
||||
// here, but it seems overkill.
|
||||
impl_assoc_ty.generics_of({
|
||||
let trait_assoc_generics = tcx.generics_of(trait_assoc_def_id);
|
||||
let trait_assoc_parent_count = trait_assoc_generics.parent_count;
|
||||
|
|
|
@ -300,6 +300,10 @@
|
|||
# This is only useful for verifying that rustc generates reproducible builds.
|
||||
#full-bootstrap = false
|
||||
|
||||
# Set the bootstrap/download cache path. It is useful when building rust
|
||||
# repeatedly in a CI invironment.
|
||||
# bootstrap-cache-path = /shared/cache
|
||||
|
||||
# Enable a build of the extended Rust tool set which is not only the compiler
|
||||
# but also tools such as Cargo. This will also produce "combined installers"
|
||||
# which are used to install Rust and Cargo together.
|
||||
|
|
|
@ -360,6 +360,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Implements comparison of arrays [lexicographically](Ord#lexicographical-comparison).
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: PartialOrd, const N: usize> PartialOrd for [T; N] {
|
||||
#[inline]
|
||||
|
|
|
@ -80,6 +80,7 @@ fn test_named_thread_truncation() {
|
|||
#[test]
|
||||
fn test_get_os_named_thread() {
|
||||
use crate::sys::thread::Thread;
|
||||
// Spawn a new thread to avoid interfering with other tests running on this thread.
|
||||
let handler = thread::spawn(|| {
|
||||
let name = c"test me please";
|
||||
Thread::set_name(name);
|
||||
|
|
|
@ -557,7 +557,9 @@ class RustBuild(object):
|
|||
shutil.rmtree(bin_root)
|
||||
|
||||
key = self.stage0_compiler.date
|
||||
cache_dst = os.path.join(self.build_dir, "cache")
|
||||
cache_dst = (self.get_toml('bootstrap-cache-path', 'build') or
|
||||
os.path.join(self.build_dir, "cache"))
|
||||
|
||||
rustc_cache = os.path.join(cache_dst, key)
|
||||
if not os.path.exists(rustc_cache):
|
||||
os.makedirs(rustc_cache)
|
||||
|
|
|
@ -149,6 +149,7 @@ v("default-linker", "rust.default-linker", "the default linker")
|
|||
# (others are conditionally saved).
|
||||
o("manage-submodules", "build.submodules", "let the build manage the git submodules")
|
||||
o("full-bootstrap", "build.full-bootstrap", "build three compilers instead of two (not recommended except for testing reproducible builds)")
|
||||
o("bootstrap-cache-path", "build.bootstrap-cache-path", "use provided path for the bootstrap cache")
|
||||
o("extended", "build.extended", "build an extended rust tool set")
|
||||
|
||||
v("tools", None, "List of extended tools will be installed")
|
||||
|
|
|
@ -81,7 +81,7 @@ fn update_rustfmt_version(build: &Builder<'_>) {
|
|||
}
|
||||
|
||||
/// Returns the Rust files modified between the `merge-base` of HEAD and
|
||||
/// rust-lang/master and what is now on the disk.
|
||||
/// rust-lang/master and what is now on the disk. Does not include removed files.
|
||||
///
|
||||
/// Returns `None` if all files should be formatted.
|
||||
fn get_modified_rs_files(build: &Builder<'_>) -> Result<Option<Vec<String>>, String> {
|
||||
|
|
|
@ -161,6 +161,7 @@ pub struct Config {
|
|||
pub vendor: bool,
|
||||
pub target_config: HashMap<TargetSelection, Target>,
|
||||
pub full_bootstrap: bool,
|
||||
pub bootstrap_cache_path: Option<PathBuf>,
|
||||
pub extended: bool,
|
||||
pub tools: Option<HashSet<String>>,
|
||||
pub sanitizers: bool,
|
||||
|
@ -827,6 +828,7 @@ define_config! {
|
|||
locked_deps: Option<bool> = "locked-deps",
|
||||
vendor: Option<bool> = "vendor",
|
||||
full_bootstrap: Option<bool> = "full-bootstrap",
|
||||
bootstrap_cache_path: Option<PathBuf> = "bootstrap-cache-path",
|
||||
extended: Option<bool> = "extended",
|
||||
tools: Option<HashSet<String>> = "tools",
|
||||
verbose: Option<usize> = "verbose",
|
||||
|
@ -1389,6 +1391,7 @@ impl Config {
|
|||
locked_deps,
|
||||
vendor,
|
||||
full_bootstrap,
|
||||
bootstrap_cache_path,
|
||||
extended,
|
||||
tools,
|
||||
verbose,
|
||||
|
@ -1477,6 +1480,7 @@ impl Config {
|
|||
config.reuse = reuse.map(PathBuf::from);
|
||||
config.submodules = submodules;
|
||||
config.android_ndk = android_ndk;
|
||||
config.bootstrap_cache_path = bootstrap_cache_path;
|
||||
set(&mut config.low_priority, low_priority);
|
||||
set(&mut config.compiler_docs, compiler_docs);
|
||||
set(&mut config.library_docs_private_items, library_docs_private_items);
|
||||
|
|
|
@ -578,7 +578,9 @@ impl Config {
|
|||
return;
|
||||
}
|
||||
|
||||
let cache_dst = self.out.join("cache");
|
||||
let cache_dst =
|
||||
self.bootstrap_cache_path.as_ref().cloned().unwrap_or_else(|| self.out.join("cache"));
|
||||
|
||||
let cache_dir = cache_dst.join(key);
|
||||
if !cache_dir.exists() {
|
||||
t!(fs::create_dir_all(&cache_dir));
|
||||
|
@ -705,7 +707,9 @@ download-rustc = false
|
|||
let llvm_assertions = self.llvm_assertions;
|
||||
|
||||
let cache_prefix = format!("llvm-{llvm_sha}-{llvm_assertions}");
|
||||
let cache_dst = self.out.join("cache");
|
||||
let cache_dst =
|
||||
self.bootstrap_cache_path.as_ref().cloned().unwrap_or_else(|| self.out.join("cache"));
|
||||
|
||||
let rustc_cache = cache_dst.join(cache_prefix);
|
||||
if !rustc_cache.exists() {
|
||||
t!(fs::create_dir_all(&rustc_cache));
|
||||
|
|
|
@ -136,4 +136,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
|
|||
severity: ChangeSeverity::Info,
|
||||
summary: "`x install` now skips providing tarball sources (under 'build/dist' path) to speed up the installation process.",
|
||||
},
|
||||
ChangeInfo {
|
||||
change_id: 121976,
|
||||
severity: ChangeSeverity::Info,
|
||||
summary: "A new `boostrap-cache-path` option has been introduced which can be utilized to modify the cache path for bootstrap.",
|
||||
},
|
||||
];
|
||||
|
|
|
@ -113,6 +113,7 @@ pub fn get_git_merge_base(
|
|||
|
||||
/// Returns the files that have been modified in the current branch compared to the master branch.
|
||||
/// The `extensions` parameter can be used to filter the files by their extension.
|
||||
/// Does not include removed files.
|
||||
/// If `extensions` is empty, all files will be returned.
|
||||
pub fn get_git_modified_files(
|
||||
config: &GitConfig<'_>,
|
||||
|
@ -125,13 +126,19 @@ pub fn get_git_modified_files(
|
|||
if let Some(git_dir) = git_dir {
|
||||
git.current_dir(git_dir);
|
||||
}
|
||||
let files = output_result(git.args(["diff-index", "--name-only", merge_base.trim()]))?
|
||||
let files = output_result(git.args(["diff-index", "--name-status", merge_base.trim()]))?
|
||||
.lines()
|
||||
.map(|s| s.trim().to_owned())
|
||||
.filter(|f| {
|
||||
Path::new(f).extension().map_or(false, |ext| {
|
||||
.filter_map(|f| {
|
||||
let (status, name) = f.trim().split_once(char::is_whitespace).unwrap();
|
||||
if status == "D" {
|
||||
None
|
||||
} else if Path::new(name).extension().map_or(false, |ext| {
|
||||
extensions.is_empty() || extensions.contains(&ext.to_str().unwrap())
|
||||
})
|
||||
}) {
|
||||
Some(name.to_owned())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
Ok(Some(files))
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
//@ revisions: loongarch64
|
||||
//@[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu
|
||||
//@[loongarch64] needs-llvm-components: loongarch
|
||||
//@[loongarch64] min-llvm-version: 17
|
||||
//@[loongarch64] min-llvm-version: 18
|
||||
//@ revisions: wasm
|
||||
//@[wasm] compile-flags: --target wasm32-unknown-unknown
|
||||
//@[wasm] needs-llvm-components: webassembly
|
||||
|
|
|
@ -251,7 +251,7 @@ warning: unexpected `cfg` condition value: `zebra`
|
|||
LL | cfg!(target_feature = "zebra");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2` and 186 more
|
||||
= note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2` and 187 more
|
||||
= note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
|
||||
|
||||
warning: 27 warnings emitted
|
||||
|
|
|
@ -154,7 +154,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
|
|||
LL | target_feature = "_UNEXPECTED_VALUE",
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `f`, `f16c`, `f32mm`, `f64mm`, `fast-unaligned-access`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, `zkt`
|
||||
= note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `f`, `f16c`, `f32mm`, `f64mm`, `fast-unaligned-access`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, `zkt`
|
||||
= note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
|
||||
|
||||
warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
|
||||
|
|
18
tests/ui/impl-trait/in-trait/rpitit-cycle-in-generics-of.rs
Normal file
18
tests/ui/impl-trait/in-trait/rpitit-cycle-in-generics-of.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
//@ check-pass
|
||||
|
||||
// Check that we don't hit a query cycle when:
|
||||
// 1. Computing generics_of, which requires...
|
||||
// 2. Calling resolve_bound_vars, which requires...
|
||||
// 3. Calling associated_items, which requires...
|
||||
// 4. Calling associated_type_for_impl_trait_in_trait, which requires...
|
||||
// 5. Computing generics_of, which cycles.
|
||||
|
||||
pub trait Foo<'a> {
|
||||
type Assoc;
|
||||
|
||||
fn demo<T>(other: T) -> impl Foo<'a, Assoc = Self::Assoc>
|
||||
where
|
||||
T: Foo<'a, Assoc = ()>;
|
||||
}
|
||||
|
||||
fn main() {}
|
1
tests/ui/imports/auxiliary/aux-issue-121915.rs
Normal file
1
tests/ui/imports/auxiliary/aux-issue-121915.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub fn item() {}
|
11
tests/ui/imports/redundant-import-issue-121915-2015.rs
Normal file
11
tests/ui/imports/redundant-import-issue-121915-2015.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
//@ compile-flags: --extern aux_issue_121915 --edition 2015
|
||||
//@ aux-build: aux-issue-121915.rs
|
||||
|
||||
extern crate aux_issue_121915;
|
||||
|
||||
#[deny(unused_imports)]
|
||||
fn main() {
|
||||
use aux_issue_121915;
|
||||
//~^ ERROR the item `aux_issue_121915` is imported redundantly
|
||||
aux_issue_121915::item();
|
||||
}
|
17
tests/ui/imports/redundant-import-issue-121915-2015.stderr
Normal file
17
tests/ui/imports/redundant-import-issue-121915-2015.stderr
Normal file
|
@ -0,0 +1,17 @@
|
|||
error: the item `aux_issue_121915` is imported redundantly
|
||||
--> $DIR/redundant-import-issue-121915-2015.rs:8:9
|
||||
|
|
||||
LL | extern crate aux_issue_121915;
|
||||
| ------------------------------ the item `aux_issue_121915` is already imported here
|
||||
...
|
||||
LL | use aux_issue_121915;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/redundant-import-issue-121915-2015.rs:6:8
|
||||
|
|
||||
LL | #[deny(unused_imports)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
9
tests/ui/imports/redundant-import-issue-121915.rs
Normal file
9
tests/ui/imports/redundant-import-issue-121915.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
//@ compile-flags: --extern aux_issue_121915 --edition 2018
|
||||
//@ aux-build: aux-issue-121915.rs
|
||||
|
||||
#[deny(unused_imports)]
|
||||
fn main() {
|
||||
use aux_issue_121915;
|
||||
//~^ ERROR the item `aux_issue_121915` is imported redundantly
|
||||
aux_issue_121915::item();
|
||||
}
|
14
tests/ui/imports/redundant-import-issue-121915.stderr
Normal file
14
tests/ui/imports/redundant-import-issue-121915.stderr
Normal file
|
@ -0,0 +1,14 @@
|
|||
error: the item `aux_issue_121915` is imported redundantly
|
||||
--> $DIR/redundant-import-issue-121915.rs:6:9
|
||||
|
|
||||
LL | use aux_issue_121915;
|
||||
| ^^^^^^^^^^^^^^^^ the item `aux_issue_121915` is already defined by prelude
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/redundant-import-issue-121915.rs:4:8
|
||||
|
|
||||
LL | #[deny(unused_imports)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
40
tests/ui/imports/suggest-remove-issue-121315.rs
Normal file
40
tests/ui/imports/suggest-remove-issue-121315.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
//@ compile-flags: --edition 2021
|
||||
#![deny(unused_imports)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
fn test0() {
|
||||
// Test remove FlatUnused
|
||||
use std::convert::TryFrom;
|
||||
//~^ ERROR the item `TryFrom` is imported redundantly
|
||||
let _ = u32::try_from(5i32);
|
||||
}
|
||||
|
||||
fn test1() {
|
||||
// FIXME(yukang) Test remove NestedFullUnused
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
//~^ ERROR the item `TryFrom` is imported redundantly
|
||||
//~| ERROR the item `TryInto` is imported redundantly
|
||||
|
||||
let _ = u32::try_from(5i32);
|
||||
let _a: i32 = u32::try_into(5u32).unwrap();
|
||||
}
|
||||
|
||||
fn test2() {
|
||||
// FIXME(yukang): Test remove both redundant and unused
|
||||
use std::convert::{AsMut, Into};
|
||||
//~^ ERROR unused import: `AsMut`
|
||||
//~| ERROR the item `Into` is imported redundantly
|
||||
|
||||
let _a: u32 = (5u8).into();
|
||||
}
|
||||
|
||||
fn test3() {
|
||||
// Test remove NestedPartialUnused
|
||||
use std::convert::{From, Infallible};
|
||||
//~^ ERROR unused import: `From`
|
||||
|
||||
trait MyTrait {}
|
||||
impl MyTrait for fn() -> Infallible {}
|
||||
}
|
||||
|
||||
fn main() {}
|
56
tests/ui/imports/suggest-remove-issue-121315.stderr
Normal file
56
tests/ui/imports/suggest-remove-issue-121315.stderr
Normal file
|
@ -0,0 +1,56 @@
|
|||
error: the item `TryFrom` is imported redundantly
|
||||
--> $DIR/suggest-remove-issue-121315.rs:7:9
|
||||
|
|
||||
LL | use std::convert::TryFrom;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
--> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
|
||||
|
|
||||
= note: the item `TryFrom` is already defined here
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/suggest-remove-issue-121315.rs:2:9
|
||||
|
|
||||
LL | #![deny(unused_imports)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: the item `TryFrom` is imported redundantly
|
||||
--> $DIR/suggest-remove-issue-121315.rs:14:24
|
||||
|
|
||||
LL | use std::convert::{TryFrom, TryInto};
|
||||
| ^^^^^^^
|
||||
--> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
|
||||
|
|
||||
= note: the item `TryFrom` is already defined here
|
||||
|
||||
error: the item `TryInto` is imported redundantly
|
||||
--> $DIR/suggest-remove-issue-121315.rs:14:33
|
||||
|
|
||||
LL | use std::convert::{TryFrom, TryInto};
|
||||
| ^^^^^^^
|
||||
--> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
|
||||
|
|
||||
= note: the item `TryInto` is already defined here
|
||||
|
||||
error: unused import: `AsMut`
|
||||
--> $DIR/suggest-remove-issue-121315.rs:24:24
|
||||
|
|
||||
LL | use std::convert::{AsMut, Into};
|
||||
| ^^^^^
|
||||
|
||||
error: the item `Into` is imported redundantly
|
||||
--> $DIR/suggest-remove-issue-121315.rs:24:31
|
||||
|
|
||||
LL | use std::convert::{AsMut, Into};
|
||||
| ^^^^
|
||||
--> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
|
||||
|
|
||||
= note: the item `Into` is already defined here
|
||||
|
||||
error: unused import: `From`
|
||||
--> $DIR/suggest-remove-issue-121315.rs:33:24
|
||||
|
|
||||
LL | use std::convert::{From, Infallible};
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
Loading…
Add table
Reference in a new issue