Auto merge of #108127 - matthiaskrgr:rollup-kpzfc6j, r=matthiaskrgr

Rollup of 7 pull requests

Successful merges:

 - #106347 (More accurate spans for arg removal suggestion)
 - #108057 (Prevent some attributes from being merged with others on reexports)
 - #108090 (`if $c:expr { Some($r:expr) } else { None }` =>> `$c.then(|| $r)`)
 - #108092 (note issue for feature(packed_bundled_libs))
 - #108099 (use chars instead of strings where applicable)
 - #108115 (Do not ICE on unmet trait alias bounds)
 - #108125 (Add new people to the compiletest review rotation)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2023-02-16 19:21:02 +00:00
commit 9a7cc6c32f
92 changed files with 677 additions and 558 deletions

View File

@ -271,7 +271,7 @@ impl<'a> AstValidator<'a> {
self.session.emit_err(InvalidVisibility { self.session.emit_err(InvalidVisibility {
span: vis.span, span: vis.span,
implied: if vis.kind.is_pub() { Some(vis.span) } else { None }, implied: vis.kind.is_pub().then_some(vis.span),
note, note,
}); });
} }

View File

@ -1186,11 +1186,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
return None; return None;
}; };
debug!("checking call args for uses of inner_param: {:?}", args); debug!("checking call args for uses of inner_param: {:?}", args);
if args.contains(&Operand::Move(inner_param)) { args.contains(&Operand::Move(inner_param)).then_some((loc, term))
Some((loc, term))
} else {
None
}
}) else { }) else {
debug!("no uses of inner_param found as a by-move call arg"); debug!("no uses of inner_param found as a by-move call arg");
return; return;

View File

@ -280,17 +280,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
debug!("give_region_a_name: error_region = {:?}", error_region); debug!("give_region_a_name: error_region = {:?}", error_region);
match *error_region { match *error_region {
ty::ReEarlyBound(ebr) => { ty::ReEarlyBound(ebr) => ebr.has_name().then(|| {
if ebr.has_name() { let span = tcx.hir().span_if_local(ebr.def_id).unwrap_or(DUMMY_SP);
let span = tcx.hir().span_if_local(ebr.def_id).unwrap_or(DUMMY_SP); RegionName { name: ebr.name, source: RegionNameSource::NamedEarlyBoundRegion(span) }
Some(RegionName { }),
name: ebr.name,
source: RegionNameSource::NamedEarlyBoundRegion(span),
})
} else {
None
}
}
ty::ReStatic => { ty::ReStatic => {
Some(RegionName { name: kw::StaticLifetime, source: RegionNameSource::Static }) Some(RegionName { name: kw::StaticLifetime, source: RegionNameSource::Static })

View File

@ -50,13 +50,11 @@ pub(super) fn generate<'mir, 'tcx>(
compute_relevant_live_locals(typeck.tcx(), &free_regions, &body); compute_relevant_live_locals(typeck.tcx(), &free_regions, &body);
let facts_enabled = use_polonius || AllFacts::enabled(typeck.tcx()); let facts_enabled = use_polonius || AllFacts::enabled(typeck.tcx());
let polonius_drop_used = if facts_enabled { let polonius_drop_used = facts_enabled.then(|| {
let mut drop_used = Vec::new(); let mut drop_used = Vec::new();
polonius::populate_access_facts(typeck, body, location_table, move_data, &mut drop_used); polonius::populate_access_facts(typeck, body, location_table, move_data, &mut drop_used);
Some(drop_used) drop_used
} else { });
None
};
trace::trace( trace::trace(
typeck, typeck,

View File

@ -135,19 +135,17 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
} }
// `let names: &'static _ = &["field1", "field2"];` // `let names: &'static _ = &["field1", "field2"];`
let names_let = if is_struct { let names_let = is_struct.then(|| {
let lt_static = Some(cx.lifetime_static(span)); let lt_static = Some(cx.lifetime_static(span));
let ty_static_ref = cx.ty_ref(span, cx.ty_infer(span), lt_static, ast::Mutability::Not); let ty_static_ref = cx.ty_ref(span, cx.ty_infer(span), lt_static, ast::Mutability::Not);
Some(cx.stmt_let_ty( cx.stmt_let_ty(
span, span,
false, false,
Ident::new(sym::names, span), Ident::new(sym::names, span),
Some(ty_static_ref), Some(ty_static_ref),
cx.expr_array_ref(span, name_exprs), cx.expr_array_ref(span, name_exprs),
)) )
} else { });
None
};
// `let values: &[&dyn Debug] = &[&&self.field1, &&self.field2];` // `let values: &[&dyn Debug] = &[&&self.field1, &&self.field2];`
let path_debug = cx.path_global(span, cx.std_path(&[sym::fmt, sym::Debug])); let path_debug = cx.path_global(span, cx.std_path(&[sym::fmt, sym::Debug]));

View File

@ -942,13 +942,11 @@ impl<'a> MethodDef<'a> {
let mut nonself_arg_tys = Vec::new(); let mut nonself_arg_tys = Vec::new();
let span = trait_.span; let span = trait_.span;
let explicit_self = if self.explicit_self { let explicit_self = self.explicit_self.then(|| {
let (self_expr, explicit_self) = ty::get_explicit_self(cx, span); let (self_expr, explicit_self) = ty::get_explicit_self(cx, span);
selflike_args.push(self_expr); selflike_args.push(self_expr);
Some(explicit_self) explicit_self
} else { });
None
};
for (ty, name) in self.nonself_args.iter() { for (ty, name) in self.nonself_args.iter() {
let ast_ty = ty.to_ty(cx, span, type_ident, generics); let ast_ty = ty.to_ty(cx, span, type_ident, generics);

View File

@ -62,7 +62,7 @@ pub fn inject(
// the one with the prelude. // the one with the prelude.
let name = names[0]; let name = names[0];
let root = (edition == Edition2015).then(|| kw::PathRoot); let root = (edition == Edition2015).then_some(kw::PathRoot);
let import_path = root let import_path = root
.iter() .iter()

View File

@ -248,17 +248,13 @@ fn reuse_workproduct_for_cgu(
dwarf_object: None, dwarf_object: None,
bytecode: None, bytecode: None,
}, },
module_global_asm: if has_global_asm { module_global_asm: has_global_asm.then(|| CompiledModule {
Some(CompiledModule { name: cgu.name().to_string(),
name: cgu.name().to_string(), kind: ModuleKind::Regular,
kind: ModuleKind::Regular, object: Some(obj_out_global_asm),
object: Some(obj_out_global_asm), dwarf_object: None,
dwarf_object: None, bytecode: None,
bytecode: None, }),
})
} else {
None
},
existing_work_product: Some((cgu.work_product_id(), work_product)), existing_work_product: Some((cgu.work_product_id(), work_product)),
}) })
} }

View File

@ -412,11 +412,7 @@ fn get_pgo_sample_use_path(config: &ModuleConfig) -> Option<CString> {
} }
fn get_instr_profile_output_path(config: &ModuleConfig) -> Option<CString> { fn get_instr_profile_output_path(config: &ModuleConfig) -> Option<CString> {
if config.instrument_coverage { config.instrument_coverage.then(|| CString::new("default_%m_%p.profraw").unwrap())
Some(CString::new("default_%m_%p.profraw").unwrap())
} else {
None
}
} }
pub(crate) unsafe fn llvm_optimize( pub(crate) unsafe fn llvm_optimize(
@ -451,11 +447,10 @@ pub(crate) unsafe fn llvm_optimize(
None None
}; };
let mut llvm_profiler = if cgcx.prof.llvm_recording_enabled() { let mut llvm_profiler = cgcx
Some(LlvmSelfProfiler::new(cgcx.prof.get_self_profiler().unwrap())) .prof
} else { .llvm_recording_enabled()
None .then(|| LlvmSelfProfiler::new(cgcx.prof.get_self_profiler().unwrap()));
};
let llvm_selfprofiler = let llvm_selfprofiler =
llvm_profiler.as_mut().map(|s| s as *mut _ as *mut c_void).unwrap_or(std::ptr::null_mut()); llvm_profiler.as_mut().map(|s| s as *mut _ as *mut c_void).unwrap_or(std::ptr::null_mut());

View File

@ -402,12 +402,8 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
let (llcx, llmod) = (&*llvm_module.llcx, llvm_module.llmod()); let (llcx, llmod) = (&*llvm_module.llcx, llvm_module.llmod());
let coverage_cx = if tcx.sess.instrument_coverage() { let coverage_cx =
let covctx = coverageinfo::CrateCoverageContext::new(); tcx.sess.instrument_coverage().then(coverageinfo::CrateCoverageContext::new);
Some(covctx)
} else {
None
};
let dbg_cx = if tcx.sess.opts.debuginfo != DebugInfo::None { let dbg_cx = if tcx.sess.opts.debuginfo != DebugInfo::None {
let dctx = debuginfo::CodegenUnitDebugContext::new(llmod); let dctx = debuginfo::CodegenUnitDebugContext::new(llmod);

View File

@ -154,7 +154,7 @@ fn struct_llfields<'a, 'tcx>(
} else { } else {
debug!("struct_llfields: offset: {:?} stride: {:?}", offset, layout.size); debug!("struct_llfields: offset: {:?} stride: {:?}", offset, layout.size);
} }
let field_remapping = if padding_used { Some(field_remapping) } else { None }; let field_remapping = padding_used.then_some(field_remapping);
(result, packed, field_remapping) (result, packed, field_remapping)
} }

View File

@ -2024,7 +2024,7 @@ fn linker_with_args<'a>(
.native_libraries .native_libraries
.iter() .iter()
.filter_map(|(cnum, libraries)| { .filter_map(|(cnum, libraries)| {
(dependency_linkage[cnum.as_usize() - 1] != Linkage::Static).then(|| libraries) (dependency_linkage[cnum.as_usize() - 1] != Linkage::Static).then_some(libraries)
}) })
.flatten(); .flatten();
for (raw_dylib_name, raw_dylib_imports) in for (raw_dylib_name, raw_dylib_imports) in

View File

@ -579,7 +579,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
} }
} }
let metadata_module = if need_metadata_module { let metadata_module = need_metadata_module.then(|| {
// Emit compressed metadata object. // Emit compressed metadata object.
let metadata_cgu_name = let metadata_cgu_name =
cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("metadata")).to_string(); cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("metadata")).to_string();
@ -594,17 +594,15 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
if let Err(error) = std::fs::write(&file_name, data) { if let Err(error) = std::fs::write(&file_name, data) {
tcx.sess.emit_fatal(errors::MetadataObjectFileWrite { error }); tcx.sess.emit_fatal(errors::MetadataObjectFileWrite { error });
} }
Some(CompiledModule { CompiledModule {
name: metadata_cgu_name, name: metadata_cgu_name,
kind: ModuleKind::Metadata, kind: ModuleKind::Metadata,
object: Some(file_name), object: Some(file_name),
dwarf_object: None, dwarf_object: None,
bytecode: None, bytecode: None,
}) }
}) })
} else { });
None
};
let ongoing_codegen = start_async_codegen( let ongoing_codegen = start_async_codegen(
backend.clone(), backend.clone(),

View File

@ -167,8 +167,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
start_bx.set_personality_fn(cx.eh_personality()); start_bx.set_personality_fn(cx.eh_personality());
} }
let cleanup_kinds = let cleanup_kinds = base::wants_msvc_seh(cx.tcx().sess).then(|| analyze::cleanup_kinds(&mir));
if base::wants_msvc_seh(cx.tcx().sess) { Some(analyze::cleanup_kinds(&mir)) } else { None };
let cached_llbbs: IndexVec<mir::BasicBlock, CachedLlbb<Bx::BasicBlock>> = let cached_llbbs: IndexVec<mir::BasicBlock, CachedLlbb<Bx::BasicBlock>> =
mir.basic_blocks mir.basic_blocks

View File

@ -207,8 +207,7 @@ impl SelfProfilerRef {
/// a measureme event, "verbose" generic activities also print a timing entry to /// a measureme event, "verbose" generic activities also print a timing entry to
/// stderr if the compiler is invoked with -Ztime-passes. /// stderr if the compiler is invoked with -Ztime-passes.
pub fn verbose_generic_activity(&self, event_label: &'static str) -> VerboseTimingGuard<'_> { pub fn verbose_generic_activity(&self, event_label: &'static str) -> VerboseTimingGuard<'_> {
let message = let message = self.print_verbose_generic_activities.then(|| event_label.to_owned());
if self.print_verbose_generic_activities { Some(event_label.to_owned()) } else { None };
VerboseTimingGuard::start(message, self.generic_activity(event_label)) VerboseTimingGuard::start(message, self.generic_activity(event_label))
} }
@ -222,11 +221,9 @@ impl SelfProfilerRef {
where where
A: Borrow<str> + Into<String>, A: Borrow<str> + Into<String>,
{ {
let message = if self.print_verbose_generic_activities { let message = self
Some(format!("{}({})", event_label, event_arg.borrow())) .print_verbose_generic_activities
} else { .then(|| format!("{}({})", event_label, event_arg.borrow()));
None
};
VerboseTimingGuard::start(message, self.generic_activity_with_arg(event_label, event_arg)) VerboseTimingGuard::start(message, self.generic_activity_with_arg(event_label, event_arg))
} }

View File

@ -1768,7 +1768,7 @@ impl EmitterWriter {
// Render the replacements for each suggestion // Render the replacements for each suggestion
let suggestions = suggestion.splice_lines(sm); let suggestions = suggestion.splice_lines(sm);
debug!("emit_suggestion_default: suggestions={:?}", suggestions); debug!(?suggestions);
if suggestions.is_empty() { if suggestions.is_empty() {
// Suggestions coming from macros can have malformed spans. This is a heavy handed // Suggestions coming from macros can have malformed spans. This is a heavy handed
@ -1797,6 +1797,7 @@ impl EmitterWriter {
for (complete, parts, highlights, only_capitalization) in for (complete, parts, highlights, only_capitalization) in
suggestions.iter().take(MAX_SUGGESTIONS) suggestions.iter().take(MAX_SUGGESTIONS)
{ {
debug!(?complete, ?parts, ?highlights);
notice_capitalization |= only_capitalization; notice_capitalization |= only_capitalization;
let has_deletion = parts.iter().any(|p| p.is_deletion(sm)); let has_deletion = parts.iter().any(|p| p.is_deletion(sm));

View File

@ -1066,29 +1066,26 @@ impl Handler {
} }
pub fn has_errors(&self) -> Option<ErrorGuaranteed> { pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
if self.inner.borrow().has_errors() { Some(ErrorGuaranteed(())) } else { None } self.inner.borrow().has_errors().then(ErrorGuaranteed::unchecked_claim_error_was_emitted)
} }
pub fn has_errors_or_lint_errors(&self) -> Option<ErrorGuaranteed> { pub fn has_errors_or_lint_errors(&self) -> Option<ErrorGuaranteed> {
if self.inner.borrow().has_errors_or_lint_errors() { self.inner
Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()) .borrow()
} else { .has_errors_or_lint_errors()
None .then(ErrorGuaranteed::unchecked_claim_error_was_emitted)
}
} }
pub fn has_errors_or_delayed_span_bugs(&self) -> Option<ErrorGuaranteed> { pub fn has_errors_or_delayed_span_bugs(&self) -> Option<ErrorGuaranteed> {
if self.inner.borrow().has_errors_or_delayed_span_bugs() { self.inner
Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()) .borrow()
} else { .has_errors_or_delayed_span_bugs()
None .then(ErrorGuaranteed::unchecked_claim_error_was_emitted)
}
} }
pub fn is_compilation_going_to_fail(&self) -> Option<ErrorGuaranteed> { pub fn is_compilation_going_to_fail(&self) -> Option<ErrorGuaranteed> {
if self.inner.borrow().is_compilation_going_to_fail() { self.inner
Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()) .borrow()
} else { .is_compilation_going_to_fail()
None .then(ErrorGuaranteed::unchecked_claim_error_was_emitted)
}
} }
pub fn print_error_count(&self, registry: &Registry) { pub fn print_error_count(&self, registry: &Registry) {

View File

@ -238,12 +238,10 @@ macro_rules! configure {
impl<'a> StripUnconfigured<'a> { impl<'a> StripUnconfigured<'a> {
pub fn configure<T: HasAttrs + HasTokens>(&self, mut node: T) -> Option<T> { pub fn configure<T: HasAttrs + HasTokens>(&self, mut node: T) -> Option<T> {
self.process_cfg_attrs(&mut node); self.process_cfg_attrs(&mut node);
if self.in_cfg(node.attrs()) { self.in_cfg(node.attrs()).then(|| {
self.try_configure_tokens(&mut node); self.try_configure_tokens(&mut node);
Some(node) node
} else { })
None
}
} }
fn try_configure_tokens<T: HasTokens>(&self, node: &mut T) { fn try_configure_tokens<T: HasTokens>(&self, node: &mut T) {
@ -257,7 +255,7 @@ impl<'a> StripUnconfigured<'a> {
fn configure_krate_attrs(&self, mut attrs: ast::AttrVec) -> Option<ast::AttrVec> { fn configure_krate_attrs(&self, mut attrs: ast::AttrVec) -> Option<ast::AttrVec> {
attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr)); attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
if self.in_cfg(&attrs) { Some(attrs) } else { None } self.in_cfg(&attrs).then_some(attrs)
} }
/// Performs cfg-expansion on `stream`, producing a new `AttrTokenStream`. /// Performs cfg-expansion on `stream`, producing a new `AttrTokenStream`.

View File

@ -164,8 +164,6 @@ declare_features! (
(active, multiple_supertrait_upcastable, "CURRENT_RUSTC_VERSION", None, None), (active, multiple_supertrait_upcastable, "CURRENT_RUSTC_VERSION", None, None),
/// Allows using `#[omit_gdb_pretty_printer_section]`. /// Allows using `#[omit_gdb_pretty_printer_section]`.
(active, omit_gdb_pretty_printer_section, "1.5.0", None, None), (active, omit_gdb_pretty_printer_section, "1.5.0", None, None),
/// Allows using `+bundled,+whole-archive` native libs.
(active, packed_bundled_libs, "1.67.0", None, None),
/// Allows using `#[prelude_import]` on glob `use` items. /// Allows using `#[prelude_import]` on glob `use` items.
(active, prelude_import, "1.2.0", None, None), (active, prelude_import, "1.2.0", None, None),
/// Used to identify crates that contain the profiler runtime. /// Used to identify crates that contain the profiler runtime.
@ -217,6 +215,8 @@ declare_features! (
(active, linkage, "1.0.0", Some(29603), None), (active, linkage, "1.0.0", Some(29603), None),
/// Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed. /// Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed.
(active, needs_panic_runtime, "1.10.0", Some(32837), None), (active, needs_panic_runtime, "1.10.0", Some(32837), None),
/// Allows using `+bundled,+whole-archive` native libs.
(active, packed_bundled_libs, "CURRENT_RUSTC_VERSION", Some(108081), None),
/// Allows using the `#![panic_runtime]` attribute. /// Allows using the `#![panic_runtime]` attribute.
(active, panic_runtime, "1.10.0", Some(32837), None), (active, panic_runtime, "1.10.0", Some(32837), None),
/// Allows using `#[rustc_allow_const_fn_unstable]`. /// Allows using `#[rustc_allow_const_fn_unstable]`.

View File

@ -574,14 +574,11 @@ impl<'hir> Generics<'hir> {
/// If there are generic parameters, return where to introduce a new one. /// If there are generic parameters, return where to introduce a new one.
pub fn span_for_param_suggestion(&self) -> Option<Span> { pub fn span_for_param_suggestion(&self) -> Option<Span> {
if self.params.iter().any(|p| self.span.contains(p.span)) { self.params.iter().any(|p| self.span.contains(p.span)).then(|| {
// `fn foo<A>(t: impl Trait)` // `fn foo<A>(t: impl Trait)`
// ^ suggest `, T: Trait` here // ^ suggest `, T: Trait` here
let span = self.span.with_lo(self.span.hi() - BytePos(1)).shrink_to_lo(); self.span.with_lo(self.span.hi() - BytePos(1)).shrink_to_lo()
Some(span) })
} else {
None
}
} }
/// `Span` where further predicates would be suggested, accounting for trailing commas, like /// `Span` where further predicates would be suggested, accounting for trailing commas, like
@ -639,7 +636,7 @@ impl<'hir> Generics<'hir> {
// We include bounds that come from a `#[derive(_)]` but point at the user's code, // We include bounds that come from a `#[derive(_)]` but point at the user's code,
// as we use this method to get a span appropriate for suggestions. // as we use this method to get a span appropriate for suggestions.
let bs = bound.span(); let bs = bound.span();
if bs.can_be_used_for_suggestions() { Some(bs.shrink_to_hi()) } else { None } bs.can_be_used_for_suggestions().then(|| bs.shrink_to_hi())
}, },
) )
} }

View File

@ -259,13 +259,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
} }
TraitItemKind::Const(ty, body_id) => body_id TraitItemKind::Const(ty, body_id) => body_id
.and_then(|body_id| { .and_then(|body_id| {
if is_suggestable_infer_ty(ty) { is_suggestable_infer_ty(ty)
Some(infer_placeholder_type( .then(|| infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant",))
tcx, def_id, body_id, ty.span, item.ident, "constant",
))
} else {
None
}
}) })
.unwrap_or_else(|| icx.to_ty(ty)), .unwrap_or_else(|| icx.to_ty(ty)),
TraitItemKind::Type(_, Some(ty)) => icx.to_ty(ty), TraitItemKind::Type(_, Some(ty)) => icx.to_ty(ty),

View File

@ -204,7 +204,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
match tcx.hir().find(hir_id) { match tcx.hir().find(hir_id) {
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => { Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => {
generics.params.is_empty().not().then(|| generics.span) generics.params.is_empty().not().then_some(generics.span)
} }
_ => { _ => {
span_bug!(tcx.def_span(def_id), "main has a non-function type"); span_bug!(tcx.def_span(def_id), "main has a non-function type");

View File

@ -74,15 +74,13 @@ pub(super) fn check_fn<'a, 'tcx>(
// C-variadic fns also have a `VaList` input that's not listed in `fn_sig` // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
// (as it's created inside the body itself, not passed in from outside). // (as it's created inside the body itself, not passed in from outside).
let maybe_va_list = if fn_sig.c_variadic { let maybe_va_list = fn_sig.c_variadic.then(|| {
let span = body.params.last().unwrap().span; let span = body.params.last().unwrap().span;
let va_list_did = tcx.require_lang_item(LangItem::VaList, Some(span)); let va_list_did = tcx.require_lang_item(LangItem::VaList, Some(span));
let region = fcx.next_region_var(RegionVariableOrigin::MiscVariable(span)); let region = fcx.next_region_var(RegionVariableOrigin::MiscVariable(span));
Some(tcx.bound_type_of(va_list_did).subst(tcx, &[region.into()])) tcx.bound_type_of(va_list_did).subst(tcx, &[region.into()])
} else { });
None
};
// Add formal parameters. // Add formal parameters.
let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs); let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs);

View File

@ -1046,7 +1046,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.param_env, self.param_env,
) )
.may_apply() .may_apply()
.then(|| deref_ty) .then_some(deref_ty)
}) })
} }

View File

@ -477,12 +477,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// This is the "trait" (meaning, the predicate "proved" by this `impl`) which provides the `Self` type we care about. // This is the "trait" (meaning, the predicate "proved" by this `impl`) which provides the `Self` type we care about.
// For the purposes of this function, we hope that it is a `struct` type, and that our current `expr` is a literal of // For the purposes of this function, we hope that it is a `struct` type, and that our current `expr` is a literal of
// that struct type. // that struct type.
let impl_trait_self_ref: Option<ty::TraitRef<'tcx>> = let impl_trait_self_ref = if self.tcx.is_trait_alias(obligation.impl_def_id) {
self.tcx.impl_trait_ref(obligation.impl_def_id).map(|impl_def| impl_def.skip_binder()); self.tcx.mk_trait_ref(
obligation.impl_def_id,
let Some(impl_trait_self_ref) = impl_trait_self_ref else { ty::InternalSubsts::identity_for_item(self.tcx, obligation.impl_def_id),
// It is possible that this is absent. In this case, we make no progress. )
return Err(expr); } else {
self.tcx
.impl_trait_ref(obligation.impl_def_id)
.map(|impl_def| impl_def.skip_binder())
// It is possible that this is absent. In this case, we make no progress.
.ok_or(expr)?
}; };
// We only really care about the `Self` type itself, which we extract from the ref. // We only really care about the `Self` type itself, which we extract from the ref.

View File

@ -755,15 +755,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
errors.drain_filter(|error| { errors.drain_filter(|error| {
let Error::Invalid(provided_idx, expected_idx, Compatibility::Incompatible(Some(e))) = error else { return false }; let Error::Invalid(
let (provided_ty, provided_span) = provided_arg_tys[*provided_idx]; provided_idx,
let trace = mk_trace(provided_span, formal_and_expected_inputs[*expected_idx], provided_ty); expected_idx,
if !matches!(trace.cause.as_failure_code(*e), FailureCode::Error0308(_)) { Compatibility::Incompatible(Some(e)),
self.err_ctxt().report_and_explain_type_error(trace, *e).emit(); ) = error else { return false };
return true; let (provided_ty, provided_span) = provided_arg_tys[*provided_idx];
} let trace =
false mk_trace(provided_span, formal_and_expected_inputs[*expected_idx], provided_ty);
}); if !matches!(trace.cause.as_failure_code(*e), FailureCode::Error0308(_)) {
self.err_ctxt().report_and_explain_type_error(trace, *e).emit();
return true;
}
false
});
// We're done if we found errors, but we already emitted them. // We're done if we found errors, but we already emitted them.
if errors.is_empty() { if errors.is_empty() {
@ -864,7 +869,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
let mut suggestion_text = SuggestionText::None; let mut suggestion_text = SuggestionText::None;
let ty_to_snippet = |ty: Ty<'tcx>, expected_idx: ExpectedIdx| {
if ty.is_unit() {
"()".to_string()
} else if ty.is_suggestable(tcx, false) {
format!("/* {} */", ty)
} else if let Some(fn_def_id) = fn_def_id
&& self.tcx.def_kind(fn_def_id).is_fn_like()
&& let self_implicit =
matches!(call_expr.kind, hir::ExprKind::MethodCall(..)) as usize
&& let Some(arg) = self.tcx.fn_arg_names(fn_def_id)
.get(expected_idx.as_usize() + self_implicit)
&& arg.name != kw::SelfLower
{
format!("/* {} */", arg.name)
} else {
"/* value */".to_string()
}
};
let mut errors = errors.into_iter().peekable(); let mut errors = errors.into_iter().peekable();
let mut suggestions = vec![];
while let Some(error) = errors.next() { while let Some(error) = errors.next() {
match error { match error {
Error::Invalid(provided_idx, expected_idx, compatibility) => { Error::Invalid(provided_idx, expected_idx, compatibility) => {
@ -905,7 +930,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
"".to_string() "".to_string()
}; };
labels labels
.push((provided_span, format!("argument{} unexpected", provided_ty_name))); .push((provided_span, format!("unexpected argument{}", provided_ty_name)));
let mut span = provided_span;
if arg_idx.index() > 0
&& let Some((_, prev)) = provided_arg_tys
.get(ProvidedIdx::from_usize(arg_idx.index() - 1)
) {
// Include previous comma
span = span.with_lo(prev.hi());
} else if let Some((_, next)) = provided_arg_tys.get(
ProvidedIdx::from_usize(arg_idx.index() + 1),
) {
// Include next comma
span = span.until(*next);
}
suggestions.push((span, String::new()));
suggestion_text = match suggestion_text { suggestion_text = match suggestion_text {
SuggestionText::None => SuggestionText::Remove(false), SuggestionText::None => SuggestionText::Remove(false),
SuggestionText::Remove(_) => SuggestionText::Remove(true), SuggestionText::Remove(_) => SuggestionText::Remove(true),
@ -1095,6 +1135,45 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
// Incorporate the argument changes in the removal suggestion.
// When a type is *missing*, and the rest are additional, we want to suggest these with a
// multipart suggestion, but in order to do so we need to figure out *where* the arg that
// was provided but had the wrong type should go, because when looking at `expected_idx`
// that is the position in the argument list in the definition, while `provided_idx` will
// not be present. So we have to look at what the *last* provided position was, and point
// one after to suggest the replacement. FIXME(estebank): This is hacky, and there's
// probably a better more involved change we can make to make this work.
// For example, if we have
// ```
// fn foo(i32, &'static str) {}
// foo((), (), ());
// ```
// what should be suggested is
// ```
// foo(/* i32 */, /* &str */);
// ```
// which includes the replacement of the first two `()` for the correct type, and the
// removal of the last `()`.
let mut prev = -1;
for (expected_idx, provided_idx) in matched_inputs.iter_enumerated() {
// We want to point not at the *current* argument expression index, but rather at the
// index position where it *should have been*, which is *after* the previous one.
if let Some(provided_idx) = provided_idx {
prev = provided_idx.index() as i64;
}
let idx = ProvidedIdx::from_usize((prev + 1) as usize);
if let None = provided_idx
&& let Some((_, arg_span)) = provided_arg_tys.get(idx)
{
// There is a type that was *not* found anywhere, so it isn't a move, but a
// replacement and we look at what type it should have been. This will allow us
// To suggest a multipart suggestion when encountering `foo(1, "")` where the def
// was `fn foo(())`.
let (_, expected_ty) = formal_and_expected_inputs[expected_idx];
suggestions.push((*arg_span, ty_to_snippet(expected_ty, expected_idx)));
}
}
// If we have less than 5 things to say, it would be useful to call out exactly what's wrong // If we have less than 5 things to say, it would be useful to call out exactly what's wrong
if labels.len() <= 5 { if labels.len() <= 5 {
for (span, label) in labels { for (span, label) in labels {
@ -1112,7 +1191,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Some(format!("provide the argument{}", if plural { "s" } else { "" })) Some(format!("provide the argument{}", if plural { "s" } else { "" }))
} }
SuggestionText::Remove(plural) => { SuggestionText::Remove(plural) => {
Some(format!("remove the extra argument{}", if plural { "s" } else { "" })) err.multipart_suggestion(
&format!("remove the extra argument{}", if plural { "s" } else { "" }),
suggestions,
Applicability::HasPlaceholders,
);
None
} }
SuggestionText::Swap => Some("swap these arguments".to_string()), SuggestionText::Swap => Some("swap these arguments".to_string()),
SuggestionText::Reorder => Some("reorder these arguments".to_string()), SuggestionText::Reorder => Some("reorder these arguments".to_string()),
@ -1151,20 +1235,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} else { } else {
// Propose a placeholder of the correct type // Propose a placeholder of the correct type
let (_, expected_ty) = formal_and_expected_inputs[expected_idx]; let (_, expected_ty) = formal_and_expected_inputs[expected_idx];
if expected_ty.is_unit() { ty_to_snippet(expected_ty, expected_idx)
"()".to_string()
} else if expected_ty.is_suggestable(tcx, false) {
format!("/* {} */", expected_ty)
} else if let Some(fn_def_id) = fn_def_id
&& self.tcx.def_kind(fn_def_id).is_fn_like()
&& let self_implicit = matches!(call_expr.kind, hir::ExprKind::MethodCall(..)) as usize
&& let Some(arg) = self.tcx.fn_arg_names(fn_def_id).get(expected_idx.as_usize() + self_implicit)
&& arg.name != kw::SelfLower
{
format!("/* {} */", arg.name)
} else {
"/* value */".to_string()
}
}; };
suggestion += &suggestion_text; suggestion += &suggestion_text;
} }

View File

@ -274,12 +274,10 @@ pub fn resolve_interior<'a, 'tcx>(
let r = fcx.tcx.mk_re_late_bound(current_depth, br); let r = fcx.tcx.mk_re_late_bound(current_depth, br);
r r
}); });
if captured_tys.insert(ty) { captured_tys.insert(ty).then(|| {
cause.ty = ty; cause.ty = ty;
Some(cause) cause
} else { })
None
}
}) })
.collect(); .collect();

View File

@ -90,20 +90,18 @@ pub fn find_param_with_region<'tcx>(
r r
} }
}); });
if found_anon_region { found_anon_region.then(|| {
let ty_hir_id = fn_decl.inputs[index].hir_id; let ty_hir_id = fn_decl.inputs[index].hir_id;
let param_ty_span = hir.span(ty_hir_id); let param_ty_span = hir.span(ty_hir_id);
let is_first = index == 0; let is_first = index == 0;
Some(AnonymousParamInfo { AnonymousParamInfo {
param, param,
param_ty: new_param_ty, param_ty: new_param_ty,
param_ty_span, param_ty_span,
bound_region, bound_region,
is_first, is_first,
}) }
} else { })
None
}
}) })
} }

View File

@ -2308,11 +2308,8 @@ impl EarlyLintPass for IncompleteFeatures {
.for_each(|(&name, &span)| { .for_each(|(&name, &span)| {
let note = rustc_feature::find_feature_issue(name, GateIssue::Language) let note = rustc_feature::find_feature_issue(name, GateIssue::Language)
.map(|n| BuiltinIncompleteFeaturesNote { n }); .map(|n| BuiltinIncompleteFeaturesNote { n });
let help = if HAS_MIN_FEATURES.contains(&name) { let help =
Some(BuiltinIncompleteFeaturesHelp) HAS_MIN_FEATURES.contains(&name).then_some(BuiltinIncompleteFeaturesHelp);
} else {
None
};
cx.emit_spanned_lint( cx.emit_spanned_lint(
INCOMPLETE_FEATURES, INCOMPLETE_FEATURES,
span, span,

View File

@ -487,7 +487,7 @@ impl LintStore {
let mut groups: Vec<_> = self let mut groups: Vec<_> = self
.lint_groups .lint_groups
.iter() .iter()
.filter_map(|(k, LintGroup { depr, .. })| if depr.is_none() { Some(k) } else { None }) .filter_map(|(k, LintGroup { depr, .. })| depr.is_none().then_some(k))
.collect(); .collect();
groups.sort(); groups.sort();
let groups = groups.iter().map(|k| Symbol::intern(k)); let groups = groups.iter().map(|k| Symbol::intern(k));
@ -1112,11 +1112,9 @@ impl<'tcx> LateContext<'tcx> {
.maybe_typeck_results() .maybe_typeck_results()
.filter(|typeck_results| typeck_results.hir_owner == id.owner) .filter(|typeck_results| typeck_results.hir_owner == id.owner)
.or_else(|| { .or_else(|| {
if self.tcx.has_typeck_results(id.owner.to_def_id()) { self.tcx
Some(self.tcx.typeck(id.owner.def_id)) .has_typeck_results(id.owner.to_def_id())
} else { .then(|| self.tcx.typeck(id.owner.def_id))
None
}
}) })
.and_then(|typeck_results| typeck_results.type_dependent_def(id)) .and_then(|typeck_results| typeck_results.type_dependent_def(id))
.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)), .map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)),

View File

@ -65,11 +65,8 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles {
} else { } else {
ForLoopsOverFalliblesLoopSub::UseWhileLet { start_span: expr.span.with_hi(pat.span.lo()), end_span: pat.span.between(arg.span), var } ForLoopsOverFalliblesLoopSub::UseWhileLet { start_span: expr.span.with_hi(pat.span.lo()), end_span: pat.span.between(arg.span), var }
} ; } ;
let question_mark = if suggest_question_mark(cx, adt, substs, expr.span) { let question_mark = suggest_question_mark(cx, adt, substs, expr.span)
Some(ForLoopsOverFalliblesQuestionMark { suggestion: arg.span.shrink_to_hi() }) .then(|| ForLoopsOverFalliblesQuestionMark { suggestion: arg.span.shrink_to_hi() });
} else {
None
};
let suggestion = ForLoopsOverFalliblesSuggestion { let suggestion = ForLoopsOverFalliblesSuggestion {
var, var,
start_span: expr.span.with_hi(pat.span.lo()), start_span: expr.span.with_hi(pat.span.lo()),

View File

@ -1062,7 +1062,7 @@ impl<'hir> Map<'hir> {
} }
pub fn span_if_local(self, id: DefId) -> Option<Span> { pub fn span_if_local(self, id: DefId) -> Option<Span> {
if id.is_local() { Some(self.tcx.def_span(id)) } else { None } id.is_local().then(|| self.tcx.def_span(id))
} }
pub fn res_span(self, res: Res) -> Option<Span> { pub fn res_span(self, res: Res) -> Option<Span> {

View File

@ -414,7 +414,7 @@ impl<'tcx> Body<'tcx> {
(self.arg_count + 1..self.local_decls.len()).filter_map(move |index| { (self.arg_count + 1..self.local_decls.len()).filter_map(move |index| {
let local = Local::new(index); let local = Local::new(index);
let decl = &self.local_decls[local]; let decl = &self.local_decls[local];
(decl.is_user_variable() && decl.mutability.is_mut()).then(|| local) (decl.is_user_variable() && decl.mutability.is_mut()).then_some(local)
}) })
} }

View File

@ -1154,13 +1154,11 @@ impl<'tcx> TyCtxt<'tcx> {
ty::FnDef(_, _) => { ty::FnDef(_, _) => {
let sig = ret_ty.fn_sig(self); let sig = ret_ty.fn_sig(self);
let output = self.erase_late_bound_regions(sig.output()); let output = self.erase_late_bound_regions(sig.output());
if output.is_impl_trait() { output.is_impl_trait().then(|| {
let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id); let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
let fn_decl = self.hir().fn_decl_by_hir_id(hir_id).unwrap(); let fn_decl = self.hir().fn_decl_by_hir_id(hir_id).unwrap();
Some((output, fn_decl.output.span())) (output, fn_decl.output.span())
} else { })
None
}
} }
_ => None, _ => None,
} }
@ -1266,13 +1264,12 @@ macro_rules! nop_lift {
impl<'a, 'tcx> Lift<'tcx> for $ty { impl<'a, 'tcx> Lift<'tcx> for $ty {
type Lifted = $lifted; type Lifted = $lifted;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
if tcx.interners.$set.contains_pointer_to(&InternedInSet(&*self.0.0)) { tcx.interners
.$set
.contains_pointer_to(&InternedInSet(&*self.0.0))
// SAFETY: `self` is interned and therefore valid // SAFETY: `self` is interned and therefore valid
// for the entire lifetime of the `TyCtxt`. // for the entire lifetime of the `TyCtxt`.
Some(unsafe { mem::transmute(self) }) .then(|| unsafe { mem::transmute(self) })
} else {
None
}
} }
} }
}; };
@ -1287,13 +1284,13 @@ impl<'a, 'tcx> Lift<'tcx> for &'a List<Ty<'a>> {
if self.is_empty() { if self.is_empty() {
return Some(List::empty()); return Some(List::empty());
} }
if tcx.interners.substs.contains_pointer_to(&InternedInSet(self.as_substs())) {
tcx.interners
.substs
.contains_pointer_to(&InternedInSet(self.as_substs()))
// SAFETY: `self` is interned and therefore valid // SAFETY: `self` is interned and therefore valid
// for the entire lifetime of the `TyCtxt`. // for the entire lifetime of the `TyCtxt`.
Some(unsafe { mem::transmute::<&'a List<Ty<'a>>, &'tcx List<Ty<'tcx>>>(self) }) .then(|| unsafe { mem::transmute::<&'a List<Ty<'a>>, &'tcx List<Ty<'tcx>>>(self) })
} else {
None
}
} }
} }
@ -1305,11 +1302,10 @@ macro_rules! nop_list_lift {
if self.is_empty() { if self.is_empty() {
return Some(List::empty()); return Some(List::empty());
} }
if tcx.interners.$set.contains_pointer_to(&InternedInSet(self)) { tcx.interners
Some(unsafe { mem::transmute(self) }) .$set
} else { .contains_pointer_to(&InternedInSet(self))
None .then(|| unsafe { mem::transmute(self) })
}
} }
} }
}; };

View File

@ -584,7 +584,7 @@ impl<'tcx> Instance<'tcx> {
/// this function returns `None`, then the MIR body does not require substitution during /// this function returns `None`, then the MIR body does not require substitution during
/// codegen. /// codegen.
fn substs_for_mir_body(&self) -> Option<SubstsRef<'tcx>> { fn substs_for_mir_body(&self) -> Option<SubstsRef<'tcx>> {
if self.def.has_polymorphic_mir_body() { Some(self.substs) } else { None } self.def.has_polymorphic_mir_body().then_some(self.substs)
} }
pub fn subst_mir<T>(&self, tcx: TyCtxt<'tcx>, v: &T) -> T pub fn subst_mir<T>(&self, tcx: TyCtxt<'tcx>, v: &T) -> T

View File

@ -267,13 +267,11 @@ pub type SubstsRef<'tcx> = &'tcx InternalSubsts<'tcx>;
impl<'tcx> InternalSubsts<'tcx> { impl<'tcx> InternalSubsts<'tcx> {
/// Checks whether all elements of this list are types, if so, transmute. /// Checks whether all elements of this list are types, if so, transmute.
pub fn try_as_type_list(&'tcx self) -> Option<&'tcx List<Ty<'tcx>>> { pub fn try_as_type_list(&'tcx self) -> Option<&'tcx List<Ty<'tcx>>> {
if self.iter().all(|arg| matches!(arg.unpack(), GenericArgKind::Type(_))) { self.iter().all(|arg| matches!(arg.unpack(), GenericArgKind::Type(_))).then(|| {
assert_eq!(TYPE_TAG, 0); assert_eq!(TYPE_TAG, 0);
// SAFETY: All elements are types, see `List<Ty<'tcx>>::as_substs`. // SAFETY: All elements are types, see `List<Ty<'tcx>>::as_substs`.
Some(unsafe { &*(self as *const List<GenericArg<'tcx>> as *const List<Ty<'tcx>>) }) unsafe { &*(self as *const List<GenericArg<'tcx>> as *const List<Ty<'tcx>>) }
} else { })
None
}
} }
/// Interpret these substitutions as the substitutions of a closure type. /// Interpret these substitutions as the substitutions of a closure type.

View File

@ -319,7 +319,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// See the notes for `ExprKind::Array` in `as_rvalue` and for // See the notes for `ExprKind::Array` in `as_rvalue` and for
// `ExprKind::Borrow` above. // `ExprKind::Borrow` above.
let is_union = adt_def.is_union(); let is_union = adt_def.is_union();
let active_field_index = if is_union { Some(fields[0].name.index()) } else { None }; let active_field_index = is_union.then(|| fields[0].name.index());
let scope = this.local_scope(); let scope = this.local_scope();

View File

@ -563,14 +563,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let not_contained = let not_contained =
self.values_not_contained_in_range(&*range, options).unwrap_or(false); self.values_not_contained_in_range(&*range, options).unwrap_or(false);
if not_contained { not_contained.then(|| {
// No switch values are contained in the pattern range, // No switch values are contained in the pattern range,
// so the pattern can be matched only if this test fails. // so the pattern can be matched only if this test fails.
let otherwise = options.len(); options.len()
Some(otherwise) })
} else {
None
}
} }
(&TestKind::SwitchInt { .. }, _) => None, (&TestKind::SwitchInt { .. }, _) => None,

