Auto merge of #135754 - jieyouxu:rollup-j4q1hpr, r=jieyouxu
Rollup of 7 pull requests Successful merges: - #135542 (Add the concrete syntax for precise capturing to 1.82 release notes.) - #135700 (Emit single privacy error for struct literal with multiple private fields and add test for `default_field_values` privacy) - #135722 (make it possible to use ci-rustc on tarball sources) - #135729 (Add debug assertions to compiler profile) - #135736 (rustdoc: Fix flaky doctest test) - #135738 (Replace usages of `map_or(bool, ...)` with `is_{some_and|none_or|ok_and}`) - #135747 (Rename FileName::QuoteExpansion to CfgSpec) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
b5741a36a8
60 changed files with 367 additions and 138 deletions
|
@ -359,7 +359,7 @@ Language
|
|||
- [`addr_of(_mut)!` macros and the newly stabilized `&raw (const|mut)` are now safe to use with all static items](https://github.com/rust-lang/rust/pull/125834)
|
||||
- [size_of_val_raw: for length 0 this is safe to call](https://github.com/rust-lang/rust/pull/126152/)
|
||||
- [Reorder trait bound modifiers *after* `for<...>` binder in trait bounds](https://github.com/rust-lang/rust/pull/127054/)
|
||||
- [Stabilize opaque type precise capturing (RFC 3617)](https://github.com/rust-lang/rust/pull/127672)
|
||||
- [Stabilize `+ use<'lt>` opaque type precise capturing (RFC 3617)](https://github.com/rust-lang/rust/pull/127672)
|
||||
- [Stabilize `&raw const` and `&raw mut` operators (RFC 2582)](https://github.com/rust-lang/rust/pull/127679)
|
||||
- [Stabilize unsafe extern blocks (RFC 3484)](https://github.com/rust-lang/rust/pull/127921)
|
||||
- [Stabilize nested field access in `offset_of!`](https://github.com/rust-lang/rust/pull/128284)
|
||||
|
|
|
@ -72,7 +72,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
if let Some(local_sig_id) = def_id.as_local() {
|
||||
// The value may be missing due to recursive delegation.
|
||||
// Error will be emitted later during HIR ty lowering.
|
||||
self.resolver.delegation_fn_sigs.get(&local_sig_id).map_or(false, |sig| sig.has_self)
|
||||
self.resolver.delegation_fn_sigs.get(&local_sig_id).is_some_and(|sig| sig.has_self)
|
||||
} else {
|
||||
match self.tcx.def_kind(def_id) {
|
||||
DefKind::Fn => false,
|
||||
|
|
|
@ -83,7 +83,7 @@ impl<'a> PostExpansionVisitor<'a> {
|
|||
feature_err_issue(&self.sess, feature, span, GateIssue::Language, explain).emit();
|
||||
}
|
||||
Err(abi::AbiDisabled::Unrecognized) => {
|
||||
if self.sess.opts.pretty.map_or(true, |ppm| ppm.needs_hir()) {
|
||||
if self.sess.opts.pretty.is_none_or(|ppm| ppm.needs_hir()) {
|
||||
self.sess.dcx().span_delayed_bug(
|
||||
span,
|
||||
format!(
|
||||
|
|
|
@ -166,7 +166,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &impl AttributeExt) -> Vec<ReprAttr
|
|||
// the `check_mod_attrs` pass, but this pass doesn't always run
|
||||
// (e.g. if we only pretty-print the source), so we have to gate
|
||||
// the `span_delayed_bug` call as follows:
|
||||
if sess.opts.pretty.map_or(true, |pp| pp.needs_analysis()) {
|
||||
if sess.opts.pretty.is_none_or(|pp| pp.needs_analysis()) {
|
||||
dcx.span_delayed_bug(item.span(), "unrecognized representation hint");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2480,7 +2480,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
|||
// To support cases like `|| { v.call(|this| v.get()) }`
|
||||
// FIXME: actually support such cases (need to figure out how to move from the
|
||||
// capture place to original local).
|
||||
&& self.res.as_ref().map_or(true, |(prev_res, _)| prev_res.span.contains(ex.span))
|
||||
&& self.res.as_ref().is_none_or(|(prev_res, _)| prev_res.span.contains(ex.span))
|
||||
{
|
||||
self.res = Some((ex, closure));
|
||||
}
|
||||
|
|
|
@ -131,10 +131,10 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
|||
&& let Ok(pat) = tcx.sess.source_map().span_to_snippet(pat.span)
|
||||
{
|
||||
suggest_rewrite_if_let(tcx, expr, &pat, init, conseq, alt, err);
|
||||
} else if path_span.map_or(true, |path_span| path_span == var_or_use_span) {
|
||||
} else if path_span.is_none_or(|path_span| path_span == var_or_use_span) {
|
||||
// We can use `var_or_use_span` if either `path_span` is not present, or both
|
||||
// spans are the same.
|
||||
if borrow_span.map_or(true, |sp| !sp.overlaps(var_or_use_span)) {
|
||||
if borrow_span.is_none_or(|sp| !sp.overlaps(var_or_use_span)) {
|
||||
err.span_label(
|
||||
var_or_use_span,
|
||||
format!("{borrow_desc}borrow later {message}"),
|
||||
|
|
|
@ -442,7 +442,7 @@ pub(crate) fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) ->
|
|||
// (or if there is no allocator argument).
|
||||
ty::Adt(def, args)
|
||||
if def.is_box()
|
||||
&& args.get(1).map_or(true, |arg| cx.layout_of(arg.expect_ty()).is_1zst()) =>
|
||||
&& args.get(1).is_none_or(|arg| cx.layout_of(arg.expect_ty()).is_1zst()) =>
|
||||
{
|
||||
build_pointer_or_reference_di_node(cx, t, t.expect_boxed_ty(), unique_type_id)
|
||||
}
|
||||
|
|
|
@ -3146,7 +3146,7 @@ impl FileWithAnnotatedLines {
|
|||
add_annotation_to_file(&mut output, Lrc::clone(&file), line, ann.as_line());
|
||||
}
|
||||
let line_end = ann.line_end - 1;
|
||||
let end_is_empty = file.get_line(line_end - 1).map_or(false, |s| !filter(&s));
|
||||
let end_is_empty = file.get_line(line_end - 1).is_some_and(|s| !filter(&s));
|
||||
if middle < line_end && !end_is_empty {
|
||||
add_annotation_to_file(&mut output, Lrc::clone(&file), line_end, ann.as_line());
|
||||
}
|
||||
|
|
|
@ -463,7 +463,8 @@ impl DiagnosticSpan {
|
|||
// is an empty string, increase the length to include the newline so we don't
|
||||
// leave an empty line
|
||||
if start.col.0 == 0
|
||||
&& suggestion.map_or(false, |(s, _)| s.is_empty())
|
||||
&& let Some((suggestion, _)) = suggestion
|
||||
&& suggestion.is_empty()
|
||||
&& let Ok(after) = je.sm.span_to_next_source(span)
|
||||
&& after.starts_with('\n')
|
||||
{
|
||||
|
|
|
@ -35,6 +35,7 @@ use std::backtrace::{Backtrace, BacktraceStatus};
|
|||
use std::borrow::Cow;
|
||||
use std::cell::Cell;
|
||||
use std::error::Report;
|
||||
use std::ffi::OsStr;
|
||||
use std::hash::Hash;
|
||||
use std::io::Write;
|
||||
use std::num::NonZero;
|
||||
|
@ -1717,7 +1718,7 @@ impl DiagCtxtInner {
|
|||
let bugs: Vec<_> =
|
||||
std::mem::take(&mut self.delayed_bugs).into_iter().map(|(b, _)| b).collect();
|
||||
|
||||
let backtrace = std::env::var_os("RUST_BACKTRACE").map_or(true, |x| &x != "0");
|
||||
let backtrace = std::env::var_os("RUST_BACKTRACE").as_deref() != Some(OsStr::new("0"));
|
||||
let decorate = backtrace || self.ice_file.is_none();
|
||||
let mut out = self
|
||||
.ice_file
|
||||
|
|
|
@ -391,7 +391,7 @@ impl<'a> StripUnconfigured<'a> {
|
|||
validate_attr::deny_builtin_meta_unsafety(&self.sess.psess, &meta_item);
|
||||
|
||||
(
|
||||
parse_cfg(&meta_item, self.sess).map_or(true, |meta_item| {
|
||||
parse_cfg(&meta_item, self.sess).is_none_or(|meta_item| {
|
||||
attr::cfg_matches(meta_item, &self.sess, self.lint_node_id, self.features)
|
||||
}),
|
||||
Some(meta_item),
|
||||
|
|
|
@ -159,7 +159,7 @@ impl<'dcx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'dcx, 'match
|
|||
if self
|
||||
.best_failure
|
||||
.as_ref()
|
||||
.map_or(true, |failure| failure.is_better_position(*approx_position))
|
||||
.is_none_or(|failure| failure.is_better_position(*approx_position))
|
||||
{
|
||||
self.best_failure = Some(BestFailure {
|
||||
token: token.clone(),
|
||||
|
|
|
@ -794,7 +794,7 @@ impl<Id> Res<Id> {
|
|||
|
||||
/// Always returns `true` if `self` is `Res::Err`
|
||||
pub fn matches_ns(&self, ns: Namespace) -> bool {
|
||||
self.ns().map_or(true, |actual_ns| actual_ns == ns)
|
||||
self.ns().is_none_or(|actual_ns| actual_ns == ns)
|
||||
}
|
||||
|
||||
/// Returns whether such a resolved path can occur in a tuple struct/variant pattern
|
||||
|
|
|
@ -1210,7 +1210,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// - foo((), "current", 42u32, "next")
|
||||
// + foo((), 42u32)
|
||||
{
|
||||
prev_extra_idx.map_or(true, |prev_extra_idx| {
|
||||
prev_extra_idx.is_none_or(|prev_extra_idx| {
|
||||
prev_extra_idx + 1 == arg_idx.index()
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1143,7 +1143,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
self.may_coerce(found, ty)
|
||||
}
|
||||
hir::FnRetTy::DefaultReturn(_) if in_closure => {
|
||||
self.ret_coercion.as_ref().map_or(false, |ret| {
|
||||
self.ret_coercion.as_ref().is_some_and(|ret| {
|
||||
let ret_ty = ret.borrow().expected_ty();
|
||||
self.may_coerce(found, ret_ty)
|
||||
})
|
||||
|
@ -1784,14 +1784,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let results = self.typeck_results.borrow();
|
||||
// First, look for a `Clone::clone` call
|
||||
if segment.ident.name == sym::clone
|
||||
&& results.type_dependent_def_id(expr.hir_id).map_or(
|
||||
false,
|
||||
|did| {
|
||||
&& results.type_dependent_def_id(expr.hir_id).is_some_and(|did| {
|
||||
let assoc_item = self.tcx.associated_item(did);
|
||||
assoc_item.container == ty::AssocItemContainer::Trait
|
||||
&& assoc_item.container_id(self.tcx) == clone_trait_did
|
||||
},
|
||||
)
|
||||
})
|
||||
// If that clone call hasn't already dereferenced the self type (i.e. don't give this
|
||||
// diagnostic in cases where we have `(&&T).clone()` and we expect `T`).
|
||||
&& !results.expr_adjustments(callee_expr).iter().any(|adj| matches!(adj.kind, ty::adjustment::Adjust::Deref(..)))
|
||||
|
|
|
@ -3761,18 +3761,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
hir::TraitFn::Required([ident, ..]) => {
|
||||
ident.name == kw::SelfLower
|
||||
}
|
||||
hir::TraitFn::Provided(body_id) => {
|
||||
self.tcx.hir().body(*body_id).params.first().map_or(
|
||||
false,
|
||||
|param| {
|
||||
matches!(
|
||||
param.pat.kind,
|
||||
hir::PatKind::Binding(_, _, ident, _)
|
||||
if ident.name == kw::SelfLower
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
hir::TraitFn::Provided(body_id) => self
|
||||
.tcx
|
||||
.hir()
|
||||
.body(*body_id)
|
||||
.params
|
||||
.first()
|
||||
.is_some_and(|param| {
|
||||
matches!(
|
||||
param.pat.kind,
|
||||
hir::PatKind::Binding(_, _, ident, _)
|
||||
if ident.name == kw::SelfLower
|
||||
)
|
||||
}),
|
||||
_ => false,
|
||||
};
|
||||
|
||||
|
|
|
@ -258,7 +258,7 @@ impl<I: Idx> IntervalSet<I> {
|
|||
}
|
||||
current = Some(*end);
|
||||
}
|
||||
current.map_or(true, |x| x < self.domain as u32)
|
||||
current.is_none_or(|x| x < self.domain as u32)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option<Symbol>) {
|
|||
let expect_id = canonicalize_id(expect_id);
|
||||
|
||||
if !fulfilled_expectations.contains(&expect_id)
|
||||
&& tool_filter.map_or(true, |filter| expectation.lint_tool == Some(filter))
|
||||
&& tool_filter.is_none_or(|filter| expectation.lint_tool == Some(filter))
|
||||
{
|
||||
let rationale = expectation.reason.map(|rationale| ExpectationNote { rationale });
|
||||
let note = expectation.is_unfulfilled_lint_expectations;
|
||||
|
|
|
@ -417,7 +417,8 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
|
|||
// Any descendants of `std` should be private. These crates are usually not marked
|
||||
// private in metadata, so we ignore that field.
|
||||
if extern_private.is_none()
|
||||
&& dep_root.map_or(false, |d| STDLIB_STABLE_CRATES.contains(&d.name))
|
||||
&& let Some(dep) = dep_root
|
||||
&& STDLIB_STABLE_CRATES.contains(&dep.name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
|
|||
debug_assert!(prov.len() <= 1);
|
||||
if let Some(entry) = prov.first() {
|
||||
// If it overlaps with this byte, it is on this byte.
|
||||
debug_assert!(self.bytes.as_ref().map_or(true, |b| b.get(&offset).is_none()));
|
||||
debug_assert!(self.bytes.as_ref().is_none_or(|b| !b.contains_key(&offset)));
|
||||
Some(entry.1)
|
||||
} else {
|
||||
// Look up per-byte provenance.
|
||||
|
@ -301,7 +301,7 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
|
|||
// For really small copies, make sure we don't start before `src` does.
|
||||
let entry_start = cmp::max(entry.0, src.start);
|
||||
for offset in entry_start..src.end() {
|
||||
if bytes.last().map_or(true, |bytes_entry| bytes_entry.0 < offset) {
|
||||
if bytes.last().is_none_or(|bytes_entry| bytes_entry.0 < offset) {
|
||||
// The last entry, if it exists, has a lower offset than us.
|
||||
bytes.push((offset, entry.1));
|
||||
} else {
|
||||
|
|
|
@ -433,7 +433,7 @@ pub fn analyze_coroutine_closure_captures<'a, 'tcx: 'a, T>(
|
|||
// A parent matches a child if they share the same prefix of projections.
|
||||
// The child may have more, if it is capturing sub-fields out of
|
||||
// something that is captured by-move in the parent closure.
|
||||
while child_captures.peek().map_or(false, |(_, child_capture)| {
|
||||
while child_captures.peek().is_some_and(|(_, child_capture)| {
|
||||
child_prefix_matches_parent_projections(parent_capture, child_capture)
|
||||
}) {
|
||||
let (child_field_idx, child_capture) = child_captures.next().unwrap();
|
||||
|
|
|
@ -336,7 +336,7 @@ pub fn suggest_constraining_type_params<'a>(
|
|||
.collect();
|
||||
|
||||
constraints
|
||||
.retain(|(_, def_id, _)| def_id.map_or(true, |def| !bound_trait_defs.contains(&def)));
|
||||
.retain(|(_, def_id, _)| def_id.is_none_or(|def| !bound_trait_defs.contains(&def)));
|
||||
|
||||
if constraints.is_empty() {
|
||||
continue;
|
||||
|
|
|
@ -328,7 +328,7 @@ impl<'tcx> InstanceKind<'tcx> {
|
|||
// We include enums without destructors to allow, say, optimizing
|
||||
// drops of `Option::None` before LTO. We also respect the intent of
|
||||
// `#[inline]` on `Drop::drop` implementations.
|
||||
return ty.ty_adt_def().map_or(true, |adt_def| {
|
||||
return ty.ty_adt_def().is_none_or(|adt_def| {
|
||||
match *self {
|
||||
ty::InstanceKind::DropGlue(..) => adt_def.destructor(tcx).map(|dtor| dtor.did),
|
||||
ty::InstanceKind::AsyncDropGlueCtorShim(..) => {
|
||||
|
|
|
@ -1894,11 +1894,11 @@ impl<'tcx> Ty<'tcx> {
|
|||
|
||||
ty::Str | ty::Slice(_) | ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => false,
|
||||
|
||||
ty::Tuple(tys) => tys.last().map_or(true, |ty| ty.is_trivially_sized(tcx)),
|
||||
ty::Tuple(tys) => tys.last().is_none_or(|ty| ty.is_trivially_sized(tcx)),
|
||||
|
||||
ty::Adt(def, args) => def
|
||||
.sized_constraint(tcx)
|
||||
.map_or(true, |ty| ty.instantiate(tcx, args).is_trivially_sized(tcx)),
|
||||
.is_none_or(|ty| ty.instantiate(tcx, args).is_trivially_sized(tcx)),
|
||||
|
||||
ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) | ty::Bound(..) => false,
|
||||
|
||||
|
|
|
@ -360,7 +360,7 @@ fn find_item_ty_spans(
|
|||
if let Res::Def(kind, def_id) = path.res
|
||||
&& matches!(kind, DefKind::Enum | DefKind::Struct | DefKind::Union)
|
||||
{
|
||||
let check_params = def_id.as_local().map_or(true, |def_id| {
|
||||
let check_params = def_id.as_local().is_none_or(|def_id| {
|
||||
if def_id == needle {
|
||||
spans.push(ty.span);
|
||||
}
|
||||
|
|
|
@ -266,7 +266,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for LayoutConstrainedPlaceVisitor<'a, 'tcx> {
|
|||
// place, i.e. the expression is a place expression and not a dereference
|
||||
// (since dereferencing something leads us to a different place).
|
||||
ExprKind::Deref { .. } => {}
|
||||
ref kind if ExprCategory::of(kind).map_or(true, |cat| cat == ExprCategory::Place) => {
|
||||
ref kind if ExprCategory::of(kind).is_none_or(|cat| cat == ExprCategory::Place) => {
|
||||
visit::walk_expr(self, expr);
|
||||
}
|
||||
|
||||
|
|
|
@ -608,7 +608,7 @@ where
|
|||
let before = diffs_before.as_mut().map(next_in_dataflow_order);
|
||||
|
||||
assert!(diffs_after.is_empty());
|
||||
assert!(diffs_before.as_ref().map_or(true, ExactSizeIterator::is_empty));
|
||||
assert!(diffs_before.as_ref().is_none_or(ExactSizeIterator::is_empty));
|
||||
|
||||
let terminator = self.cursor.body()[block].terminator();
|
||||
let mut terminator_str = String::new();
|
||||
|
|
|
@ -135,7 +135,7 @@ impl CoverageGraph {
|
|||
bb_to_bcb[bb] = Some(bcb);
|
||||
}
|
||||
|
||||
let is_out_summable = basic_blocks.last().map_or(false, |&bb| {
|
||||
let is_out_summable = basic_blocks.last().is_some_and(|&bb| {
|
||||
bcb_filtered_successors(mir_body[bb].terminator()).is_out_summable()
|
||||
});
|
||||
let bcb_data = BasicCoverageBlockData { basic_blocks, is_out_summable };
|
||||
|
|
|
@ -273,7 +273,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
|||
//
|
||||
// For this we set `next_orig_uv` to the next smallest, not yet compressed,
|
||||
// universe of the input.
|
||||
if next_orig_uv.map_or(true, |curr_next_uv| uv.cannot_name(curr_next_uv)) {
|
||||
if next_orig_uv.is_none_or(|curr_next_uv| uv.cannot_name(curr_next_uv)) {
|
||||
next_orig_uv = Some(uv);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2095,7 +2095,7 @@ impl<'a> Parser<'a> {
|
|||
// point literal here, since there's no use of the exponent
|
||||
// syntax that also constitutes a valid integer, so we need
|
||||
// not check for that.
|
||||
if suffix.map_or(true, |s| s == sym::f32 || s == sym::f64)
|
||||
if suffix.is_none_or(|s| s == sym::f32 || s == sym::f64)
|
||||
&& symbol.as_str().chars().all(|c| c.is_numeric() || c == '_')
|
||||
&& self.token.span.hi() == next_token.span.lo()
|
||||
{
|
||||
|
|
|
@ -1231,7 +1231,7 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {
|
|||
continue;
|
||||
}
|
||||
|
||||
let is_positional = variant.fields.raw.first().map_or(false, |field| {
|
||||
let is_positional = variant.fields.raw.first().is_some_and(|field| {
|
||||
field.name.as_str().starts_with(|c: char| c.is_ascii_digit())
|
||||
});
|
||||
let report_on =
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
privacy_field_is_private = field `{$field_name}` of {$variant_descr} `{$def_path_str}` is private
|
||||
privacy_field_is_private_is_update_syntax_label = field `{$field_name}` is private
|
||||
privacy_field_is_private =
|
||||
{$len ->
|
||||
[1] field
|
||||
*[other] fields
|
||||
} {$field_names} of {$variant_descr} `{$def_path_str}` {$len ->
|
||||
[1] is
|
||||
*[other] are
|
||||
} private
|
||||
.label = in this type
|
||||
privacy_field_is_private_is_update_syntax_label = {$rest_len ->
|
||||
[1] field
|
||||
*[other] fields
|
||||
} {$rest_field_names} {$rest_len ->
|
||||
[1] is
|
||||
*[other] are
|
||||
} private
|
||||
privacy_field_is_private_label = private field
|
||||
|
||||
privacy_from_private_dep_in_public_interface =
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc_errors::DiagArgFromDisplay;
|
||||
use rustc_errors::codes::*;
|
||||
use rustc_errors::{DiagArgFromDisplay, MultiSpan};
|
||||
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
||||
|
@ -7,12 +7,15 @@ use rustc_span::{Span, Symbol};
|
|||
#[diag(privacy_field_is_private, code = E0451)]
|
||||
pub(crate) struct FieldIsPrivate {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub field_name: Symbol,
|
||||
pub span: MultiSpan,
|
||||
#[label]
|
||||
pub struct_span: Option<Span>,
|
||||
pub field_names: String,
|
||||
pub variant_descr: &'static str,
|
||||
pub def_path_str: String,
|
||||
#[subdiagnostic]
|
||||
pub label: FieldIsPrivateLabel,
|
||||
pub labels: Vec<FieldIsPrivateLabel>,
|
||||
pub len: usize,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
|
@ -21,7 +24,8 @@ pub(crate) enum FieldIsPrivateLabel {
|
|||
IsUpdateSyntax {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
field_name: Symbol,
|
||||
rest_field_names: String,
|
||||
rest_len: usize,
|
||||
},
|
||||
#[label(privacy_field_is_private_label)]
|
||||
Other {
|
||||
|
|
|
@ -24,6 +24,7 @@ use rustc_ast::MacroDef;
|
|||
use rustc_ast::visit::{VisitorResult, try_visit};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_errors::MultiSpan;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId, LocalModDefId};
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
|
@ -38,7 +39,7 @@ use rustc_middle::ty::{
|
|||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_session::lint;
|
||||
use rustc_span::hygiene::Transparency;
|
||||
use rustc_span::{Ident, Span, kw, sym};
|
||||
use rustc_span::{Ident, Span, Symbol, kw, sym};
|
||||
use tracing::debug;
|
||||
use {rustc_attr_parsing as attr, rustc_hir as hir};
|
||||
|
||||
|
@ -921,31 +922,95 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
|
|||
&mut self,
|
||||
hir_id: hir::HirId, // ID of the field use
|
||||
use_ctxt: Span, // syntax context of the field name at the use site
|
||||
span: Span, // span of the field pattern, e.g., `x: 0`
|
||||
def: ty::AdtDef<'tcx>, // definition of the struct or enum
|
||||
field: &'tcx ty::FieldDef,
|
||||
in_update_syntax: bool,
|
||||
) {
|
||||
) -> bool {
|
||||
if def.is_enum() {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
// definition of the field
|
||||
let ident = Ident::new(kw::Empty, use_ctxt);
|
||||
let def_id = self.tcx.adjust_ident_and_get_scope(ident, def.did(), hir_id).1;
|
||||
if !field.vis.is_accessible_from(def_id, self.tcx) {
|
||||
self.tcx.dcx().emit_err(FieldIsPrivate {
|
||||
span,
|
||||
field_name: field.name,
|
||||
variant_descr: def.variant_descr(),
|
||||
def_path_str: self.tcx.def_path_str(def.did()),
|
||||
label: if in_update_syntax {
|
||||
FieldIsPrivateLabel::IsUpdateSyntax { span, field_name: field.name }
|
||||
} else {
|
||||
FieldIsPrivateLabel::Other { span }
|
||||
},
|
||||
});
|
||||
!field.vis.is_accessible_from(def_id, self.tcx)
|
||||
}
|
||||
|
||||
// Checks that a field in a struct constructor (expression or pattern) is accessible.
|
||||
fn emit_unreachable_field_error(
|
||||
&mut self,
|
||||
fields: Vec<(Symbol, Span, bool /* field is present */)>,
|
||||
def: ty::AdtDef<'tcx>, // definition of the struct or enum
|
||||
update_syntax: Option<Span>,
|
||||
struct_span: Span,
|
||||
) {
|
||||
if def.is_enum() || fields.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
// error[E0451]: fields `beta` and `gamma` of struct `Alpha` are private
|
||||
// --> $DIR/visibility.rs:18:13
|
||||
// |
|
||||
// LL | let _x = Alpha {
|
||||
// | ----- in this type # from `def`
|
||||
// LL | beta: 0,
|
||||
// | ^^^^^^^ private field # `fields.2` is `true`
|
||||
// LL | ..
|
||||
// | ^^ field `gamma` is private # `fields.2` is `false`
|
||||
|
||||
// Get the list of all private fields for the main message.
|
||||
let field_names: Vec<_> = fields.iter().map(|(name, _, _)| name).collect();
|
||||
let field_names = match &field_names[..] {
|
||||
[] => return,
|
||||
[name] => format!("`{name}`"),
|
||||
[fields @ .., last] => format!(
|
||||
"{} and `{last}`",
|
||||
fields.iter().map(|f| format!("`{f}`")).collect::<Vec<_>>().join(", "),
|
||||
),
|
||||
};
|
||||
let span: MultiSpan = fields.iter().map(|(_, span, _)| *span).collect::<Vec<Span>>().into();
|
||||
|
||||
// Get the list of all private fields when pointing at the `..rest`.
|
||||
let rest_field_names: Vec<_> =
|
||||
fields.iter().filter(|(_, _, is_present)| !is_present).map(|(n, _, _)| n).collect();
|
||||
let rest_len = rest_field_names.len();
|
||||
let rest_field_names = match &rest_field_names[..] {
|
||||
[] => String::new(),
|
||||
[name] => format!("`{name}`"),
|
||||
[fields @ .., last] => format!(
|
||||
"{} and `{last}`",
|
||||
fields.iter().map(|f| format!("`{f}`")).collect::<Vec<_>>().join(", "),
|
||||
),
|
||||
};
|
||||
// Get all the labels for each field or `..rest` in the primary MultiSpan.
|
||||
let labels = fields
|
||||
.iter()
|
||||
.filter(|(_, _, is_present)| *is_present)
|
||||
.map(|(_, span, _)| FieldIsPrivateLabel::Other { span: *span })
|
||||
.chain(update_syntax.iter().map(|span| FieldIsPrivateLabel::IsUpdateSyntax {
|
||||
span: *span,
|
||||
rest_field_names: rest_field_names.clone(),
|
||||
rest_len,
|
||||
}))
|
||||
.collect();
|
||||
|
||||
self.tcx.dcx().emit_err(FieldIsPrivate {
|
||||
span,
|
||||
struct_span: if self
|
||||
.tcx
|
||||
.sess
|
||||
.source_map()
|
||||
.is_multiline(fields[0].1.between(struct_span))
|
||||
{
|
||||
Some(struct_span)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
field_names: field_names.clone(),
|
||||
variant_descr: def.variant_descr(),
|
||||
def_path_str: self.tcx.def_path_str(def.did()),
|
||||
labels,
|
||||
len: fields.len(),
|
||||
});
|
||||
}
|
||||
|
||||
fn check_expanded_fields(
|
||||
|
@ -955,7 +1020,9 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
|
|||
fields: &[hir::ExprField<'tcx>],
|
||||
hir_id: hir::HirId,
|
||||
span: Span,
|
||||
struct_span: Span,
|
||||
) {
|
||||
let mut failed_fields = vec![];
|
||||
for (vf_index, variant_field) in variant.fields.iter_enumerated() {
|
||||
let field =
|
||||
fields.iter().find(|f| self.typeck_results().field_index(f.hir_id) == vf_index);
|
||||
|
@ -963,8 +1030,15 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
|
|||
Some(field) => (field.hir_id, field.ident.span, field.span),
|
||||
None => (hir_id, span, span),
|
||||
};
|
||||
self.check_field(hir_id, use_ctxt, span, adt, variant_field, true);
|
||||
if self.check_field(hir_id, use_ctxt, adt, variant_field) {
|
||||
let name = match field {
|
||||
Some(field) => field.ident.name,
|
||||
None => variant_field.name,
|
||||
};
|
||||
failed_fields.push((name, span, field.is_some()));
|
||||
}
|
||||
}
|
||||
self.emit_unreachable_field_error(failed_fields, adt, Some(span), struct_span);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -990,24 +1064,35 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
|
|||
// If the expression uses FRU we need to make sure all the unmentioned fields
|
||||
// are checked for privacy (RFC 736). Rather than computing the set of
|
||||
// unmentioned fields, just check them all.
|
||||
self.check_expanded_fields(adt, variant, fields, base.hir_id, base.span);
|
||||
self.check_expanded_fields(
|
||||
adt,
|
||||
variant,
|
||||
fields,
|
||||
base.hir_id,
|
||||
base.span,
|
||||
qpath.span(),
|
||||
);
|
||||
}
|
||||
hir::StructTailExpr::DefaultFields(span) => {
|
||||
self.check_expanded_fields(adt, variant, fields, expr.hir_id, span);
|
||||
self.check_expanded_fields(
|
||||
adt,
|
||||
variant,
|
||||
fields,
|
||||
expr.hir_id,
|
||||
span,
|
||||
qpath.span(),
|
||||
);
|
||||
}
|
||||
hir::StructTailExpr::None => {
|
||||
let mut failed_fields = vec![];
|
||||
for field in fields {
|
||||
let (hir_id, use_ctxt, span) = (field.hir_id, field.ident.span, field.span);
|
||||
let (hir_id, use_ctxt) = (field.hir_id, field.ident.span);
|
||||
let index = self.typeck_results().field_index(field.hir_id);
|
||||
self.check_field(
|
||||
hir_id,
|
||||
use_ctxt,
|
||||
span,
|
||||
adt,
|
||||
&variant.fields[index],
|
||||
false,
|
||||
);
|
||||
if self.check_field(hir_id, use_ctxt, adt, &variant.fields[index]) {
|
||||
failed_fields.push((field.ident.name, field.ident.span, true));
|
||||
}
|
||||
}
|
||||
self.emit_unreachable_field_error(failed_fields, adt, None, qpath.span());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1020,11 +1105,15 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
|
|||
let res = self.typeck_results().qpath_res(qpath, pat.hir_id);
|
||||
let adt = self.typeck_results().pat_ty(pat).ty_adt_def().unwrap();
|
||||
let variant = adt.variant_of_res(res);
|
||||
let mut failed_fields = vec![];
|
||||
for field in fields {
|
||||
let (hir_id, use_ctxt, span) = (field.hir_id, field.ident.span, field.span);
|
||||
let (hir_id, use_ctxt) = (field.hir_id, field.ident.span);
|
||||
let index = self.typeck_results().field_index(field.hir_id);
|
||||
self.check_field(hir_id, use_ctxt, span, adt, &variant.fields[index], false);
|
||||
if self.check_field(hir_id, use_ctxt, adt, &variant.fields[index]) {
|
||||
failed_fields.push((field.ident.name, field.ident.span, true));
|
||||
}
|
||||
}
|
||||
self.emit_unreachable_field_error(failed_fields, adt, None, qpath.span());
|
||||
}
|
||||
|
||||
intravisit::walk_pat(self, pat);
|
||||
|
|
|
@ -397,7 +397,7 @@ impl Resolver<'_, '_> {
|
|||
}
|
||||
ImportKind::ExternCrate { id, .. } => {
|
||||
let def_id = self.local_def_id(id);
|
||||
if self.extern_crate_map.get(&def_id).map_or(true, |&cnum| {
|
||||
if self.extern_crate_map.get(&def_id).is_none_or(|&cnum| {
|
||||
!tcx.is_compiler_builtins(cnum)
|
||||
&& !tcx.is_panic_runtime(cnum)
|
||||
&& !tcx.has_global_allocator(cnum)
|
||||
|
|
|
@ -322,7 +322,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
let duplicate = new_binding.res().opt_def_id() == old_binding.res().opt_def_id();
|
||||
let has_dummy_span = new_binding.span.is_dummy() || old_binding.span.is_dummy();
|
||||
let from_item =
|
||||
self.extern_prelude.get(&ident).map_or(true, |entry| entry.introduced_by_item);
|
||||
self.extern_prelude.get(&ident).is_none_or(|entry| entry.introduced_by_item);
|
||||
// Only suggest removing an import if both bindings are to the same def, if both spans
|
||||
// aren't dummy spans. Further, if both bindings are imports, then the ident must have
|
||||
// been introduced by an item.
|
||||
|
@ -537,7 +537,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
) {
|
||||
module.for_each_child(self, |_this, ident, _ns, binding| {
|
||||
let res = binding.res();
|
||||
if filter_fn(res) && ctxt.map_or(true, |ctxt| ctxt == ident.span.ctxt()) {
|
||||
if filter_fn(res) && ctxt.is_none_or(|ctxt| ctxt == ident.span.ctxt()) {
|
||||
names.push(TypoSuggestion::typo_from_ident(ident, res));
|
||||
}
|
||||
});
|
||||
|
@ -1229,7 +1229,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
_ => res.opt_def_id(),
|
||||
};
|
||||
let child_doc_visible = doc_visible
|
||||
&& (did.map_or(true, |did| did.is_local() || !this.tcx.is_doc_hidden(did)));
|
||||
&& did.is_none_or(|did| did.is_local() || !this.tcx.is_doc_hidden(did));
|
||||
|
||||
// collect results based on the filter function
|
||||
// avoid suggesting anything from the same module in which we are resolving
|
||||
|
|
|
@ -289,7 +289,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
|
||||
if let ImportKind::Glob { ref max_vis, .. } = import.kind {
|
||||
if vis == import_vis
|
||||
|| max_vis.get().map_or(true, |max_vis| vis.is_at_least(max_vis, self.tcx))
|
||||
|| max_vis.get().is_none_or(|max_vis| vis.is_at_least(max_vis, self.tcx))
|
||||
{
|
||||
max_vis.set(Some(vis.expect_local()))
|
||||
}
|
||||
|
|
|
@ -612,7 +612,7 @@ impl MaybeExported<'_> {
|
|||
return vis.kind.is_pub();
|
||||
}
|
||||
};
|
||||
def_id.map_or(true, |def_id| r.effective_visibilities.is_exported(def_id))
|
||||
def_id.is_none_or(|def_id| r.effective_visibilities.is_exported(def_id))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5104,7 +5104,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
fn def_id_matches_path(tcx: TyCtxt<'_>, mut def_id: DefId, expected_path: &[&str]) -> bool {
|
||||
let mut path = expected_path.iter().rev();
|
||||
while let (Some(parent), Some(next_step)) = (tcx.opt_parent(def_id), path.next()) {
|
||||
if !tcx.opt_item_name(def_id).map_or(false, |n| n.as_str() == *next_step) {
|
||||
if !tcx.opt_item_name(def_id).is_some_and(|n| n.as_str() == *next_step) {
|
||||
return false;
|
||||
}
|
||||
def_id = parent;
|
||||
|
|
|
@ -1696,7 +1696,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
|||
) => {
|
||||
// Don't suggest macro if it's unstable.
|
||||
let suggestable = def_id.is_local()
|
||||
|| self.r.tcx.lookup_stability(def_id).map_or(true, |s| s.is_stable());
|
||||
|| self.r.tcx.lookup_stability(def_id).is_none_or(|s| s.is_stable());
|
||||
|
||||
err.span_label(span, fallback_label.to_string());
|
||||
|
||||
|
@ -2135,7 +2135,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
|||
.r
|
||||
.delegation_fn_sigs
|
||||
.get(&self.r.local_def_id(assoc_item.id))
|
||||
.map_or(false, |sig| sig.has_self) =>
|
||||
.is_some_and(|sig| sig.has_self) =>
|
||||
{
|
||||
AssocSuggestion::MethodWithSelf { called }
|
||||
}
|
||||
|
@ -2166,7 +2166,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
|||
.r
|
||||
.delegation_fn_sigs
|
||||
.get(&def_id)
|
||||
.map_or(false, |sig| sig.has_self),
|
||||
.is_some_and(|sig| sig.has_self),
|
||||
None => self
|
||||
.r
|
||||
.tcx
|
||||
|
|
|
@ -1242,7 +1242,7 @@ impl<'ra> ResolverArenas<'ra> {
|
|||
no_implicit_prelude,
|
||||
))));
|
||||
let def_id = module.opt_def_id();
|
||||
if def_id.map_or(true, |def_id| def_id.is_local()) {
|
||||
if def_id.is_none_or(|def_id| def_id.is_local()) {
|
||||
self.local_modules.borrow_mut().push(module);
|
||||
}
|
||||
if let Some(def_id) = def_id {
|
||||
|
|
|
@ -1022,7 +1022,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
span: Span,
|
||||
) {
|
||||
if let Some(Res::NonMacroAttr(kind)) = res {
|
||||
if kind != NonMacroAttrKind::Tool && binding.map_or(true, |b| b.is_import()) {
|
||||
if kind != NonMacroAttrKind::Tool && binding.is_none_or(|b| b.is_import()) {
|
||||
let binding_span = binding.map(|binding| binding.span);
|
||||
self.dcx().emit_err(errors::CannotUseThroughAnImport {
|
||||
span,
|
||||
|
|
|
@ -350,10 +350,7 @@ pub fn strip_generics_from_path(path_str: &str) -> Result<Box<str>, MalformedGen
|
|||
/// If there are no doc-comments, return true.
|
||||
/// FIXME(#78591): Support both inner and outer attributes on the same item.
|
||||
pub fn inner_docs(attrs: &[impl AttributeExt]) -> bool {
|
||||
attrs
|
||||
.iter()
|
||||
.find(|a| a.doc_str().is_some())
|
||||
.map_or(true, |a| a.style() == ast::AttrStyle::Inner)
|
||||
attrs.iter().find(|a| a.doc_str().is_some()).is_none_or(|a| a.style() == ast::AttrStyle::Inner)
|
||||
}
|
||||
|
||||
/// Has `#[rustc_doc_primitive]` or `#[doc(keyword)]`.
|
||||
|
|
|
@ -675,7 +675,7 @@ impl OutputTypes {
|
|||
|
||||
/// Returns `true` if user specified a name and not just produced type
|
||||
pub fn contains_explicit_name(&self, key: &OutputType) -> bool {
|
||||
self.0.get(key).map_or(false, |f| f.is_some())
|
||||
matches!(self.0.get(key), Some(Some(..)))
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> BTreeMapIter<'_, OutputType, Option<OutFileName>> {
|
||||
|
@ -888,7 +888,7 @@ impl Input {
|
|||
Input::File(file) => Some(file),
|
||||
Input::Str { name, .. } => match name {
|
||||
FileName::Real(real) => real.local_path(),
|
||||
FileName::QuoteExpansion(_) => None,
|
||||
FileName::CfgSpec(_) => None,
|
||||
FileName::Anon(_) => None,
|
||||
FileName::MacroExpansion(_) => None,
|
||||
FileName::ProcMacroSourceCode(_) => None,
|
||||
|
@ -1951,7 +1951,7 @@ fn collect_print_requests(
|
|||
matches: &getopts::Matches,
|
||||
) -> Vec<PrintRequest> {
|
||||
let mut prints = Vec::<PrintRequest>::new();
|
||||
if cg.target_cpu.as_ref().is_some_and(|s| s == "help") {
|
||||
if cg.target_cpu.as_deref() == Some("help") {
|
||||
prints.push(PrintRequest { kind: PrintKind::TargetCPUs, out: OutFileName::Stdout });
|
||||
cg.target_cpu = None;
|
||||
};
|
||||
|
|
|
@ -305,8 +305,8 @@ impl RealFileName {
|
|||
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash, Decodable, Encodable)]
|
||||
pub enum FileName {
|
||||
Real(RealFileName),
|
||||
/// Call to `quote!`.
|
||||
QuoteExpansion(Hash64),
|
||||
/// Strings provided as `--cfg [cfgspec]`.
|
||||
CfgSpec(Hash64),
|
||||
/// Command line.
|
||||
Anon(Hash64),
|
||||
/// Hack in `src/librustc_ast/parse.rs`.
|
||||
|
@ -353,7 +353,7 @@ impl fmt::Display for FileNameDisplay<'_> {
|
|||
Real(ref name) => {
|
||||
write!(fmt, "{}", name.to_string_lossy(self.display_pref))
|
||||
}
|
||||
QuoteExpansion(_) => write!(fmt, "<quote expansion>"),
|
||||
CfgSpec(_) => write!(fmt, "<cfgspec>"),
|
||||
MacroExpansion(_) => write!(fmt, "<macro expansion>"),
|
||||
Anon(_) => write!(fmt, "<anon>"),
|
||||
ProcMacroSourceCode(_) => write!(fmt, "<proc-macro source code>"),
|
||||
|
@ -384,7 +384,7 @@ impl FileName {
|
|||
| ProcMacroSourceCode(_)
|
||||
| CliCrateAttr(_)
|
||||
| Custom(_)
|
||||
| QuoteExpansion(_)
|
||||
| CfgSpec(_)
|
||||
| DocTest(_, _)
|
||||
| InlineAsm(_) => false,
|
||||
}
|
||||
|
@ -425,7 +425,7 @@ impl FileName {
|
|||
pub fn cfg_spec_source_code(src: &str) -> FileName {
|
||||
let mut hasher = StableHasher::new();
|
||||
src.hash(&mut hasher);
|
||||
FileName::QuoteExpansion(hasher.finish())
|
||||
FileName::CfgSpec(hasher.finish())
|
||||
}
|
||||
|
||||
pub fn cli_crate_attr_source_code(src: &str) -> FileName {
|
||||
|
|
|
@ -420,8 +420,8 @@ fn make_elided_region_spans_suggs<'a>(
|
|||
|
||||
let mut process_consecutive_brackets =
|
||||
|span: Option<Span>, spans_suggs: &mut Vec<(Span, String)>| {
|
||||
if span
|
||||
.is_some_and(|span| bracket_span.map_or(true, |bracket_span| span == bracket_span))
|
||||
if let Some(span) = span
|
||||
&& bracket_span.is_none_or(|bracket_span| span == bracket_span)
|
||||
{
|
||||
consecutive_brackets += 1;
|
||||
} else if let Some(bracket_span) = bracket_span.take() {
|
||||
|
|
|
@ -8,6 +8,8 @@ compiler-docs = true
|
|||
# where adding `debug!()` appears to do nothing.
|
||||
# However, it makes running the compiler slightly slower.
|
||||
debug-logging = true
|
||||
# Enables debug assertions, which guard from many mistakes when working on the compiler.
|
||||
debug-assertions = true
|
||||
# Get actually-useful information from backtraces, profiling, etc. with minimal added bytes
|
||||
debuginfo-level = "line-tables-only"
|
||||
# This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower.
|
||||
|
|
|
@ -2875,21 +2875,26 @@ impl Config {
|
|||
allowed_paths.push(":!library");
|
||||
}
|
||||
|
||||
// Look for a version to compare to based on the current commit.
|
||||
// Only commits merged by bors will have CI artifacts.
|
||||
let commit = match self.last_modified_commit(&allowed_paths, "download-rustc", if_unchanged)
|
||||
{
|
||||
Some(commit) => commit,
|
||||
None => {
|
||||
if if_unchanged {
|
||||
return None;
|
||||
let commit = if self.rust_info.is_managed_git_subrepository() {
|
||||
// Look for a version to compare to based on the current commit.
|
||||
// Only commits merged by bors will have CI artifacts.
|
||||
match self.last_modified_commit(&allowed_paths, "download-rustc", if_unchanged) {
|
||||
Some(commit) => commit,
|
||||
None => {
|
||||
if if_unchanged {
|
||||
return None;
|
||||
}
|
||||
println!("ERROR: could not find commit hash for downloading rustc");
|
||||
println!("HELP: maybe your repository history is too shallow?");
|
||||
println!("HELP: consider setting `rust.download-rustc=false` in config.toml");
|
||||
println!("HELP: or fetch enough history to include one upstream commit");
|
||||
crate::exit!(1);
|
||||
}
|
||||
println!("ERROR: could not find commit hash for downloading rustc");
|
||||
println!("HELP: maybe your repository history is too shallow?");
|
||||
println!("HELP: consider setting `rust.download-rustc=false` in config.toml");
|
||||
println!("HELP: or fetch enough history to include one upstream commit");
|
||||
crate::exit!(1);
|
||||
}
|
||||
} else {
|
||||
channel::read_commit_info_file(&self.src)
|
||||
.map(|info| info.sha.trim().to_owned())
|
||||
.expect("git-commit-info is missing in the project root")
|
||||
};
|
||||
|
||||
if CiEnv::is_ci() && {
|
||||
|
@ -2971,6 +2976,11 @@ impl Config {
|
|||
option_name: &str,
|
||||
if_unchanged: bool,
|
||||
) -> Option<String> {
|
||||
assert!(
|
||||
self.rust_info.is_managed_git_subrepository(),
|
||||
"Can't run `Config::last_modified_commit` on a non-git source."
|
||||
);
|
||||
|
||||
// Look for a version to compare to based on the current commit.
|
||||
// Only commits merged by bors will have CI artifacts.
|
||||
let commit = get_closest_merge_commit(Some(&self.src), &self.git_config(), &[]).unwrap();
|
||||
|
|
|
@ -335,4 +335,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
|
|||
severity: ChangeSeverity::Warning,
|
||||
summary: "Some stamp names in the build artifacts may have changed slightly (e.g., from `llvm-finished-building` to `.llvm-stamp`).",
|
||||
},
|
||||
ChangeInfo {
|
||||
change_id: 135729,
|
||||
severity: ChangeSeverity::Info,
|
||||
summary: "Change the compiler profile to default to rust.debug-assertions = true",
|
||||
},
|
||||
];
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
//@ compile-flags:--test
|
||||
//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
|
||||
//@ check-pass
|
||||
#![allow(rustdoc::invalid_codeblock_attributes)]
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
|
||||
|
||||
|
|
|
@ -739,8 +739,11 @@ LL | _)
|
|||
error[E0451]: field `i` of struct `this_crate::nested::DeprecatedStruct` is private
|
||||
--> $DIR/deprecation-lint.rs:280:13
|
||||
|
|
||||
LL | let _ = nested::DeprecatedStruct {
|
||||
| ------------------------ in this type
|
||||
LL |
|
||||
LL | i: 0
|
||||
| ^^^^ private field
|
||||
| ^ private field
|
||||
|
||||
error: aborting due to 123 previous errors
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ error[E0451]: field `b` of struct `Foo` is private
|
|||
--> $DIR/E0451.rs:18:29
|
||||
|
|
||||
LL | let f = bar::Foo{ a: 0, b: 0 };
|
||||
| ^^^^ private field
|
||||
| ^ private field
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ error[E0451]: field `1` of struct `Box` is private
|
|||
--> $DIR/issue-82772-match-box-as-struct.rs:4:15
|
||||
|
|
||||
LL | let Box { 1: _, .. }: Box<()>;
|
||||
| ^^^^ private field
|
||||
| ^ private field
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ error[E0451]: field `x` of struct `Foo` is private
|
|||
--> $DIR/private-struct-field-ctor.rs:8:22
|
||||
|
|
||||
LL | let s = a::Foo { x: 1 };
|
||||
| ^^^^ private field
|
||||
| ^ private field
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ error[E0451]: field `x` of struct `Foo` is private
|
|||
--> $DIR/private-struct-field-pattern.rs:15:15
|
||||
|
|
||||
LL | Foo { x: _ } => {}
|
||||
| ^^^^ private field
|
||||
| ^ private field
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ error[E0451]: field `x` of struct `S` is private
|
|||
--> $DIR/struct-literal-field.rs:18:9
|
||||
|
|
||||
LL | S { x: 0 };
|
||||
| ^^^^ private field
|
||||
| ^ private field
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ error[E0451]: field `c` of union `U` is private
|
|||
--> $DIR/union-field-privacy-1.rs:12:20
|
||||
|
|
||||
LL | let u = m::U { c: 0 };
|
||||
| ^^^^ private field
|
||||
| ^ private field
|
||||
|
||||
error[E0451]: field `c` of union `U` is private
|
||||
--> $DIR/union-field-privacy-1.rs:16:16
|
||||
|
|
42
tests/ui/structs/default-field-values/visibility.rs
Normal file
42
tests/ui/structs/default-field-values/visibility.rs
Normal file
|
@ -0,0 +1,42 @@
|
|||
#![feature(default_field_values)]
|
||||
pub mod foo {
|
||||
#[derive(Default)]
|
||||
pub struct Alpha {
|
||||
beta: u8 = 42,
|
||||
gamma: bool = true,
|
||||
}
|
||||
}
|
||||
|
||||
mod bar {
|
||||
use crate::foo::Alpha;
|
||||
fn baz() {
|
||||
let _x = Alpha { .. };
|
||||
//~^ ERROR fields `beta` and `gamma` of struct `Alpha` are private
|
||||
let _x = Alpha {
|
||||
beta: 0, //~ ERROR fields `beta` and `gamma` of struct `Alpha` are private
|
||||
gamma: false,
|
||||
};
|
||||
let _x = Alpha {
|
||||
beta: 0, //~ ERROR fields `beta` and `gamma` of struct `Alpha` are private
|
||||
..
|
||||
};
|
||||
let _x = Alpha { beta: 0, .. };
|
||||
//~^ ERROR fields `beta` and `gamma` of struct `Alpha` are private
|
||||
let _x = Alpha { beta: 0, ..Default::default() };
|
||||
//~^ ERROR fields `beta` and `gamma` of struct `Alpha` are private
|
||||
}
|
||||
}
|
||||
|
||||
pub mod baz {
|
||||
pub struct S {
|
||||
x: i32 = 1,
|
||||
}
|
||||
}
|
||||
fn main() {
|
||||
let _a = baz::S {
|
||||
.. //~ ERROR field `x` of struct `S` is private
|
||||
};
|
||||
let _b = baz::S {
|
||||
x: 0, //~ ERROR field `x` of struct `S` is private
|
||||
};
|
||||
}
|
61
tests/ui/structs/default-field-values/visibility.stderr
Normal file
61
tests/ui/structs/default-field-values/visibility.stderr
Normal file
|
@ -0,0 +1,61 @@
|
|||
error[E0451]: field `x` of struct `S` is private
|
||||
--> $DIR/visibility.rs:37:9
|
||||
|
|
||||
LL | let _a = baz::S {
|
||||
| ------ in this type
|
||||
LL | ..
|
||||
| ^^ field `x` is private
|
||||
|
||||
error[E0451]: field `x` of struct `S` is private
|
||||
--> $DIR/visibility.rs:40:9
|
||||
|
|
||||
LL | let _b = baz::S {
|
||||
| ------ in this type
|
||||
LL | x: 0,
|
||||
| ^ private field
|
||||
|
||||
error[E0451]: fields `beta` and `gamma` of struct `Alpha` are private
|
||||
--> $DIR/visibility.rs:13:26
|
||||
|
|
||||
LL | let _x = Alpha { .. };
|
||||
| ^^ fields `beta` and `gamma` are private
|
||||
|
||||
error[E0451]: fields `beta` and `gamma` of struct `Alpha` are private
|
||||
--> $DIR/visibility.rs:16:13
|
||||
|
|
||||
LL | let _x = Alpha {
|
||||
| ----- in this type
|
||||
LL | beta: 0,
|
||||
| ^^^^ private field
|
||||
LL | gamma: false,
|
||||
| ^^^^^ private field
|
||||
|
||||
error[E0451]: fields `beta` and `gamma` of struct `Alpha` are private
|
||||
--> $DIR/visibility.rs:20:13
|
||||
|
|
||||
LL | let _x = Alpha {
|
||||
| ----- in this type
|
||||
LL | beta: 0,
|
||||
| ^^^^^^^ private field
|
||||
LL | ..
|
||||
| ^^ field `gamma` is private
|
||||
|
||||
error[E0451]: fields `beta` and `gamma` of struct `Alpha` are private
|
||||
--> $DIR/visibility.rs:23:26
|
||||
|
|
||||
LL | let _x = Alpha { beta: 0, .. };
|
||||
| ^^^^^^^ ^^ field `gamma` is private
|
||||
| |
|
||||
| private field
|
||||
|
||||
error[E0451]: fields `beta` and `gamma` of struct `Alpha` are private
|
||||
--> $DIR/visibility.rs:25:26
|
||||
|
|
||||
LL | let _x = Alpha { beta: 0, ..Default::default() };
|
||||
| ^^^^^^^ ^^^^^^^^^^^^^^^^^^ field `gamma` is private
|
||||
| |
|
||||
| private field
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0451`.
|
|
@ -2,19 +2,19 @@ error[E0451]: field `0` of struct `Box` is private
|
|||
--> $DIR/issue-82772.rs:5:15
|
||||
|
|
||||
LL | let Box { 0: _, .. }: Box<()>;
|
||||
| ^^^^ private field
|
||||
| ^ private field
|
||||
|
||||
error[E0451]: field `1` of struct `Box` is private
|
||||
--> $DIR/issue-82772.rs:6:15
|
||||
|
|
||||
LL | let Box { 1: _, .. }: Box<()>;
|
||||
| ^^^^ private field
|
||||
| ^ private field
|
||||
|
||||
error[E0451]: field `1` of struct `ModPrivateStruct` is private
|
||||
--> $DIR/issue-82772.rs:7:28
|
||||
|
|
||||
LL | let ModPrivateStruct { 1: _, .. } = ModPrivateStruct::default();
|
||||
| ^^^^ private field
|
||||
| ^ private field
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue