Skip to content

Commit e3051d8

Browse files
committed
Auto merge of #78028 - JohnTitor:rollup-jt3hikb, r=JohnTitor
Rollup of 10 pull requests Successful merges: - #75209 (Suggest imports of unresolved macros) - #77547 (stabilize union with 'ManuallyDrop' fields and 'impl Drop for Union') - #77827 (Don't link to nightly primitives on stable channel) - #77855 (resolve: further improvements to "try using the enum's variant" diagnostic) - #77900 (Use fdatasync for File::sync_data on more OSes) - #77925 (Suggest minimal subset features in `incomplete_features` lint) - #77971 (Deny broken intra-doc links in linkchecker) - #77991 (Bump backtrace-rs) - #77992 (instrument-coverage: try our best to not ICE) - #78013 (Fix sidebar scroll on mobile devices) Failed merges: r? `@ghost`
2 parents 5a51185 + 001fcd9 commit e3051d8

File tree

154 files changed

+667
-275
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

154 files changed

+667
-275
lines changed

Diff for: Cargo.lock

+4
Original file line numberDiff line numberDiff line change
@@ -1744,6 +1744,10 @@ dependencies = [
17441744
[[package]]
17451745
name = "linkchecker"
17461746
version = "0.1.0"
1747+
dependencies = [
1748+
"once_cell",
1749+
"regex",
1750+
]
17471751

17481752
[[package]]
17491753
name = "linked-hash-map"

Diff for: compiler/rustc_error_codes/src/error_codes/E0660.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ llvm_asm!("nop" "nop");
99
Considering that this would be a long explanation, we instead recommend you
1010
take a look at the [`llvm_asm`] chapter of the Unstable book:
1111

12-
[llvm_asm]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html
12+
[`llvm_asm`]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html

Diff for: compiler/rustc_error_codes/src/error_codes/E0661.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ llvm_asm!("nop" : "r"(a));
1010
Considering that this would be a long explanation, we instead recommend you
1111
take a look at the [`llvm_asm`] chapter of the Unstable book:
1212

13-
[llvm_asm]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html
13+
[`llvm_asm`]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html

Diff for: compiler/rustc_error_codes/src/error_codes/E0662.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ llvm_asm!("xor %eax, %eax"
1313
Considering that this would be a long explanation, we instead recommend you
1414
take a look at the [`llvm_asm`] chapter of the Unstable book:
1515

16-
[llvm_asm]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html
16+
[`llvm_asm`]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html

Diff for: compiler/rustc_error_codes/src/error_codes/E0663.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ llvm_asm!("xor %eax, %eax"
1313
Considering that this would be a long explanation, we instead recommend you
1414
take a look at the [`llvm_asm`] chapter of the Unstable book:
1515

16-
[llvm_asm]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html
16+
[`llvm_asm`]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html

Diff for: compiler/rustc_error_codes/src/error_codes/E0664.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ llvm_asm!("mov $$0x200, %eax"
1313
Considering that this would be a long explanation, we instead recommend you
1414
take a look at the [`llvm_asm`] chapter of the Unstable book:
1515

16-
[llvm_asm]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html
16+
[`llvm_asm`]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html

Diff for: compiler/rustc_lint/src/builtin.rs

+8
Original file line numberDiff line numberDiff line change
@@ -2288,12 +2288,20 @@ impl EarlyLintPass for IncompleteFeatures {
22882288
n, n,
22892289
));
22902290
}
2291+
if HAS_MIN_FEATURES.contains(&name) {
2292+
builder.help(&format!(
2293+
"consider using `min_{}` instead, which is more stable and complete",
2294+
name,
2295+
));
2296+
}
22912297
builder.emit();
22922298
})
22932299
});
22942300
}
22952301
}
22962302

2303+
const HAS_MIN_FEATURES: &[Symbol] = &[sym::const_generics, sym::specialization];
2304+
22972305
declare_lint! {
22982306
/// The `invalid_value` lint detects creating a value that is not valid,
22992307
/// such as a NULL reference.

Diff for: compiler/rustc_mir/src/transform/instrument_coverage.rs

+2-10
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ use rustc_middle::ty::query::Providers;
2222
use rustc_middle::ty::TyCtxt;
2323
use rustc_span::def_id::DefId;
2424
use rustc_span::source_map::original_sp;
25-
use rustc_span::{
26-
BytePos, CharPos, FileName, Pos, RealFileName, SourceFile, Span, Symbol, SyntaxContext,
27-
};
25+
use rustc_span::{BytePos, CharPos, Pos, SourceFile, Span, Symbol, SyntaxContext};
2826

2927
use std::cmp::Ordering;
3028

@@ -549,13 +547,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
549547
let mir_body = &self.mir_body;
550548
let body_span = self.body_span();
551549
let source_file = source_map.lookup_source_file(body_span.lo());
552-
let file_name = match &source_file.name {
553-
FileName::Real(RealFileName::Named(path)) => Symbol::intern(&path.to_string_lossy()),
554-
_ => bug!(
555-
"source_file.name should be a RealFileName, but it was: {:?}",
556-
source_file.name
557-
),
558-
};
550+
let file_name = Symbol::intern(&source_file.name.to_string());
559551

560552
debug!("instrumenting {:?}, span: {}", def_id, source_map.span_to_string(body_span));
561553

Diff for: compiler/rustc_passes/src/stability.rs

+29-23
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,13 @@ use rustc_hir::{Generics, HirId, Item, StructField, TraitRef, Ty, TyKind, Varian
1313
use rustc_middle::hir::map::Map;
1414
use rustc_middle::middle::privacy::AccessLevels;
1515
use rustc_middle::middle::stability::{DeprecationEntry, Index};
16-
use rustc_middle::ty::query::Providers;
17-
use rustc_middle::ty::TyCtxt;
16+
use rustc_middle::ty::{self, query::Providers, TyCtxt};
1817
use rustc_session::lint;
1918
use rustc_session::lint::builtin::INEFFECTIVE_UNSTABLE_TRAIT_IMPL;
2019
use rustc_session::parse::feature_err;
2120
use rustc_session::Session;
2221
use rustc_span::symbol::{sym, Symbol};
23-
use rustc_span::Span;
24-
use rustc_trait_selection::traits::misc::can_type_implement_copy;
22+
use rustc_span::{Span, DUMMY_SP};
2523

2624
use std::cmp::Ordering;
2725
use std::mem::replace;
@@ -711,27 +709,35 @@ impl Visitor<'tcx> for Checker<'tcx> {
711709
// so semi-randomly perform it here in stability.rs
712710
hir::ItemKind::Union(..) if !self.tcx.features().untagged_unions => {
713711
let def_id = self.tcx.hir().local_def_id(item.hir_id);
714-
let adt_def = self.tcx.adt_def(def_id);
715712
let ty = self.tcx.type_of(def_id);
713+
let (adt_def, substs) = match ty.kind() {
714+
ty::Adt(adt_def, substs) => (adt_def, substs),
715+
_ => bug!(),
716+
};
716717

717-
if adt_def.has_dtor(self.tcx) {
718-
feature_err(
719-
&self.tcx.sess.parse_sess,
720-
sym::untagged_unions,
721-
item.span,
722-
"unions with `Drop` implementations are unstable",
723-
)
724-
.emit();
725-
} else {
726-
let param_env = self.tcx.param_env(def_id);
727-
if can_type_implement_copy(self.tcx, param_env, ty).is_err() {
728-
feature_err(
729-
&self.tcx.sess.parse_sess,
730-
sym::untagged_unions,
731-
item.span,
732-
"unions with non-`Copy` fields are unstable",
733-
)
734-
.emit();
718+
// Non-`Copy` fields are unstable, except for `ManuallyDrop`.
719+
let param_env = self.tcx.param_env(def_id);
720+
for field in &adt_def.non_enum_variant().fields {
721+
let field_ty = field.ty(self.tcx, substs);
722+
if !field_ty.ty_adt_def().map_or(false, |adt_def| adt_def.is_manually_drop())
723+
&& !field_ty.is_copy_modulo_regions(self.tcx.at(DUMMY_SP), param_env)
724+
{
725+
if field_ty.needs_drop(self.tcx, param_env) {
726+
// Avoid duplicate error: This will error later anyway because fields
727+
// that need drop are not allowed.
728+
self.tcx.sess.delay_span_bug(
729+
item.span,
730+
"union should have been rejected due to potentially dropping field",
731+
);
732+
} else {
733+
feature_err(
734+
&self.tcx.sess.parse_sess,
735+
sym::untagged_unions,
736+
self.tcx.def_span(field.did),
737+
"unions with non-`Copy` fields other than `ManuallyDrop<T>` are unstable",
738+
)
739+
.emit();
740+
}
735741
}
736742
}
737743
}

Diff for: compiler/rustc_resolve/src/diagnostics.rs

+11
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,17 @@ impl<'a> Resolver<'a> {
922922
);
923923
self.add_typo_suggestion(err, suggestion, ident.span);
924924

925+
let import_suggestions = self.lookup_import_candidates(
926+
ident,
927+
Namespace::MacroNS,
928+
parent_scope,
929+
|res| match res {
930+
Res::Def(DefKind::Macro(MacroKind::Bang), _) => true,
931+
_ => false,
932+
},
933+
);
934+
show_candidates(err, None, &import_suggestions, false, true);
935+
925936
if macro_kind == MacroKind::Derive && (ident.name == sym::Send || ident.name == sym::Sync) {
926937
let msg = format!("unsafe traits like `{}` should be implemented explicitly", ident);
927938
err.span_note(ident.span, &msg);

Diff for: compiler/rustc_resolve/src/late/diagnostics.rs

+88-62
Original file line numberDiff line numberDiff line change
@@ -1330,58 +1330,17 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
13301330

13311331
let suggest_only_tuple_variants =
13321332
matches!(source, PathSource::TupleStruct(..)) || source.is_call();
1333-
let mut suggestable_variants = if suggest_only_tuple_variants {
1333+
if suggest_only_tuple_variants {
13341334
// Suggest only tuple variants regardless of whether they have fields and do not
13351335
// suggest path with added parenthesis.
1336-
variants
1336+
let mut suggestable_variants = variants
13371337
.iter()
13381338
.filter(|(.., kind)| *kind == CtorKind::Fn)
13391339
.map(|(variant, ..)| path_names_to_string(variant))
1340-
.collect::<Vec<_>>()
1341-
} else {
1342-
variants
1343-
.iter()
1344-
.filter(|(_, def_id, kind)| {
1345-
// Suggest only variants that have no fields (these can definitely
1346-
// be constructed).
1347-
let has_fields =
1348-
self.r.field_names.get(&def_id).map(|f| f.is_empty()).unwrap_or(false);
1349-
match kind {
1350-
CtorKind::Const => true,
1351-
CtorKind::Fn | CtorKind::Fictive if has_fields => true,
1352-
_ => false,
1353-
}
1354-
})
1355-
.map(|(variant, _, kind)| (path_names_to_string(variant), kind))
1356-
.map(|(variant_str, kind)| {
1357-
// Add constructor syntax where appropriate.
1358-
match kind {
1359-
CtorKind::Const => variant_str,
1360-
CtorKind::Fn => format!("({}())", variant_str),
1361-
CtorKind::Fictive => format!("({} {{}})", variant_str),
1362-
}
1363-
})
1364-
.collect::<Vec<_>>()
1365-
};
1366-
1367-
let non_suggestable_variant_count = variants.len() - suggestable_variants.len();
1340+
.collect::<Vec<_>>();
13681341

1369-
if !suggestable_variants.is_empty() {
1370-
let msg = if non_suggestable_variant_count == 0 && suggestable_variants.len() == 1 {
1371-
"try using the enum's variant"
1372-
} else {
1373-
"try using one of the enum's variants"
1374-
};
1342+
let non_suggestable_variant_count = variants.len() - suggestable_variants.len();
13751343

1376-
err.span_suggestions(
1377-
span,
1378-
msg,
1379-
suggestable_variants.drain(..),
1380-
Applicability::MaybeIncorrect,
1381-
);
1382-
}
1383-
1384-
if suggest_only_tuple_variants {
13851344
let source_msg = if source.is_call() {
13861345
"to construct"
13871346
} else if matches!(source, PathSource::TupleStruct(..)) {
@@ -1390,6 +1349,21 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
13901349
unreachable!()
13911350
};
13921351

1352+
if !suggestable_variants.is_empty() {
1353+
let msg = if non_suggestable_variant_count == 0 && suggestable_variants.len() == 1 {
1354+
format!("try {} the enum's variant", source_msg)
1355+
} else {
1356+
format!("try {} one of the enum's variants", source_msg)
1357+
};
1358+
1359+
err.span_suggestions(
1360+
span,
1361+
&msg,
1362+
suggestable_variants.drain(..),
1363+
Applicability::MaybeIncorrect,
1364+
);
1365+
}
1366+
13931367
// If the enum has no tuple variants..
13941368
if non_suggestable_variant_count == variants.len() {
13951369
err.help(&format!("the enum has no tuple variants {}", source_msg));
@@ -1408,24 +1382,76 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
14081382
));
14091383
}
14101384
} else {
1411-
let made_suggestion = non_suggestable_variant_count != variants.len();
1412-
if made_suggestion {
1413-
if non_suggestable_variant_count == 1 {
1414-
err.help(
1415-
"you might have meant to use the enum's other variant that has fields",
1416-
);
1417-
} else if non_suggestable_variant_count >= 1 {
1418-
err.help(
1419-
"you might have meant to use one of the enum's other variants that \
1420-
have fields",
1421-
);
1422-
}
1423-
} else {
1424-
if non_suggestable_variant_count == 1 {
1425-
err.help("you might have meant to use the enum's variant");
1426-
} else if non_suggestable_variant_count >= 1 {
1427-
err.help("you might have meant to use one of the enum's variants");
1385+
let needs_placeholder = |def_id: DefId, kind: CtorKind| {
1386+
let has_no_fields =
1387+
self.r.field_names.get(&def_id).map(|f| f.is_empty()).unwrap_or(false);
1388+
match kind {
1389+
CtorKind::Const => false,
1390+
CtorKind::Fn | CtorKind::Fictive if has_no_fields => false,
1391+
_ => true,
14281392
}
1393+
};
1394+
1395+
let mut suggestable_variants = variants
1396+
.iter()
1397+
.filter(|(_, def_id, kind)| !needs_placeholder(*def_id, *kind))
1398+
.map(|(variant, _, kind)| (path_names_to_string(variant), kind))
1399+
.map(|(variant, kind)| match kind {
1400+
CtorKind::Const => variant,
1401+
CtorKind::Fn => format!("({}())", variant),
1402+
CtorKind::Fictive => format!("({} {{}})", variant),
1403+
})
1404+
.collect::<Vec<_>>();
1405+
1406+
if !suggestable_variants.is_empty() {
1407+
let msg = if suggestable_variants.len() == 1 {
1408+
"you might have meant to use the following enum variant"
1409+
} else {
1410+
"you might have meant to use one of the following enum variants"
1411+
};
1412+
1413+
err.span_suggestions(
1414+
span,
1415+
msg,
1416+
suggestable_variants.drain(..),
1417+
Applicability::MaybeIncorrect,
1418+
);
1419+
}
1420+
1421+
let mut suggestable_variants_with_placeholders = variants
1422+
.iter()
1423+
.filter(|(_, def_id, kind)| needs_placeholder(*def_id, *kind))
1424+
.map(|(variant, _, kind)| (path_names_to_string(variant), kind))
1425+
.filter_map(|(variant, kind)| match kind {
1426+
CtorKind::Fn => Some(format!("({}(/* fields */))", variant)),
1427+
CtorKind::Fictive => Some(format!("({} {{ /* fields */ }})", variant)),
1428+
_ => None,
1429+
})
1430+
.collect::<Vec<_>>();
1431+
1432+
if !suggestable_variants_with_placeholders.is_empty() {
1433+
let msg = match (
1434+
suggestable_variants.is_empty(),
1435+
suggestable_variants_with_placeholders.len(),
1436+
) {
1437+
(true, 1) => "the following enum variant is available",
1438+
(true, _) => "the following enum variants are available",
1439+
(false, 1) => "alternatively, the following enum variant is available",
1440+
(false, _) => "alternatively, the following enum variants are also available",
1441+
};
1442+
1443+
err.span_suggestions(
1444+
span,
1445+
msg,
1446+
suggestable_variants_with_placeholders.drain(..),
1447+
Applicability::HasPlaceholders,
1448+
);
1449+
}
1450+
};
1451+
1452+
if def_id.is_local() {
1453+
if let Some(span) = self.def_span(def_id) {
1454+
err.span_note(span, "the enum is defined here");
14291455
}
14301456
}
14311457
}

Diff for: compiler/rustc_typeck/src/check/check.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,7 @@ pub(super) fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
348348
check_packed(tcx, span, def);
349349
}
350350

351-
/// When the `#![feature(untagged_unions)]` gate is active,
352-
/// check that the fields of the `union` does not contain fields that need dropping.
351+
/// Check that the fields of the `union` do not need dropping.
353352
pub(super) fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool {
354353
let item_type = tcx.type_of(item_def_id);
355354
if let ty::Adt(def, substs) = item_type.kind() {

0 commit comments

Comments
 (0)