View File

@ -172,7 +172,7 @@ impl IntRange {
ty: Ty<'tcx>, ty: Ty<'tcx>,
end: &RangeEnd, end: &RangeEnd,
) -> Option<IntRange> { ) -> Option<IntRange> {
if Self::is_integral(ty) { Self::is_integral(ty).then(|| {
// Perform a shift if the underlying types are signed, // Perform a shift if the underlying types are signed,
// which makes the interval arithmetic simpler. // which makes the interval arithmetic simpler.
let bias = IntRange::signed_bias(tcx, ty); let bias = IntRange::signed_bias(tcx, ty);
@ -182,10 +182,8 @@ impl IntRange {
// This should have been caught earlier by E0030. // This should have been caught earlier by E0030.
bug!("malformed range pattern: {}..={}", lo, (hi - offset)); bug!("malformed range pattern: {}..={}", lo, (hi - offset));
} }
Some(IntRange { range: lo..=(hi - offset), bias }) IntRange { range: lo..=(hi - offset), bias }
} else { })
None
}
} }
// The return value of `signed_bias` should be XORed with an endpoint to encode/decode it. // The return value of `signed_bias` should be XORed with an endpoint to encode/decode it.

View File

@ -203,11 +203,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
if !lower_overflow && !higher_overflow { if !lower_overflow && !higher_overflow {
self.tcx.sess.emit_err(LowerRangeBoundMustBeLessThanOrEqualToUpper { self.tcx.sess.emit_err(LowerRangeBoundMustBeLessThanOrEqualToUpper {
span, span,
teach: if self.tcx.sess.teach(&error_code!(E0030)) { teach: self.tcx.sess.teach(&error_code!(E0030)).then_some(()),
Some(())
} else {
None
},
}); });
} }
PatKind::Wild PatKind::Wild

View File

@ -254,13 +254,7 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
) { ) {
// Compute the place that we are storing to, if any // Compute the place that we are storing to, if any
let destination = match &statement.kind { let destination = match &statement.kind {
StatementKind::Assign(assign) => { StatementKind::Assign(assign) => assign.1.is_safe_to_remove().then_some(assign.0),
if assign.1.is_safe_to_remove() {
Some(assign.0)
} else {
None
}
}
StatementKind::SetDiscriminant { place, .. } | StatementKind::Deinit(place) => { StatementKind::SetDiscriminant { place, .. } | StatementKind::Deinit(place) => {
Some(**place) Some(**place)
} }

View File

@ -111,11 +111,9 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> {
/// If the given predicate is the trait `fmt::Pointer`, returns the bound parameter type. /// If the given predicate is the trait `fmt::Pointer`, returns the bound parameter type.
fn is_pointer_trait(&self, bound: &PredicateKind<'tcx>) -> Option<Ty<'tcx>> { fn is_pointer_trait(&self, bound: &PredicateKind<'tcx>) -> Option<Ty<'tcx>> {
if let ty::PredicateKind::Clause(ty::Clause::Trait(predicate)) = bound { if let ty::PredicateKind::Clause(ty::Clause::Trait(predicate)) = bound {
if self.tcx.is_diagnostic_item(sym::Pointer, predicate.def_id()) { self.tcx
Some(predicate.trait_ref.self_ty()) .is_diagnostic_item(sym::Pointer, predicate.def_id())
} else { .then(|| predicate.trait_ref.self_ty())
None
}
} else { } else {
None None
} }

View File

@ -1283,22 +1283,16 @@ impl<'a> Parser<'a> {
} }
fn parse_delim_args_inner(&mut self) -> Option<DelimArgs> { fn parse_delim_args_inner(&mut self) -> Option<DelimArgs> {
if self.check(&token::OpenDelim(Delimiter::Parenthesis)) let delimited = self.check(&token::OpenDelim(Delimiter::Parenthesis))
|| self.check(&token::OpenDelim(Delimiter::Bracket)) || self.check(&token::OpenDelim(Delimiter::Bracket))
|| self.check(&token::OpenDelim(Delimiter::Brace)) || self.check(&token::OpenDelim(Delimiter::Brace));
{
match self.parse_token_tree() { delimited.then(|| {
// We've confirmed above that there is a delimiter so unwrapping is OK. // We've confirmed above that there is a delimiter so unwrapping is OK.
TokenTree::Delimited(dspan, delim, tokens) => Some(DelimArgs { let TokenTree::Delimited(dspan, delim, tokens) = self.parse_token_tree() else { unreachable!() };
dspan,
delim: MacDelimiter::from_token(delim).unwrap(), DelimArgs { dspan, delim: MacDelimiter::from_token(delim).unwrap(), tokens }
tokens, })
}),
_ => unreachable!(),
}
} else {
None
}
} }
fn parse_or_use_outer_attributes( fn parse_or_use_outer_attributes(

View File

@ -404,7 +404,7 @@ impl<'a> Parser<'a> {
let is_first_invocation = style == PathStyle::Expr; let is_first_invocation = style == PathStyle::Expr;
// Take a snapshot before attempting to parse - we can restore this later. // Take a snapshot before attempting to parse - we can restore this later.
let snapshot = if is_first_invocation { Some(self.clone()) } else { None }; let snapshot = is_first_invocation.then(|| self.clone());
debug!("parse_generic_args_with_leading_angle_bracket_recovery: (snapshotting)"); debug!("parse_generic_args_with_leading_angle_bracket_recovery: (snapshotting)");
match self.parse_angle_args(ty_generics) { match self.parse_angle_args(ty_generics) {

View File

@ -450,8 +450,7 @@ impl<'a> Parser<'a> {
fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> { fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {
let and_span = self.prev_token.span; let and_span = self.prev_token.span;
let mut opt_lifetime = let mut opt_lifetime = self.check_lifetime().then(|| self.expect_lifetime());
if self.check_lifetime() { Some(self.expect_lifetime()) } else { None };
let mut mutbl = self.parse_mutability(); let mut mutbl = self.parse_mutability();
if self.token.is_lifetime() && mutbl == Mutability::Mut && opt_lifetime.is_none() { if self.token.is_lifetime() && mutbl == Mutability::Mut && opt_lifetime.is_none() {
// A lifetime is invalid here: it would be part of a bare trait bound, which requires // A lifetime is invalid here: it would be part of a bare trait bound, which requires
@ -871,7 +870,7 @@ impl<'a> Parser<'a> {
None None
}; };
let maybe = if self.eat(&token::Question) { Some(self.prev_token.span) } else { None }; let maybe = self.eat(&token::Question).then_some(self.prev_token.span);
Ok(BoundModifiers { maybe, maybe_const }) Ok(BoundModifiers { maybe, maybe_const })
} }

View File

@ -835,7 +835,7 @@ impl<'a> Parser<'a> {
); );
} }
if found { Some(cur) } else { None } found.then_some(cur)
} }
fn suggest_format(&mut self) { fn suggest_format(&mut self) {

View File

@ -32,11 +32,8 @@ fn collect_item(tcx: TyCtxt<'_>, items: &mut DiagnosticItems, name: Symbol, item
if let Some(original_def_id) = items.name_to_id.insert(name, item_def_id) { if let Some(original_def_id) = items.name_to_id.insert(name, item_def_id) {
if original_def_id != item_def_id { if original_def_id != item_def_id {
let orig_span = tcx.hir().span_if_local(original_def_id); let orig_span = tcx.hir().span_if_local(original_def_id);
let orig_crate_name = if orig_span.is_some() { let orig_crate_name =
None orig_span.is_none().then(|| tcx.crate_name(original_def_id.krate));
} else {
Some(tcx.crate_name(original_def_id.krate))
};
match tcx.hir().span_if_local(item_def_id) { match tcx.hir().span_if_local(item_def_id) {
Some(span) => tcx.sess.emit_err(DuplicateDiagnosticItem { span, name }), Some(span) => tcx.sess.emit_err(DuplicateDiagnosticItem { span, name }),
None => tcx.sess.emit_err(DuplicateDiagnosticItemInCrate { None => tcx.sess.emit_err(DuplicateDiagnosticItemInCrate {

View File

@ -281,7 +281,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
self.recurse_with_stability_attrs( self.recurse_with_stability_attrs(
depr.map(|(d, _)| DeprecationEntry::local(d, def_id)), depr.map(|(d, _)| DeprecationEntry::local(d, def_id)),
stab, stab,
if inherit_const_stability.yes() { const_stab } else { None }, inherit_const_stability.yes().then_some(const_stab).flatten(),
visit_children, visit_children,
); );
} }

View File

@ -242,8 +242,7 @@ impl<K: DepKind + Encodable<FileEncoder>> GraphEncoder<K> {
record_graph: bool, record_graph: bool,
record_stats: bool, record_stats: bool,
) -> Self { ) -> Self {
let record_graph = let record_graph = record_graph.then(|| Lock::new(DepGraphQuery::new(prev_node_count)));
if record_graph { Some(Lock::new(DepGraphQuery::new(prev_node_count))) } else { None };
let status = Lock::new(EncoderState::new(encoder, record_stats)); let status = Lock::new(EncoderState::new(encoder, record_stats));
GraphEncoder { status, record_graph } GraphEncoder { status, record_graph }
} }

View File

@ -1700,11 +1700,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
let crate_mod = let crate_mod =
Res::Def(DefKind::Mod, crate_id.as_def_id()); Res::Def(DefKind::Mod, crate_id.as_def_id());
if filter_fn(crate_mod) { filter_fn(crate_mod).then(|| {
Some(TypoSuggestion::typo_from_ident(*ident, crate_mod)) TypoSuggestion::typo_from_ident(*ident, crate_mod)
} else { })
None
}
}) })
})); }));

View File

@ -344,7 +344,7 @@ fn preprocess_link(link: &str) -> String {
let link = link.strip_suffix("()").unwrap_or(link); let link = link.strip_suffix("()").unwrap_or(link);
let link = link.strip_suffix("{}").unwrap_or(link); let link = link.strip_suffix("{}").unwrap_or(link);
let link = link.strip_suffix("[]").unwrap_or(link); let link = link.strip_suffix("[]").unwrap_or(link);
let link = if link != "!" { link.strip_suffix("!").unwrap_or(link) } else { link }; let link = if link != "!" { link.strip_suffix('!').unwrap_or(link) } else { link };
strip_generics_from_path(link).unwrap_or_else(|_| link.to_string()) strip_generics_from_path(link).unwrap_or_else(|_| link.to_string())
} }

View File

@ -2544,7 +2544,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
} }
// Only use this directory if it has a file we can expect to always find. // Only use this directory if it has a file we can expect to always find.
if candidate.join("library/std/src/lib.rs").is_file() { Some(candidate) } else { None } candidate.join("library/std/src/lib.rs").is_file().then_some(candidate)
}; };
let working_dir = std::env::current_dir().unwrap_or_else(|e| { let working_dir = std::env::current_dir().unwrap_or_else(|e| {

View File

@ -322,11 +322,7 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
.take_while(|c| *c != 'i' && *c != 'u') .take_while(|c| *c != 'i' && *c != 'u')
.all(|c| c.to_digit(base).is_some()); .all(|c| c.to_digit(base).is_some());
if valid { valid.then(|| format!("0{}{}", base_char.to_ascii_lowercase(), &suffix[1..]))
Some(format!("0{}{}", base_char.to_ascii_lowercase(), &suffix[1..]))
} else {
None
}
} }
let token::Lit { kind, symbol, suffix, .. } = lit; let token::Lit { kind, symbol, suffix, .. } = lit;

View File

@ -217,7 +217,7 @@ pub fn get_or_default_sysroot() -> Result<PathBuf, String> {
// Look for the target rustlib directory in the suspected sysroot. // Look for the target rustlib directory in the suspected sysroot.
let mut rustlib_path = rustc_target::target_rustlib_path(&p, "dummy"); let mut rustlib_path = rustc_target::target_rustlib_path(&p, "dummy");
rustlib_path.pop(); // pop off the dummy target. rustlib_path.pop(); // pop off the dummy target.
if rustlib_path.exists() { Some(p) } else { None } rustlib_path.exists().then_some(p)
} }
None => None, None => None,
} }

View File

@ -809,7 +809,7 @@ mod parse {
if v.is_some() { if v.is_some() {
let mut bool_arg = None; let mut bool_arg = None;
if parse_opt_bool(&mut bool_arg, v) { if parse_opt_bool(&mut bool_arg, v) {
*slot = if bool_arg.unwrap() { Some(MirSpanview::Statement) } else { None }; *slot = bool_arg.unwrap().then_some(MirSpanview::Statement);
return true; return true;
} }
} }
@ -850,7 +850,7 @@ mod parse {
if v.is_some() { if v.is_some() {
let mut bool_arg = None; let mut bool_arg = None;
if parse_opt_bool(&mut bool_arg, v) { if parse_opt_bool(&mut bool_arg, v) {
*slot = if bool_arg.unwrap() { Some(InstrumentCoverage::All) } else { None }; *slot = bool_arg.unwrap().then_some(InstrumentCoverage::All);
return true; return true;
} }
} }

View File

@ -299,7 +299,7 @@ impl DefId {
#[inline] #[inline]
pub fn as_local(self) -> Option<LocalDefId> { pub fn as_local(self) -> Option<LocalDefId> {
if self.is_local() { Some(LocalDefId { local_def_index: self.index }) } else { None } self.is_local().then(|| LocalDefId { local_def_index: self.index })
} }
#[inline] #[inline]
@ -320,7 +320,7 @@ impl DefId {
#[inline] #[inline]
pub fn as_crate_root(self) -> Option<CrateNum> { pub fn as_crate_root(self) -> Option<CrateNum> {
if self.is_crate_root() { Some(self.krate) } else { None } self.is_crate_root().then_some(self.krate)
} }
#[inline] #[inline]

View File

@ -244,8 +244,7 @@ fn compute_symbol_name<'tcx>(
// project. // project.
let avoid_cross_crate_conflicts = is_generic(substs) || is_globally_shared_function; let avoid_cross_crate_conflicts = is_generic(substs) || is_globally_shared_function;
let instantiating_crate = let instantiating_crate = avoid_cross_crate_conflicts.then(compute_instantiating_crate);
if avoid_cross_crate_conflicts { Some(compute_instantiating_crate()) } else { None };
// Pick the crate responsible for the symbol mangling version, which has to: // Pick the crate responsible for the symbol mangling version, which has to:
// 1. be stable for each instance, whether it's being defined or imported // 1. be stable for each instance, whether it's being defined or imported

View File

@ -82,11 +82,8 @@ impl<'tcx, 'a> GeneratorData<'tcx, 'a> {
upvars.iter().find_map(|(upvar_id, upvar)| { upvars.iter().find_map(|(upvar_id, upvar)| {
let upvar_ty = typeck_results.node_type(*upvar_id); let upvar_ty = typeck_results.node_type(*upvar_id);
let upvar_ty = infer_context.resolve_vars_if_possible(upvar_ty); let upvar_ty = infer_context.resolve_vars_if_possible(upvar_ty);
if ty_matches(ty::Binder::dummy(upvar_ty)) { ty_matches(ty::Binder::dummy(upvar_ty))
Some(GeneratorInteriorOrUpvar::Upvar(upvar.span)) .then(|| GeneratorInteriorOrUpvar::Upvar(upvar.span))
} else {
None
}
}) })
}) })
} }
@ -770,15 +767,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
obligation.param_env, obligation.param_env,
real_trait_pred_and_ty, real_trait_pred_and_ty,
); );
if obligations let may_hold = obligations
.iter() .iter()
.chain([&obligation]) .chain([&obligation])
.all(|obligation| self.predicate_may_hold(obligation)) .all(|obligation| self.predicate_may_hold(obligation))
{ .then_some(steps);
Some(steps)
} else { may_hold
None
}
}) })
{ {
if steps > 0 { if steps > 0 {

View File

@ -523,16 +523,14 @@ fn is_impossible_method(tcx: TyCtxt<'_>, (impl_def_id, trait_item_def_id): (DefI
let mut visitor = ReferencesOnlyParentGenerics { tcx, generics, trait_item_def_id }; let mut visitor = ReferencesOnlyParentGenerics { tcx, generics, trait_item_def_id };
let predicates_for_trait = predicates.predicates.iter().filter_map(|(pred, span)| { let predicates_for_trait = predicates.predicates.iter().filter_map(|(pred, span)| {
if pred.visit_with(&mut visitor).is_continue() { pred.visit_with(&mut visitor).is_continue().then(|| {
Some(Obligation::new( Obligation::new(
tcx, tcx,
ObligationCause::dummy_with_span(*span), ObligationCause::dummy_with_span(*span),
param_env, param_env,
ty::EarlyBinder(*pred).subst(tcx, impl_trait_ref.substs), ty::EarlyBinder(*pred).subst(tcx, impl_trait_ref.substs),
)) )
} else { })
None
}
}); });
let infcx = tcx.infer_ctxt().ignoring_regions().build(); let infcx = tcx.infer_ctxt().ignoring_regions().build();

View File

@ -307,7 +307,7 @@ fn predicate_references_self<'tcx>(
match predicate.kind().skip_binder() { match predicate.kind().skip_binder() {
ty::PredicateKind::Clause(ty::Clause::Trait(ref data)) => { ty::PredicateKind::Clause(ty::Clause::Trait(ref data)) => {
// In the case of a trait predicate, we can skip the "self" type. // In the case of a trait predicate, we can skip the "self" type.
if data.trait_ref.substs[1..].iter().any(has_self_ty) { Some(sp) } else { None } data.trait_ref.substs[1..].iter().any(has_self_ty).then_some(sp)
} }
ty::PredicateKind::Clause(ty::Clause::Projection(ref data)) => { ty::PredicateKind::Clause(ty::Clause::Projection(ref data)) => {
// And similarly for projections. This should be redundant with // And similarly for projections. This should be redundant with
@ -325,7 +325,7 @@ fn predicate_references_self<'tcx>(
// //
// This is ALT2 in issue #56288, see that for discussion of the // This is ALT2 in issue #56288, see that for discussion of the
// possible alternatives. // possible alternatives.
if data.projection_ty.substs[1..].iter().any(has_self_ty) { Some(sp) } else { None } data.projection_ty.substs[1..].iter().any(has_self_ty).then_some(sp)
} }
ty::PredicateKind::AliasEq(..) => bug!("`AliasEq` not allowed as assumption"), ty::PredicateKind::AliasEq(..) => bug!("`AliasEq` not allowed as assumption"),

View File

@ -21,11 +21,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for DropckOutlives<'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
key: &ParamEnvAnd<'tcx, Self>, key: &ParamEnvAnd<'tcx, Self>,
) -> Option<Self::QueryResponse> { ) -> Option<Self::QueryResponse> {
if trivial_dropck_outlives(tcx, key.value.dropped_ty) { trivial_dropck_outlives(tcx, key.value.dropped_ty).then(DropckOutlivesResult::default)
Some(DropckOutlivesResult::default())
} else {
None
}
} }
fn perform_query( fn perform_query(

View File

@ -378,11 +378,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let self_ty = trait_ref.self_ty(); let self_ty = trait_ref.self_ty();
let (trait_desc, self_desc) = with_no_trimmed_paths!({ let (trait_desc, self_desc) = with_no_trimmed_paths!({
let trait_desc = trait_ref.print_only_trait_path().to_string(); let trait_desc = trait_ref.print_only_trait_path().to_string();
let self_desc = if self_ty.has_concrete_skeleton() { let self_desc =
Some(self_ty.to_string()) self_ty.has_concrete_skeleton().then(|| self_ty.to_string());
} else {
None
};
(trait_desc, self_desc) (trait_desc, self_desc)
}); });
let cause = if let Conflict::Upstream = conflict { let cause = if let Conflict::Upstream = conflict {

View File

@ -113,7 +113,7 @@ impl<'tcx> ChildrenExt<'tcx> for Children {
// Only report the `Self` type if it has at least // Only report the `Self` type if it has at least
// some outer concrete shell; otherwise, it's // some outer concrete shell; otherwise, it's
// not adding much information. // not adding much information.
self_ty: if self_ty.has_concrete_skeleton() { Some(self_ty) } else { None }, self_ty: self_ty.has_concrete_skeleton().then_some(self_ty),
intercrate_ambiguity_causes: overlap.intercrate_ambiguity_causes, intercrate_ambiguity_causes: overlap.intercrate_ambiguity_causes,
involves_placeholder: overlap.involves_placeholder, involves_placeholder: overlap.involves_placeholder,
} }

View File

@ -206,11 +206,8 @@ fn fn_abi_of_instance<'tcx>(
let sig = fn_sig_for_fn_abi(tcx, instance, param_env); let sig = fn_sig_for_fn_abi(tcx, instance, param_env);
let caller_location = if instance.def.requires_caller_location(tcx) { let caller_location =
Some(tcx.caller_location_ty()) instance.def.requires_caller_location(tcx).then(|| tcx.caller_location_ty());
} else {
None
};
fn_abi_new_uncached( fn_abi_new_uncached(
&LayoutCx { tcx, param_env }, &LayoutCx { tcx, param_env },

View File

@ -11,6 +11,8 @@ pub(crate) mod types;
pub(crate) mod utils; pub(crate) mod utils;
use rustc_ast as ast; use rustc_ast as ast;
use rustc_ast::token::{Token, TokenKind};
use rustc_ast::tokenstream::{TokenStream, TokenTree};
use rustc_attr as attr; use rustc_attr as attr;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, IndexEntry}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, IndexEntry};
use rustc_hir as hir; use rustc_hir as hir;
@ -2079,8 +2081,8 @@ impl<'hir> hir::intravisit::Visitor<'hir> for OneLevelVisitor<'hir> {
fn visit_item(&mut self, item: &'hir hir::Item<'hir>) { fn visit_item(&mut self, item: &'hir hir::Item<'hir>) {
if self.item.is_none() if self.item.is_none()
&& item.ident == self.looking_for && item.ident == self.looking_for
&& matches!(item.kind, hir::ItemKind::Use(_, _)) && (matches!(item.kind, hir::ItemKind::Use(_, _))
|| item.owner_id.def_id == self.target_def_id || item.owner_id.def_id == self.target_def_id)
{ {
self.item = Some(item); self.item = Some(item);
} }
@ -2096,34 +2098,149 @@ fn get_all_import_attributes<'hir>(
tcx: TyCtxt<'hir>, tcx: TyCtxt<'hir>,
target_def_id: LocalDefId, target_def_id: LocalDefId,
attributes: &mut Vec<ast::Attribute>, attributes: &mut Vec<ast::Attribute>,
is_inline: bool,
) { ) {
let hir_map = tcx.hir(); let hir_map = tcx.hir();
let mut visitor = OneLevelVisitor::new(hir_map, target_def_id); let mut visitor = OneLevelVisitor::new(hir_map, target_def_id);
let mut visited = FxHashSet::default(); let mut visited = FxHashSet::default();
// If the item is an import and has at least a path with two parts, we go into it. // If the item is an import and has at least a path with two parts, we go into it.
while let hir::ItemKind::Use(path, _) = item.kind && while let hir::ItemKind::Use(path, _) = item.kind && visited.insert(item.hir_id()) {
path.segments.len() > 1 && // We add the attributes from this import into the list.
let hir::def::Res::Def(_, def_id) = path.segments[path.segments.len() - 2].res && add_without_unwanted_attributes(attributes, hir_map.attrs(item.hir_id()), is_inline);
visited.insert(def_id)
{ let def_id = if path.segments.len() > 1 {
if let Some(hir::Node::Item(parent_item)) = hir_map.get_if_local(def_id) { match path.segments[path.segments.len() - 2].res {
// We add the attributes from this import into the list. hir::def::Res::Def(_, def_id) => def_id,
attributes.extend_from_slice(hir_map.attrs(item.hir_id())); _ => break,
// We get the `Ident` we will be looking for into `item`.
let looking_for = path.segments[path.segments.len() - 1].ident;
visitor.reset(looking_for);
hir::intravisit::walk_item(&mut visitor, parent_item);
if let Some(i) = visitor.item {
item = i;
} else {
break;
} }
} else {
// If the path doesn't have a parent, then the parent is the current module.
tcx.parent(item.owner_id.def_id.to_def_id())
};
let Some(parent) = hir_map.get_if_local(def_id) else { break };
// We get the `Ident` we will be looking for into `item`.
let looking_for = path.segments[path.segments.len() - 1].ident;
visitor.reset(looking_for);
match parent {
hir::Node::Item(parent_item) => {
hir::intravisit::walk_item(&mut visitor, parent_item);
}
hir::Node::Crate(m) => {
hir::intravisit::walk_mod(
&mut visitor,
m,
tcx.local_def_id_to_hir_id(def_id.as_local().unwrap()),
);
}
_ => break,
}
if let Some(i) = visitor.item {
item = i;
} else { } else {
break; break;
} }
} }
} }
fn filter_tokens_from_list(
args_tokens: TokenStream,
should_retain: impl Fn(&TokenTree) -> bool,
) -> Vec<TokenTree> {
let mut tokens = Vec::with_capacity(args_tokens.len());
let mut skip_next_comma = false;
for token in args_tokens.into_trees() {
match token {
TokenTree::Token(Token { kind: TokenKind::Comma, .. }, _) if skip_next_comma => {
skip_next_comma = false;
}
token if should_retain(&token) => {
skip_next_comma = false;
tokens.push(token);
}
_ => {
skip_next_comma = true;
}
}
}
tokens
}
/// When inlining items, we merge its attributes (and all the reexports attributes too) with the
/// final reexport. For example:
///
/// ```ignore (just an example)
/// #[doc(hidden, cfg(feature = "foo"))]
/// pub struct Foo;
///
/// #[doc(cfg(feature = "bar"))]
/// #[doc(hidden, no_inline)]
/// pub use Foo as Foo1;
///
/// #[doc(inline)]
/// pub use Foo2 as Bar;
/// ```
///
/// So `Bar` at the end will have both `cfg(feature = "...")`. However, we don't want to merge all
/// attributes so we filter out the following ones:
/// * `doc(inline)`
/// * `doc(no_inline)`
/// * `doc(hidden)`
fn add_without_unwanted_attributes(
attrs: &mut Vec<ast::Attribute>,
new_attrs: &[ast::Attribute],
is_inline: bool,
) {
// If it's `#[doc(inline)]`, we don't want all attributes, otherwise we keep everything.
if !is_inline {
attrs.extend_from_slice(new_attrs);
return;
}
for attr in new_attrs {
let mut attr = attr.clone();
match attr.kind {
ast::AttrKind::Normal(ref mut normal) => {
if let [ident] = &*normal.item.path.segments &&
let ident = ident.ident.name &&
ident == sym::doc
{
match normal.item.args {
ast::AttrArgs::Delimited(ref mut args) => {
let tokens =
filter_tokens_from_list(args.tokens.clone(), |token| {
!matches!(
token,
TokenTree::Token(
Token {
kind: TokenKind::Ident(
sym::hidden | sym::inline | sym::no_inline,
_,
),
..
},
_,
),
)
});
args.tokens = TokenStream::new(tokens);
attrs.push(attr);
}
ast::AttrArgs::Empty | ast::AttrArgs::Eq(..) => {
attrs.push(attr);
continue;
}
}
}
}
ast::AttrKind::DocComment(..) => {
attrs.push(attr);
}
}
}
}
fn clean_maybe_renamed_item<'tcx>( fn clean_maybe_renamed_item<'tcx>(
cx: &mut DocContext<'tcx>, cx: &mut DocContext<'tcx>,
item: &hir::Item<'tcx>, item: &hir::Item<'tcx>,
@ -2212,19 +2329,20 @@ fn clean_maybe_renamed_item<'tcx>(
{ {
// First, we add the attributes from the current import. // First, we add the attributes from the current import.
extra_attrs.extend_from_slice(inline::load_attrs(cx, import_id.to_def_id())); extra_attrs.extend_from_slice(inline::load_attrs(cx, import_id.to_def_id()));
let is_inline = extra_attrs.lists(sym::doc).get_word_attr(sym::inline).is_some();
// Then we get all the various imports' attributes. // Then we get all the various imports' attributes.
get_all_import_attributes(use_node, cx.tcx, item.owner_id.def_id, &mut extra_attrs); get_all_import_attributes(use_node, cx.tcx, item.owner_id.def_id, &mut extra_attrs, is_inline);
add_without_unwanted_attributes(&mut extra_attrs, inline::load_attrs(cx, def_id), is_inline);
} else {
// We only keep the item's attributes.
extra_attrs.extend_from_slice(inline::load_attrs(cx, def_id));
} }
let mut item = if !extra_attrs.is_empty() { let attrs = Attributes::from_ast(&extra_attrs);
extra_attrs.extend_from_slice(inline::load_attrs(cx, def_id)); let cfg = extra_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg);
let attrs = Attributes::from_ast(&extra_attrs);
let cfg = extra_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg);
Item::from_def_id_and_attrs_and_parts(def_id, Some(name), kind, Box::new(attrs), cfg) let mut item =
} else { Item::from_def_id_and_attrs_and_parts(def_id, Some(name), kind, Box::new(attrs), cfg);
Item::from_def_id_and_parts(def_id, Some(name), kind, cx)
};
item.inline_stmt_id = import_id.map(|def_id| def_id.to_def_id()); item.inline_stmt_id = import_id.map(|def_id| def_id.to_def_id());
vec![item] vec![item]
}) })

View File

@ -361,7 +361,7 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
for _ in 0..padding_amout { for _ in 0..padding_amout {
br_with_padding.push_str(" "); br_with_padding.push_str(" ");
} }
let where_preds = where_preds.to_string().replace("\n", &br_with_padding); let where_preds = where_preds.to_string().replace('\n', &br_with_padding);
if ending == Ending::Newline { if ending == Ending::Newline {
let mut clause = " ".repeat(indent.saturating_sub(1)); let mut clause = " ".repeat(indent.saturating_sub(1));
@ -1419,12 +1419,12 @@ impl clean::FnDecl {
format!( format!(
"({pad}{args}{close}){arrow}", "({pad}{args}{close}){arrow}",
pad = if self.inputs.values.is_empty() { "" } else { &full_pad }, pad = if self.inputs.values.is_empty() { "" } else { &full_pad },
args = args.replace("\n", &full_pad), args = args.replace('\n', &full_pad),
close = close_pad, close = close_pad,
arrow = arrow arrow = arrow
) )
} else { } else {
format!("({args}){arrow}", args = args.replace("\n", " "), arrow = arrow) format!("({args}){arrow}", args = args.replace('\n', " "), arrow = arrow)
}; };
write!(f, "{}", output) write!(f, "{}", output)

View File

@ -0,0 +1,33 @@
// Regression test for <https://github.com/rust-lang/rust/issues/59368>.
// The goal is to ensure that `doc(hidden)`, `doc(inline)` and `doc(no_inline)`
// are not copied from an item when inlined.
#![crate_name = "foo"]
#![feature(doc_cfg)]
// @has 'foo/index.html'
#[doc(hidden, cfg(feature = "foo"))]
pub struct Foo;
#[doc(hidden, no_inline, cfg(feature = "bar"))]
pub use Foo as Foo1;
#[doc(hidden, inline)]
pub use Foo1 as Foo2;
// First we ensure that only the reexport `Bar2` and the inlined struct `Bar`
// are inlined.
// @count - '//a[@class="struct"]' 2
// Then we check that both `cfg` are displayed.
// @has - '//*[@class="stab portability"]' 'foo'
// @has - '//*[@class="stab portability"]' 'bar'
// And finally we check that the only element displayed is `Bar`.
// @has - '//a[@class="struct"]' 'Bar'
#[doc(inline)]
pub use Foo2 as Bar;
// This one should appear but `Bar2` won't be linked because there is no
// `#[doc(inline)]`.
// @has - '//*[@id="reexport.Bar2"]' 'pub use Foo2 as Bar2;'
pub use Foo2 as Bar2;

View File

@ -7,7 +7,10 @@ LL | fn oom() -> ! {
| _-^^^^^^^^^^^^ | _-^^^^^^^^^^^^
LL | | loop {} LL | | loop {}
LL | | } LL | | }
| |_- argument of type `core::alloc::Layout` unexpected | | -
| | |
| |_unexpected argument of type `core::alloc::Layout`
| help: remove the extra argument
| |
note: function defined here note: function defined here
--> $DIR/alloc-error-handler-bad-signature-3.rs:10:4 --> $DIR/alloc-error-handler-bad-signature-3.rs:10:4
@ -15,10 +18,6 @@ note: function defined here
LL | fn oom() -> ! { LL | fn oom() -> ! {
| ^^^ | ^^^
= note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info)
help: remove the extra argument
|
LL | fn oom() -> !() {
| ++
error: aborting due to previous error error: aborting due to previous error

View File

@ -16,17 +16,16 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/basic.rs:21:5 --> $DIR/basic.rs:21:5
| |
LL | extra(""); LL | extra("");
| ^^^^^ -- argument of type `&'static str` unexpected | ^^^^^ --
| |
| unexpected argument of type `&'static str`
| help: remove the extra argument
| |
note: function defined here note: function defined here
--> $DIR/basic.rs:14:4 --> $DIR/basic.rs:14:4
| |
LL | fn extra() {} LL | fn extra() {}
| ^^^^^ | ^^^^^
help: remove the extra argument
|
LL | extra();
| ~~
error[E0061]: this function takes 1 argument but 0 arguments were supplied error[E0061]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/basic.rs:22:5 --> $DIR/basic.rs:22:5

View File

@ -2,65 +2,61 @@ error[E0057]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/exotic-calls.rs:2:5 --> $DIR/exotic-calls.rs:2:5
| |
LL | t(1i32); LL | t(1i32);
| ^ ---- argument of type `i32` unexpected | ^ ----
| |
| unexpected argument of type `i32`
| help: remove the extra argument
| |
note: callable defined here note: callable defined here
--> $DIR/exotic-calls.rs:1:11 --> $DIR/exotic-calls.rs:1:11
| |
LL | fn foo<T: Fn()>(t: T) { LL | fn foo<T: Fn()>(t: T) {
| ^^^^ | ^^^^
help: remove the extra argument
|
LL | t();
| ~~
error[E0057]: this function takes 0 arguments but 1 argument was supplied error[E0057]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/exotic-calls.rs:7:5 --> $DIR/exotic-calls.rs:7:5
| |
LL | t(1i32); LL | t(1i32);
| ^ ---- argument of type `i32` unexpected | ^ ----
| |
| unexpected argument of type `i32`
| help: remove the extra argument
| |
note: type parameter defined here note: type parameter defined here
--> $DIR/exotic-calls.rs:6:11 --> $DIR/exotic-calls.rs:6:11
| |
LL | fn bar(t: impl Fn()) { LL | fn bar(t: impl Fn()) {
| ^^^^^^^^^ | ^^^^^^^^^
help: remove the extra argument
|
LL | t();
| ~~
error[E0057]: this function takes 0 arguments but 1 argument was supplied error[E0057]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/exotic-calls.rs:16:5 --> $DIR/exotic-calls.rs:16:5
| |
LL | baz()(1i32) LL | baz()(1i32)
| ^^^^^ ---- argument of type `i32` unexpected | ^^^^^ ----
| |
| unexpected argument of type `i32`
| help: remove the extra argument
| |
note: opaque type defined here note: opaque type defined here
--> $DIR/exotic-calls.rs:11:13 --> $DIR/exotic-calls.rs:11:13
| |
LL | fn baz() -> impl Fn() { LL | fn baz() -> impl Fn() {
| ^^^^^^^^^ | ^^^^^^^^^
help: remove the extra argument
|
LL | baz()()
| ~~
error[E0057]: this function takes 0 arguments but 1 argument was supplied error[E0057]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/exotic-calls.rs:22:5 --> $DIR/exotic-calls.rs:22:5
| |
LL | x(1i32); LL | x(1i32);
| ^ ---- argument of type `i32` unexpected | ^ ----
| |
| unexpected argument of type `i32`
| help: remove the extra argument
| |
note: closure defined here note: closure defined here
--> $DIR/exotic-calls.rs:21:13 --> $DIR/exotic-calls.rs:21:13
| |
LL | let x = || {}; LL | let x = || {};
| ^^ | ^^
help: remove the extra argument
|
LL | x();
| ~~
error: aborting due to 4 previous errors error: aborting due to 4 previous errors

View File

@ -2,57 +2,54 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/extra_arguments.rs:7:3 --> $DIR/extra_arguments.rs:7:3
| |
LL | empty(""); LL | empty("");
| ^^^^^ -- argument of type `&'static str` unexpected | ^^^^^ --
| |
| unexpected argument of type `&'static str`
| help: remove the extra argument
| |
note: function defined here note: function defined here
--> $DIR/extra_arguments.rs:1:4 --> $DIR/extra_arguments.rs:1:4
| |
LL | fn empty() {} LL | fn empty() {}
| ^^^^^ | ^^^^^
help: remove the extra argument
|
LL | empty();
| ~~
error[E0061]: this function takes 1 argument but 2 arguments were supplied error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/extra_arguments.rs:9:3 --> $DIR/extra_arguments.rs:9:3
| |
LL | one_arg(1, 1); LL | one_arg(1, 1);
| ^^^^^^^ - argument of type `{integer}` unexpected | ^^^^^^^ ---
| | |
| | unexpected argument of type `{integer}`
| help: remove the extra argument
| |
note: function defined here note: function defined here
--> $DIR/extra_arguments.rs:2:4 --> $DIR/extra_arguments.rs:2:4
| |
LL | fn one_arg(_a: i32) {} LL | fn one_arg(_a: i32) {}
| ^^^^^^^ ------- | ^^^^^^^ -------
help: remove the extra argument
|
LL | one_arg(1);
| ~~~
error[E0061]: this function takes 1 argument but 2 arguments were supplied error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/extra_arguments.rs:10:3 --> $DIR/extra_arguments.rs:10:3
| |
LL | one_arg(1, ""); LL | one_arg(1, "");
| ^^^^^^^ -- argument of type `&'static str` unexpected | ^^^^^^^ ----
| | |
| | unexpected argument of type `&'static str`
| help: remove the extra argument
| |
note: function defined here note: function defined here
--> $DIR/extra_arguments.rs:2:4 --> $DIR/extra_arguments.rs:2:4
| |
LL | fn one_arg(_a: i32) {} LL | fn one_arg(_a: i32) {}
| ^^^^^^^ ------- | ^^^^^^^ -------
help: remove the extra argument
|
LL | one_arg(1);
| ~~~
error[E0061]: this function takes 1 argument but 3 arguments were supplied error[E0061]: this function takes 1 argument but 3 arguments were supplied
--> $DIR/extra_arguments.rs:11:3 --> $DIR/extra_arguments.rs:11:3
| |
LL | one_arg(1, "", 1.0); LL | one_arg(1, "", 1.0);
| ^^^^^^^ -- --- argument of type `{float}` unexpected | ^^^^^^^ -- --- unexpected argument of type `{float}`
| | | |
| argument of type `&'static str` unexpected | unexpected argument of type `&'static str`
| |
note: function defined here note: function defined here
--> $DIR/extra_arguments.rs:2:4 --> $DIR/extra_arguments.rs:2:4
@ -61,80 +58,77 @@ LL | fn one_arg(_a: i32) {}
| ^^^^^^^ ------- | ^^^^^^^ -------
help: remove the extra arguments help: remove the extra arguments
| |
LL | one_arg(1); LL - one_arg(1, "", 1.0);
| ~~~ LL + one_arg(1);
|
error[E0061]: this function takes 2 arguments but 3 arguments were supplied error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/extra_arguments.rs:13:3 --> $DIR/extra_arguments.rs:13:3
| |
LL | two_arg_same(1, 1, 1); LL | two_arg_same(1, 1, 1);
| ^^^^^^^^^^^^ - argument of type `{integer}` unexpected | ^^^^^^^^^^^^ ---
| | |
| | unexpected argument of type `{integer}`
| help: remove the extra argument
| |
note: function defined here note: function defined here
--> $DIR/extra_arguments.rs:3:4 --> $DIR/extra_arguments.rs:3:4
| |
LL | fn two_arg_same(_a: i32, _b: i32) {} LL | fn two_arg_same(_a: i32, _b: i32) {}
| ^^^^^^^^^^^^ ------- ------- | ^^^^^^^^^^^^ ------- -------
help: remove the extra argument
|
LL | two_arg_same(1, 1);
| ~~~~~~
error[E0061]: this function takes 2 arguments but 3 arguments were supplied error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/extra_arguments.rs:14:3 --> $DIR/extra_arguments.rs:14:3
| |
LL | two_arg_same(1, 1, 1.0); LL | two_arg_same(1, 1, 1.0);
| ^^^^^^^^^^^^ --- argument of type `{float}` unexpected | ^^^^^^^^^^^^ -----
| | |
| | unexpected argument of type `{float}`
| help: remove the extra argument
| |
note: function defined here note: function defined here
--> $DIR/extra_arguments.rs:3:4 --> $DIR/extra_arguments.rs:3:4
| |
LL | fn two_arg_same(_a: i32, _b: i32) {} LL | fn two_arg_same(_a: i32, _b: i32) {}
| ^^^^^^^^^^^^ ------- ------- | ^^^^^^^^^^^^ ------- -------
help: remove the extra argument
|
LL | two_arg_same(1, 1);
| ~~~~~~
error[E0061]: this function takes 2 arguments but 3 arguments were supplied error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/extra_arguments.rs:16:3 --> $DIR/extra_arguments.rs:16:3
| |
LL | two_arg_diff(1, 1, ""); LL | two_arg_diff(1, 1, "");
| ^^^^^^^^^^^^ - argument of type `{integer}` unexpected | ^^^^^^^^^^^^ ---
| | |
| | unexpected argument of type `{integer}`
| help: remove the extra argument
| |
note: function defined here note: function defined here
--> $DIR/extra_arguments.rs:4:4 --> $DIR/extra_arguments.rs:4:4
| |
LL | fn two_arg_diff(_a: i32, _b: &str) {} LL | fn two_arg_diff(_a: i32, _b: &str) {}
| ^^^^^^^^^^^^ ------- -------- | ^^^^^^^^^^^^ ------- --------
help: remove the extra argument
|
LL | two_arg_diff(1, "");
| ~~~~~~~
error[E0061]: this function takes 2 arguments but 3 arguments were supplied error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/extra_arguments.rs:17:3 --> $DIR/extra_arguments.rs:17:3
| |
LL | two_arg_diff(1, "", ""); LL | two_arg_diff(1, "", "");
| ^^^^^^^^^^^^ -- argument of type `&'static str` unexpected | ^^^^^^^^^^^^ ----
| | |
| | unexpected argument of type `&'static str`
| help: remove the extra argument
| |
note: function defined here note: function defined here
--> $DIR/extra_arguments.rs:4:4 --> $DIR/extra_arguments.rs:4:4
| |
LL | fn two_arg_diff(_a: i32, _b: &str) {} LL | fn two_arg_diff(_a: i32, _b: &str) {}
| ^^^^^^^^^^^^ ------- -------- | ^^^^^^^^^^^^ ------- --------
help: remove the extra argument
|
LL | two_arg_diff(1, "");
| ~~~~~~~
error[E0061]: this function takes 2 arguments but 4 arguments were supplied error[E0061]: this function takes 2 arguments but 4 arguments were supplied
--> $DIR/extra_arguments.rs:18:3 --> $DIR/extra_arguments.rs:18:3
| |
LL | two_arg_diff(1, 1, "", ""); LL | two_arg_diff(1, 1, "", "");
| ^^^^^^^^^^^^ - -- argument of type `&'static str` unexpected | ^^^^^^^^^^^^ - -- unexpected argument of type `&'static str`
| | | |
| argument of type `{integer}` unexpected | unexpected argument of type `{integer}`
| |
note: function defined here note: function defined here
--> $DIR/extra_arguments.rs:4:4 --> $DIR/extra_arguments.rs:4:4
@ -143,16 +137,17 @@ LL | fn two_arg_diff(_a: i32, _b: &str) {}
| ^^^^^^^^^^^^ ------- -------- | ^^^^^^^^^^^^ ------- --------
help: remove the extra arguments help: remove the extra arguments
| |
LL | two_arg_diff(1, ""); LL - two_arg_diff(1, 1, "", "");
| ~~~~~~~ LL + two_arg_diff(1, "");
|
error[E0061]: this function takes 2 arguments but 4 arguments were supplied error[E0061]: this function takes 2 arguments but 4 arguments were supplied
--> $DIR/extra_arguments.rs:19:3 --> $DIR/extra_arguments.rs:19:3
| |
LL | two_arg_diff(1, "", 1, ""); LL | two_arg_diff(1, "", 1, "");
| ^^^^^^^^^^^^ - -- argument of type `&'static str` unexpected | ^^^^^^^^^^^^ - -- unexpected argument of type `&'static str`
| | | |
| argument of type `{integer}` unexpected | unexpected argument of type `{integer}`
| |
note: function defined here note: function defined here
--> $DIR/extra_arguments.rs:4:4 --> $DIR/extra_arguments.rs:4:4
@ -161,78 +156,78 @@ LL | fn two_arg_diff(_a: i32, _b: &str) {}
| ^^^^^^^^^^^^ ------- -------- | ^^^^^^^^^^^^ ------- --------
help: remove the extra arguments help: remove the extra arguments
| |
LL | two_arg_diff(1, ""); LL - two_arg_diff(1, "", 1, "");
| ~~~~~~~ LL + two_arg_diff(1, "");
|
error[E0061]: this function takes 2 arguments but 3 arguments were supplied error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/extra_arguments.rs:22:3 --> $DIR/extra_arguments.rs:22:3
| |
LL | two_arg_same(1, 1, ""); LL | two_arg_same(1, 1, "");
| ^^^^^^^^^^^^ -- argument of type `&'static str` unexpected | ^^^^^^^^^^^^ --------
| | |
| | unexpected argument of type `&'static str`
| help: remove the extra argument
| |
note: function defined here note: function defined here
--> $DIR/extra_arguments.rs:3:4 --> $DIR/extra_arguments.rs:3:4
| |
LL | fn two_arg_same(_a: i32, _b: i32) {} LL | fn two_arg_same(_a: i32, _b: i32) {}
| ^^^^^^^^^^^^ ------- ------- | ^^^^^^^^^^^^ ------- -------
help: remove the extra argument
|
LL | two_arg_same(1, 1);
| ~~~~~~
error[E0061]: this function takes 2 arguments but 3 arguments were supplied error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/extra_arguments.rs:23:3 --> $DIR/extra_arguments.rs:23:3
| |
LL | two_arg_diff(1, 1, ""); LL | two_arg_diff(1, 1, "");
| ^^^^^^^^^^^^ - argument of type `{integer}` unexpected | ^^^^^^^^^^^^ ---
| | |
| | unexpected argument of type `{integer}`
| help: remove the extra argument
| |
note: function defined here note: function defined here
--> $DIR/extra_arguments.rs:4:4 --> $DIR/extra_arguments.rs:4:4
| |
LL | fn two_arg_diff(_a: i32, _b: &str) {} LL | fn two_arg_diff(_a: i32, _b: &str) {}
| ^^^^^^^^^^^^ ------- -------- | ^^^^^^^^^^^^ ------- --------
help: remove the extra argument
|
LL | two_arg_diff(1, "");
| ~~~~~~~
error[E0061]: this function takes 2 arguments but 3 arguments were supplied error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/extra_arguments.rs:24:3 --> $DIR/extra_arguments.rs:24:3
| |
LL | two_arg_same( LL | two_arg_same(
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
... LL | 1,
LL | "" LL | 1,
| -- argument of type `&'static str` unexpected | ______-
LL | | ""
| | --
| |_____||
| |help: remove the extra argument
| unexpected argument of type `&'static str`
| |
note: function defined here note: function defined here
--> $DIR/extra_arguments.rs:3:4 --> $DIR/extra_arguments.rs:3:4
| |
LL | fn two_arg_same(_a: i32, _b: i32) {} LL | fn two_arg_same(_a: i32, _b: i32) {}
| ^^^^^^^^^^^^ ------- ------- | ^^^^^^^^^^^^ ------- -------
help: remove the extra argument
|
LL | two_arg_same(1, 1);
| ~~~~~~
error[E0061]: this function takes 2 arguments but 3 arguments were supplied error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/extra_arguments.rs:30:3 --> $DIR/extra_arguments.rs:30:3
| |
LL | two_arg_diff( LL | two_arg_diff(
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
LL | 1, LL | 1,
LL | 1, | ______-
| - argument of type `{integer}` unexpected LL | | 1,
| | -
| | |
| |_____unexpected argument of type `{integer}`
| help: remove the extra argument
| |
note: function defined here note: function defined here
--> $DIR/extra_arguments.rs:4:4 --> $DIR/extra_arguments.rs:4:4
| |
LL | fn two_arg_diff(_a: i32, _b: &str) {} LL | fn two_arg_diff(_a: i32, _b: &str) {}
| ^^^^^^^^^^^^ ------- -------- | ^^^^^^^^^^^^ ------- --------
help: remove the extra argument
|
LL | two_arg_diff(1, "");
| ~~~~~~~
error: aborting due to 14 previous errors error: aborting due to 14 previous errors

View File

@ -4,7 +4,7 @@ error[E0061]: this function takes 6 arguments but 7 arguments were supplied
LL | f(C, A, A, A, B, B, C); LL | f(C, A, A, A, B, B, C);
| ^ - - - - expected `C`, found `B` | ^ - - - - expected `C`, found `B`
| | | | | | | |
| | | argument of type `A` unexpected | | | unexpected argument of type `A`
| | expected `B`, found `A` | | expected `B`, found `A`
| expected `A`, found `C` | expected `A`, found `C`
| |
@ -64,8 +64,8 @@ error[E0308]: arguments to this function are incorrect
LL | f(A, A, D, D, B, B); LL | f(A, A, D, D, B, B);
| ^ - - ---- two arguments of type `C` and `C` are missing | ^ - - ---- two arguments of type `C` and `C` are missing
| | | | | |
| | argument of type `D` unexpected | | unexpected argument of type `D`
| argument of type `D` unexpected | unexpected argument of type `D`
| |
note: function defined here note: function defined here
--> $DIR/issue-101097.rs:6:4 --> $DIR/issue-101097.rs:6:4

View File

@ -2,11 +2,11 @@ error[E0061]: this function takes 4 arguments but 7 arguments were supplied
--> $DIR/issue-97484.rs:12:5 --> $DIR/issue-97484.rs:12:5
| |
LL | foo(&&A, B, C, D, E, F, G); LL | foo(&&A, B, C, D, E, F, G);
| ^^^ - - - - argument of type `F` unexpected | ^^^ - - - - unexpected argument of type `F`
| | | | | | | |
| | | expected `&E`, found `E` | | | expected `&E`, found `E`
| | argument of type `C` unexpected | | unexpected argument of type `C`
| argument of type `B` unexpected | unexpected argument of type `B`
| |
note: function defined here note: function defined here
--> $DIR/issue-97484.rs:9:4 --> $DIR/issue-97484.rs:9:4
@ -19,8 +19,9 @@ LL | foo(&&A, B, C, D, &E, F, G);
| ~~ | ~~
help: remove the extra arguments help: remove the extra arguments
| |
LL | foo(&&A, D, /* &E */, G); LL - foo(&&A, B, C, D, E, F, G);
| ~~~~~~~~~~~~~~~~~~~~~ LL + foo(&&A, D, /* &E */, G);
|
error: aborting due to previous error error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/mixed_cases.rs:10:3 --> $DIR/mixed_cases.rs:10:3
| |
LL | two_args(1, "", X {}); LL | two_args(1, "", X {});
| ^^^^^^^^ -- ---- argument of type `X` unexpected | ^^^^^^^^ -- ---- unexpected argument of type `X`
| | | |
| expected `f32`, found `&str` | expected `f32`, found `&str`
| |
@ -13,16 +13,17 @@ LL | fn two_args(_a: i32, _b: f32) {}
| ^^^^^^^^ ------- ------- | ^^^^^^^^ ------- -------
help: remove the extra argument help: remove the extra argument
| |
LL | two_args(1, /* f32 */); LL - two_args(1, "", X {});
| ~~~~~~~~~~~~~~ LL + two_args(1, /* f32 */);
|
error[E0061]: this function takes 3 arguments but 4 arguments were supplied error[E0061]: this function takes 3 arguments but 4 arguments were supplied
--> $DIR/mixed_cases.rs:11:3 --> $DIR/mixed_cases.rs:11:3
| |
LL | three_args(1, "", X {}, ""); LL | three_args(1, "", X {}, "");
| ^^^^^^^^^^ -- ---- -- argument of type `&'static str` unexpected | ^^^^^^^^^^ -- ---- -- unexpected argument of type `&'static str`
| | | | | |
| | argument of type `X` unexpected | | unexpected argument of type `X`
| an argument of type `f32` is missing | an argument of type `f32` is missing
| |
note: function defined here note: function defined here
@ -58,7 +59,7 @@ error[E0308]: arguments to this function are incorrect
--> $DIR/mixed_cases.rs:17:3 --> $DIR/mixed_cases.rs:17:3
| |
LL | three_args(1, "", X {}); LL | three_args(1, "", X {});
| ^^^^^^^^^^ -- ---- argument of type `X` unexpected | ^^^^^^^^^^ -- ---- unexpected argument of type `X`
| | | |
| an argument of type `f32` is missing | an argument of type `f32` is missing
| |

View File

@ -18,17 +18,16 @@ error[E0057]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/E0057.rs:5:13 --> $DIR/E0057.rs:5:13
| |
LL | let c = f(2, 3); LL | let c = f(2, 3);
| ^ - argument of type `{integer}` unexpected | ^ ---
| | |
| | unexpected argument of type `{integer}`
| help: remove the extra argument
| |
note: closure defined here note: closure defined here
--> $DIR/E0057.rs:2:13 --> $DIR/E0057.rs:2:13
| |
LL | let f = |x| x * 3; LL | let f = |x| x * 3;
| ^^^ | ^^^
help: remove the extra argument
|
LL | let c = f(2);
| ~~~
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View File

@ -2,17 +2,16 @@ error[E0057]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/issue-16939.rs:5:9 --> $DIR/issue-16939.rs:5:9
| |
LL | |t| f(t); LL | |t| f(t);
| ^ - argument unexpected | ^ -
| |
| unexpected argument
| help: remove the extra argument
| |
note: callable defined here note: callable defined here
--> $DIR/issue-16939.rs:4:12 --> $DIR/issue-16939.rs:4:12
| |
LL | fn _foo<F: Fn()> (f: F) { LL | fn _foo<F: Fn()> (f: F) {
| ^^^^ | ^^^^
help: remove the extra argument
|
LL | |t| f();
| ~~
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,6 +1,6 @@
macro_rules! some_macro { macro_rules! some_macro {
($other: expr) => ({ ($other: expr) => ({
$other(None) //~ NOTE argument of type `Option<_>` unexpected $other(None) //~ NOTE unexpected argument of type `Option<_>`
}) })
} }

View File

@ -2,7 +2,10 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/issue-26094.rs:10:17 --> $DIR/issue-26094.rs:10:17
| |
LL | $other(None) LL | $other(None)
| ---- argument of type `Option<_>` unexpected | ----
| |
| unexpected argument of type `Option<_>`
| help: remove the extra argument
... ...
LL | some_macro!(some_function); LL | some_macro!(some_function);
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -12,10 +15,6 @@ note: function defined here
| |
LL | fn some_function() {} LL | fn some_function() {}
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
help: remove the extra argument
|
LL | some_function()
| ~~~~~~~~~~~~~~~
error: aborting due to previous error error: aborting due to previous error

View File

@ -2,17 +2,16 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/issue-4935.rs:5:13 --> $DIR/issue-4935.rs:5:13
| |
LL | fn main() { foo(5, 6) } LL | fn main() { foo(5, 6) }
| ^^^ - argument of type `{integer}` unexpected | ^^^ ---
| | |
| | unexpected argument of type `{integer}`
| help: remove the extra argument
| |
note: function defined here note: function defined here
--> $DIR/issue-4935.rs:3:4 --> $DIR/issue-4935.rs:3:4
| |
LL | fn foo(a: usize) {} LL | fn foo(a: usize) {}
| ^^^ -------- | ^^^ --------
help: remove the extra argument
|
LL | fn main() { foo(5) }
| ~~~
error: aborting due to previous error error: aborting due to previous error

View File

@ -2,17 +2,16 @@ error[E0061]: this method takes 0 arguments but 1 argument was supplied
--> $DIR/method-call-err-msg.rs:13:7 --> $DIR/method-call-err-msg.rs:13:7
| |
LL | x.zero(0) LL | x.zero(0)
| ^^^^ - argument of type `{integer}` unexpected | ^^^^ -
| |
| unexpected argument of type `{integer}`
| help: remove the extra argument
| |
note: associated function defined here note: associated function defined here
--> $DIR/method-call-err-msg.rs:5:8 --> $DIR/method-call-err-msg.rs:5:8
| |
LL | fn zero(self) -> Foo { self } LL | fn zero(self) -> Foo { self }
| ^^^^ | ^^^^
help: remove the extra argument
|
LL | x.zero()
| ~~
error[E0061]: this method takes 1 argument but 0 arguments were supplied error[E0061]: this method takes 1 argument but 0 arguments were supplied
--> $DIR/method-call-err-msg.rs:14:7 --> $DIR/method-call-err-msg.rs:14:7

View File

@ -32,7 +32,7 @@ error[E0057]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/overloaded-calls-bad.rs:37:15 --> $DIR/overloaded-calls-bad.rs:37:15
| |
LL | let ans = s("burma", "shave"); LL | let ans = s("burma", "shave");
| ^ ------- ------- argument of type `&'static str` unexpected | ^ ------- ------- unexpected argument of type `&'static str`
| | | |
| expected `isize`, found `&str` | expected `isize`, found `&str`
| |
@ -43,8 +43,9 @@ LL | impl FnMut<(isize,)> for S {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
help: remove the extra argument help: remove the extra argument
| |
LL | let ans = s(/* isize */); LL - let ans = s("burma", "shave");
| ~~~~~~~~~~~~~ LL + let ans = s(/* isize */);
|
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/overloaded-calls-bad.rs:40:7 --> $DIR/overloaded-calls-bad.rs:40:7

View File

@ -24,14 +24,13 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/resolve-primitive-fallback.rs:3:5 --> $DIR/resolve-primitive-fallback.rs:3:5
| |
LL | std::mem::size_of(u16); LL | std::mem::size_of(u16);
| ^^^^^^^^^^^^^^^^^ --- argument unexpected | ^^^^^^^^^^^^^^^^^ ---
| |
| unexpected argument
| help: remove the extra argument
| |
note: function defined here note: function defined here
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
help: remove the extra argument
|
LL | std::mem::size_of();
| ~~
error: aborting due to 3 previous errors error: aborting due to 3 previous errors

View File

@ -54,17 +54,16 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/issue-34264.rs:7:5 --> $DIR/issue-34264.rs:7:5
| |
LL | foo(Some(42), 2, ""); LL | foo(Some(42), 2, "");
| ^^^ -- argument of type `&'static str` unexpected | ^^^ ----
| | |
| | unexpected argument of type `&'static str`
| help: remove the extra argument
| |
note: function defined here note: function defined here
--> $DIR/issue-34264.rs:1:4 --> $DIR/issue-34264.rs:1:4
| |
LL | fn foo(Option<i32>, String) {} LL | fn foo(Option<i32>, String) {}
| ^^^ ----------- ------ | ^^^ ----------- ------
help: remove the extra argument
|
LL | foo(Some(42), 2);
| ~~~~~~~~~~~~~
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/issue-34264.rs:8:13 --> $DIR/issue-34264.rs:8:13
@ -84,17 +83,16 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/issue-34264.rs:10:5 --> $DIR/issue-34264.rs:10:5
| |
LL | bar(1, 2, 3); LL | bar(1, 2, 3);
| ^^^ - argument of type `{integer}` unexpected | ^^^ ---
| | |
| | unexpected argument of type `{integer}`
| help: remove the extra argument
| |
note: function defined here note: function defined here
--> $DIR/issue-34264.rs:3:4 --> $DIR/issue-34264.rs:3:4
| |
LL | fn bar(x, y: usize) {} LL | fn bar(x, y: usize) {}
| ^^^ - -------- | ^^^ - --------
help: remove the extra argument
|
LL | bar(1, 2);
| ~~~~~~
error: aborting due to 6 previous errors error: aborting due to 6 previous errors

View File

@ -2,7 +2,7 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied
--> $DIR/args-instead-of-tuple-errors.rs:6:34 --> $DIR/args-instead-of-tuple-errors.rs:6:34
| |
LL | let _: Option<(i32, bool)> = Some(1, 2); LL | let _: Option<(i32, bool)> = Some(1, 2);
| ^^^^ - argument of type `{integer}` unexpected | ^^^^ - unexpected argument of type `{integer}`
| |
note: expected `(i32, bool)`, found integer note: expected `(i32, bool)`, found integer
--> $DIR/args-instead-of-tuple-errors.rs:6:39 --> $DIR/args-instead-of-tuple-errors.rs:6:39
@ -22,14 +22,15 @@ note: tuple variant defined here
--> $SRC_DIR/core/src/option.rs:LL:COL --> $SRC_DIR/core/src/option.rs:LL:COL
help: remove the extra argument help: remove the extra argument
| |
LL | let _: Option<(i32, bool)> = Some(/* (i32, bool) */); LL - let _: Option<(i32, bool)> = Some(1, 2);
| ~~~~~~~~~~~~~~~~~~~ LL + let _: Option<(i32, bool)> = Some(/* (i32, bool) */);
|
error[E0061]: this function takes 1 argument but 2 arguments were supplied error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/args-instead-of-tuple-errors.rs:8:5 --> $DIR/args-instead-of-tuple-errors.rs:8:5
| |
LL | int_bool(1, 2); LL | int_bool(1, 2);
| ^^^^^^^^ - argument of type `{integer}` unexpected | ^^^^^^^^ - unexpected argument of type `{integer}`
| |
note: expected `(i32, bool)`, found integer note: expected `(i32, bool)`, found integer
--> $DIR/args-instead-of-tuple-errors.rs:8:14 --> $DIR/args-instead-of-tuple-errors.rs:8:14
@ -45,8 +46,9 @@ LL | fn int_bool(_: (i32, bool)) {
| ^^^^^^^^ -------------- | ^^^^^^^^ --------------
help: remove the extra argument help: remove the extra argument
| |
LL | int_bool(/* (i32, bool) */); LL - int_bool(1, 2);
| ~~~~~~~~~~~~~~~~~~~ LL + int_bool(/* (i32, bool) */);
|
error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied
--> $DIR/args-instead-of-tuple-errors.rs:11:28 --> $DIR/args-instead-of-tuple-errors.rs:11:28

View File

@ -0,0 +1,11 @@
// Regression test for #108072: do not ICE upon unmet trait alias constraint
#![feature(trait_alias)]
trait IteratorAlias = Iterator;
fn f(_: impl IteratorAlias) {}
fn main() {
f(()) //~ `()` is not an iterator
}

View File

@ -0,0 +1,19 @@
error[E0277]: `()` is not an iterator
--> $DIR/issue-108072-unmet-trait-alias-bound.rs:10:7
|
LL | f(())
| - ^^ `()` is not an iterator
| |
| required by a bound introduced by this call
|
= help: the trait `Iterator` is not implemented for `()`
= note: required for `()` to implement `IteratorAlias`
note: required by a bound in `f`
--> $DIR/issue-108072-unmet-trait-alias-bound.rs:7:14
|
LL | fn f(_: impl IteratorAlias) {}
| ^^^^^^^^^^^^^ required by this bound in `f`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.

View File

@ -2,7 +2,7 @@ error[E0061]: this method takes 1 argument but 2 arguments were supplied
--> $DIR/wrong_argument_ice-3.rs:9:16 --> $DIR/wrong_argument_ice-3.rs:9:16
| |
LL | groups.push(new_group, vec![process]); LL | groups.push(new_group, vec![process]);
| ^^^^ ------------- argument of type `Vec<&Process>` unexpected | ^^^^ ------------- unexpected argument of type `Vec<&Process>`
| |
note: expected `(Vec<String>, Vec<Process>)`, found `Vec<String>` note: expected `(Vec<String>, Vec<Process>)`, found `Vec<String>`
--> $DIR/wrong_argument_ice-3.rs:9:21 --> $DIR/wrong_argument_ice-3.rs:9:21
@ -15,8 +15,9 @@ note: associated function defined here
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
help: remove the extra argument help: remove the extra argument
| |
LL | groups.push(/* (Vec<String>, Vec<Process>) */); LL - groups.push(new_group, vec![process]);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LL + groups.push(/* (Vec<String>, Vec<Process>) */);
|
error: aborting due to previous error error: aborting due to previous error

View File

@ -6,17 +6,16 @@ LL | (|| {})(|| {
LL | | LL | |
LL | | let b = 1; LL | | let b = 1;
LL | | }); LL | | });
| |_____- argument of type `[closure@$DIR/wrong_argument_ice-4.rs:2:13: 2:15]` unexpected | | -
| | |
| |_____unexpected argument of type `[closure@$DIR/wrong_argument_ice-4.rs:2:13: 2:15]`
| help: remove the extra argument
| |
note: closure defined here note: closure defined here
--> $DIR/wrong_argument_ice-4.rs:2:6 --> $DIR/wrong_argument_ice-4.rs:2:6
| |
LL | (|| {})(|| { LL | (|| {})(|| {
| ^^ | ^^
help: remove the extra argument
|
LL | (|| {})();
| ~~
error: aborting due to previous error error: aborting due to previous error

View File

@ -11,14 +11,13 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/type-ascription-instead-of-initializer.rs:2:12 --> $DIR/type-ascription-instead-of-initializer.rs:2:12
| |
LL | let x: Vec::with_capacity(10, 20); LL | let x: Vec::with_capacity(10, 20);
| ^^^^^^^^^^^^^^^^^^ -- argument of type `{integer}` unexpected | ^^^^^^^^^^^^^^^^^^ ----
| | |
| | unexpected argument of type `{integer}`
| help: remove the extra argument
| |
note: associated function defined here note: associated function defined here
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
help: remove the extra argument
|
LL | let x: Vec::with_capacity(10);
| ~~~~
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View File

@ -2,17 +2,16 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/remove-extra-argument.rs:6:5 --> $DIR/remove-extra-argument.rs:6:5
| |
LL | l(vec![], vec![]) LL | l(vec![], vec![])
| ^ ------ argument of type `Vec<_>` unexpected | ^ --------
| | |
| | unexpected argument of type `Vec<_>`
| help: remove the extra argument
| |
note: function defined here note: function defined here
--> $DIR/remove-extra-argument.rs:3:4 --> $DIR/remove-extra-argument.rs:3:4
| |
LL | fn l(_a: Vec<u8>) {} LL | fn l(_a: Vec<u8>) {}
| ^ ----------- | ^ -----------
help: remove the extra argument
|
LL | l(vec![])
| ~~~~~~~~
error: aborting due to previous error error: aborting due to previous error

View File

@ -2,29 +2,29 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied
--> $DIR/struct-enum-wrong-args.rs:6:13 --> $DIR/struct-enum-wrong-args.rs:6:13
| |
LL | let _ = Some(3, 2); LL | let _ = Some(3, 2);
| ^^^^ - argument of type `{integer}` unexpected | ^^^^ ---
| | |
| | unexpected argument of type `{integer}`
| help: remove the extra argument
| |
note: tuple variant defined here note: tuple variant defined here
--> $SRC_DIR/core/src/option.rs:LL:COL --> $SRC_DIR/core/src/option.rs:LL:COL
help: remove the extra argument
|
LL | let _ = Some(3);
| ~~~
error[E0061]: this enum variant takes 1 argument but 3 arguments were supplied error[E0061]: this enum variant takes 1 argument but 3 arguments were supplied
--> $DIR/struct-enum-wrong-args.rs:7:13 --> $DIR/struct-enum-wrong-args.rs:7:13
| |
LL | let _ = Ok(3, 6, 2); LL | let _ = Ok(3, 6, 2);
| ^^ - - argument of type `{integer}` unexpected | ^^ - - unexpected argument of type `{integer}`
| | | |
| argument of type `{integer}` unexpected | unexpected argument of type `{integer}`
| |
note: tuple variant defined here note: tuple variant defined here
--> $SRC_DIR/core/src/result.rs:LL:COL --> $SRC_DIR/core/src/result.rs:LL:COL
help: remove the extra arguments help: remove the extra arguments
| |
LL | let _ = Ok(3); LL - let _ = Ok(3, 6, 2);
| ~~~ LL + let _ = Ok(3);
|
error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied
--> $DIR/struct-enum-wrong-args.rs:8:13 --> $DIR/struct-enum-wrong-args.rs:8:13
@ -59,17 +59,16 @@ error[E0061]: this struct takes 1 argument but 2 arguments were supplied
--> $DIR/struct-enum-wrong-args.rs:10:13 --> $DIR/struct-enum-wrong-args.rs:10:13
| |
LL | let _ = Wrapper(5, 2); LL | let _ = Wrapper(5, 2);
| ^^^^^^^ - argument of type `{integer}` unexpected | ^^^^^^^ ---
| | |
| | unexpected argument of type `{integer}`
| help: remove the extra argument
| |
note: tuple struct defined here note: tuple struct defined here
--> $DIR/struct-enum-wrong-args.rs:2:8 --> $DIR/struct-enum-wrong-args.rs:2:8
| |
LL | struct Wrapper(i32); LL | struct Wrapper(i32);
| ^^^^^^^ | ^^^^^^^
help: remove the extra argument
|
LL | let _ = Wrapper(5);
| ~~~
error[E0061]: this struct takes 2 arguments but 0 arguments were supplied error[E0061]: this struct takes 2 arguments but 0 arguments were supplied
--> $DIR/struct-enum-wrong-args.rs:11:13 --> $DIR/struct-enum-wrong-args.rs:11:13
@ -107,17 +106,16 @@ error[E0061]: this struct takes 2 arguments but 3 arguments were supplied
--> $DIR/struct-enum-wrong-args.rs:13:13 --> $DIR/struct-enum-wrong-args.rs:13:13
| |
LL | let _ = DoubleWrapper(5, 2, 7); LL | let _ = DoubleWrapper(5, 2, 7);
| ^^^^^^^^^^^^^ - argument of type `{integer}` unexpected | ^^^^^^^^^^^^^ ---
| | |
| | unexpected argument of type `{integer}`
| help: remove the extra argument
| |
note: tuple struct defined here note: tuple struct defined here
--> $DIR/struct-enum-wrong-args.rs:3:8 --> $DIR/struct-enum-wrong-args.rs:3:8
| |
LL | struct DoubleWrapper(i32, i32); LL | struct DoubleWrapper(i32, i32);
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
help: remove the extra argument
|
LL | let _ = DoubleWrapper(5, 2);
| ~~~~~~
error: aborting due to 8 previous errors error: aborting due to 8 previous errors

View File

@ -630,7 +630,7 @@ style-team = [
"/src/stage0.json" = ["bootstrap"] "/src/stage0.json" = ["bootstrap"]
"/tests/ui" = ["compiler"] "/tests/ui" = ["compiler"]
"/src/tools/cargo" = ["@ehuss", "@joshtriplett"] "/src/tools/cargo" = ["@ehuss", "@joshtriplett"]
"/src/tools/compiletest" = ["bootstrap"] "/src/tools/compiletest" = ["bootstrap", "@wesleywiser", "@oli-obk"]
"/src/tools/linkchecker" = ["@ehuss"] "/src/tools/linkchecker" = ["@ehuss"]
"/src/tools/rust-installer" = ["bootstrap"] "/src/tools/rust-installer" = ["bootstrap"]
"/src/tools/rustbook" = ["@ehuss"] "/src/tools/rustbook" = ["@ehuss"]