Skip to content

Commit 6d9f6ae

Browse files
committed
Auto merge of rust-lang#134395 - matthiaskrgr:rollup-4j2gx1x, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - rust-lang#134124 (CI: use free runners for x86_64-gnu-llvm jobs) - rust-lang#134197 (rustc_mir_build: Clarify that 'mirrored' does not mean 'flipped' or 'reversed') - rust-lang#134260 (Correctly handle comments in attributes in doctests source code) - rust-lang#134277 (rustdoc-search: handle `impl Into<X>` better) - rust-lang#134284 (Keep track of patterns that could have introduced a binding, but didn't) - rust-lang#134337 (reject unsound toggling of RISCV target features) - rust-lang#134371 (Check for array lengths that aren't actually `usize`) - rust-lang#134385 (tests/ui/asm: Remove uses of rustc_attrs, lang_items, and decl_macro features by using minicore) - rust-lang#134386 (Some trait method vs impl method signature difference diagnostic cleanups) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 83ab648 + 9a0dab2 commit 6d9f6ae

File tree

81 files changed

+1223
-760
lines changed

Some content is hidden

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

81 files changed

+1223
-760
lines changed

Diff for: compiler/rustc_ast/src/ast.rs

+2
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,8 @@ pub enum PatKind {
859859
pub enum PatFieldsRest {
860860
/// `module::StructName { field, ..}`
861861
Rest,
862+
/// `module::StructName { field, syntax error }`
863+
Recovered(ErrorGuaranteed),
862864
/// `module::StructName { field }`
863865
None,
864866
}

Diff for: compiler/rustc_ast_lowering/src/pat.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
9292
span: self.lower_span(f.span),
9393
}
9494
}));
95-
break hir::PatKind::Struct(qpath, fs, *etc == ast::PatFieldsRest::Rest);
95+
break hir::PatKind::Struct(
96+
qpath,
97+
fs,
98+
matches!(
99+
etc,
100+
ast::PatFieldsRest::Rest | ast::PatFieldsRest::Recovered(_)
101+
),
102+
);
96103
}
97104
PatKind::Tuple(pats) => {
98105
let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple");

Diff for: compiler/rustc_ast_pretty/src/pprust/state.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1654,11 +1654,14 @@ impl<'a> State<'a> {
16541654
},
16551655
|f| f.pat.span,
16561656
);
1657-
if *etc == ast::PatFieldsRest::Rest {
1657+
if let ast::PatFieldsRest::Rest | ast::PatFieldsRest::Recovered(_) = etc {
16581658
if !fields.is_empty() {
16591659
self.word_space(",");
16601660
}
16611661
self.word("..");
1662+
if let ast::PatFieldsRest::Recovered(_) = etc {
1663+
self.word("/* recovered parse error */");
1664+
}
16621665
}
16631666
if !empty {
16641667
self.space();

Diff for: compiler/rustc_borrowck/src/diagnostics/region_name.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -459,11 +459,8 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
459459
) -> RegionNameHighlight {
460460
let mut highlight = RegionHighlightMode::default();
461461
highlight.highlighting_region_vid(self.infcx.tcx, needle_fr, counter);
462-
let type_name = self
463-
.infcx
464-
.err_ctxt()
465-
.extract_inference_diagnostics_data(ty.into(), Some(highlight))
466-
.name;
462+
let type_name =
463+
self.infcx.err_ctxt().extract_inference_diagnostics_data(ty.into(), highlight).name;
467464

468465
debug!(
469466
"highlight_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}",
@@ -874,7 +871,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
874871
let type_name = self
875872
.infcx
876873
.err_ctxt()
877-
.extract_inference_diagnostics_data(yield_ty.into(), Some(highlight))
874+
.extract_inference_diagnostics_data(yield_ty.into(), highlight)
878875
.name;
879876

880877
let yield_span = match tcx.hir_node(self.mir_hir_id()) {

Diff for: compiler/rustc_mir_build/src/build/expr/as_place.rs

+25-7
Original file line numberDiff line numberDiff line change
@@ -647,13 +647,31 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
647647

648648
match place_ty.kind() {
649649
ty::Array(_elem_ty, len_const) => {
650-
// We know how long an array is, so just use that as a constant
651-
// directly -- no locals needed. We do need one statement so
652-
// that borrow- and initialization-checking consider it used,
653-
// though. FIXME: Do we really *need* to count this as a use?
654-
// Could partial array tracking work off something else instead?
655-
self.cfg.push_fake_read(block, source_info, FakeReadCause::ForIndex, place);
656-
let const_ = Const::from_ty_const(*len_const, usize_ty, self.tcx);
650+
let ty_const = if let Some((_, len_ty)) = len_const.try_to_valtree()
651+
&& len_ty != self.tcx.types.usize
652+
{
653+
// Bad const generics can give us a constant from the type that's
654+
// not actually a `usize`, so in that case give an error instead.
655+
// FIXME: It'd be nice if the type checker made sure this wasn't
656+
// possible, instead.
657+
let err = self.tcx.dcx().span_delayed_bug(
658+
span,
659+
format!(
660+
"Array length should have already been a type error, as it's {len_ty:?}"
661+
),
662+
);
663+
ty::Const::new_error(self.tcx, err)
664+
} else {
665+
// We know how long an array is, so just use that as a constant
666+
// directly -- no locals needed. We do need one statement so
667+
// that borrow- and initialization-checking consider it used,
668+
// though. FIXME: Do we really *need* to count this as a use?
669+
// Could partial array tracking work off something else instead?
670+
self.cfg.push_fake_read(block, source_info, FakeReadCause::ForIndex, place);
671+
*len_const
672+
};
673+
674+
let const_ = Const::from_ty_const(ty_const, usize_ty, self.tcx);
657675
Operand::Constant(Box::new(ConstOperand { span, user_ty: None, const_ }))
658676
}
659677
ty::Slice(_elem_ty) => {

Diff for: compiler/rustc_mir_build/src/thir/cx/expr.rs

+8
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ use crate::thir::cx::Cx;
2525
use crate::thir::util::UserAnnotatedTyHelpers;
2626

2727
impl<'tcx> Cx<'tcx> {
28+
/// Create a THIR expression for the given HIR expression. This expands all
29+
/// adjustments and directly adds the type information from the
30+
/// `typeck_results`. See the [dev-guide] for more details.
31+
///
32+
/// (The term "mirror" in this case does not refer to "flipped" or
33+
/// "reversed".)
34+
///
35+
/// [dev-guide]: https://rustc-dev-guide.rust-lang.org/thir.html
2836
pub(crate) fn mirror_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> ExprId {
2937
// `mirror_expr` is recursing very deep. Make sure the stack doesn't overflow.
3038
ensure_sufficient_stack(|| self.mirror_expr_inner(expr))

Diff for: compiler/rustc_parse/src/parser/pat.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1371,10 +1371,10 @@ impl<'a> Parser<'a> {
13711371
self.bump();
13721372
let (fields, etc) = self.parse_pat_fields().unwrap_or_else(|mut e| {
13731373
e.span_label(path.span, "while parsing the fields for this pattern");
1374-
e.emit();
1374+
let guar = e.emit();
13751375
self.recover_stmt();
13761376
// When recovering, pretend we had `Foo { .. }`, to avoid cascading errors.
1377-
(ThinVec::new(), PatFieldsRest::Rest)
1377+
(ThinVec::new(), PatFieldsRest::Recovered(guar))
13781378
});
13791379
self.bump();
13801380
Ok(PatKind::Struct(qself, path, fields, etc))

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

+36-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ use rustc_ast::visit::{
1919
use rustc_ast::*;
2020
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
2121
use rustc_errors::codes::*;
22-
use rustc_errors::{Applicability, DiagArgValue, IntoDiagArg, StashKey, Suggestions};
22+
use rustc_errors::{
23+
Applicability, DiagArgValue, ErrorGuaranteed, IntoDiagArg, StashKey, Suggestions,
24+
};
2325
use rustc_hir::def::Namespace::{self, *};
2426
use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS};
2527
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE, LocalDefId};
@@ -264,12 +266,17 @@ impl RibKind<'_> {
264266
#[derive(Debug)]
265267
pub(crate) struct Rib<'ra, R = Res> {
266268
pub bindings: IdentMap<R>,
269+
pub patterns_with_skipped_bindings: FxHashMap<DefId, Vec<(Span, Result<(), ErrorGuaranteed>)>>,
267270
pub kind: RibKind<'ra>,
268271
}
269272

270273
impl<'ra, R> Rib<'ra, R> {
271274
fn new(kind: RibKind<'ra>) -> Rib<'ra, R> {
272-
Rib { bindings: Default::default(), kind }
275+
Rib {
276+
bindings: Default::default(),
277+
patterns_with_skipped_bindings: Default::default(),
278+
kind,
279+
}
273280
}
274281
}
275282

@@ -3775,6 +3782,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
37753782
/// When a whole or-pattern has been dealt with, the thing happens.
37763783
///
37773784
/// See the implementation and `fresh_binding` for more details.
3785+
#[tracing::instrument(skip(self, bindings), level = "debug")]
37783786
fn resolve_pattern_inner(
37793787
&mut self,
37803788
pat: &Pat,
@@ -3783,7 +3791,6 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
37833791
) {
37843792
// Visit all direct subpatterns of this pattern.
37853793
pat.walk(&mut |pat| {
3786-
debug!("resolve_pattern pat={:?} node={:?}", pat, pat.kind);
37873794
match pat.kind {
37883795
PatKind::Ident(bmode, ident, ref sub) => {
37893796
// First try to resolve the identifier as some existing entity,
@@ -3809,8 +3816,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
38093816
PatKind::Path(ref qself, ref path) => {
38103817
self.smart_resolve_path(pat.id, qself, path, PathSource::Pat);
38113818
}
3812-
PatKind::Struct(ref qself, ref path, ..) => {
3819+
PatKind::Struct(ref qself, ref path, ref _fields, ref rest) => {
38133820
self.smart_resolve_path(pat.id, qself, path, PathSource::Struct);
3821+
self.record_patterns_with_skipped_bindings(pat, rest);
38143822
}
38153823
PatKind::Or(ref ps) => {
38163824
// Add a new set of bindings to the stack. `Or` here records that when a
@@ -3843,6 +3851,30 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
38433851
});
38443852
}
38453853

3854+
fn record_patterns_with_skipped_bindings(&mut self, pat: &Pat, rest: &ast::PatFieldsRest) {
3855+
match rest {
3856+
ast::PatFieldsRest::Rest | ast::PatFieldsRest::Recovered(_) => {
3857+
// Record that the pattern doesn't introduce all the bindings it could.
3858+
if let Some(partial_res) = self.r.partial_res_map.get(&pat.id)
3859+
&& let Some(res) = partial_res.full_res()
3860+
&& let Some(def_id) = res.opt_def_id()
3861+
{
3862+
self.ribs[ValueNS]
3863+
.last_mut()
3864+
.unwrap()
3865+
.patterns_with_skipped_bindings
3866+
.entry(def_id)
3867+
.or_default()
3868+
.push((pat.span, match rest {
3869+
ast::PatFieldsRest::Recovered(guar) => Err(*guar),
3870+
_ => Ok(()),
3871+
}));
3872+
}
3873+
}
3874+
ast::PatFieldsRest::None => {}
3875+
}
3876+
}
3877+
38463878
fn fresh_binding(
38473879
&mut self,
38483880
ident: Ident,

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

+43
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
430430
let mut err = self.r.dcx().struct_span_err(base_error.span, base_error.msg.clone());
431431
err.code(code);
432432

433+
self.detect_missing_binding_available_from_pattern(&mut err, path, following_seg);
433434
self.suggest_at_operator_in_slice_pat_with_range(&mut err, path);
434435
self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span);
435436

@@ -1120,6 +1121,48 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
11201121
true
11211122
}
11221123

1124+
fn detect_missing_binding_available_from_pattern(
1125+
&mut self,
1126+
err: &mut Diag<'_>,
1127+
path: &[Segment],
1128+
following_seg: Option<&Segment>,
1129+
) {
1130+
let [segment] = path else { return };
1131+
let None = following_seg else { return };
1132+
for rib in self.ribs[ValueNS].iter().rev() {
1133+
for (def_id, spans) in &rib.patterns_with_skipped_bindings {
1134+
if let Some(fields) = self.r.field_idents(*def_id) {
1135+
for field in fields {
1136+
if field.name == segment.ident.name {
1137+
if spans.iter().all(|(_, had_error)| had_error.is_err()) {
1138+
// This resolution error will likely be fixed by fixing a
1139+
// syntax error in a pattern, so it is irrelevant to the user.
1140+
let multispan: MultiSpan =
1141+
spans.iter().map(|(s, _)| *s).collect::<Vec<_>>().into();
1142+
err.span_note(
1143+
multispan,
1144+
"this pattern had a recovered parse error which likely lost \
1145+
the expected fields",
1146+
);
1147+
err.downgrade_to_delayed_bug();
1148+
}
1149+
let ty = self.r.tcx.item_name(*def_id);
1150+
for (span, _) in spans {
1151+
err.span_label(
1152+
*span,
1153+
format!(
1154+
"this pattern doesn't include `{field}`, which is \
1155+
available in `{ty}`",
1156+
),
1157+
);
1158+
}
1159+
}
1160+
}
1161+
}
1162+
}
1163+
}
1164+
}
1165+
11231166
fn suggest_at_operator_in_slice_pat_with_range(
11241167
&mut self,
11251168
err: &mut Diag<'_>,

Diff for: compiler/rustc_target/src/spec/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3166,7 +3166,7 @@ impl Target {
31663166
// Note that the `lp64e` is still unstable as it's not (yet) part of the ELF psABI.
31673167
check_matches!(
31683168
&*self.llvm_abiname,
3169-
"lp64" | "lp64f" | "lp64d" | "lp64q" | "lp64e",
3169+
"lp64" | "lp64f" | "lp64d" | "lp64e",
31703170
"invalid RISC-V ABI name"
31713171
);
31723172
}

Diff for: compiler/rustc_target/src/target_features.rs

+71-4
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub enum Stability<Toggleability> {
3939
allow_toggle: Toggleability,
4040
},
4141
/// This feature can not be set via `-Ctarget-feature` or `#[target_feature]`, it can only be
42-
/// set in the basic target definition. It is never set in `cfg(target_feature)`. Used in
42+
/// set in the target spec. It is never set in `cfg(target_feature)`. Used in
4343
/// particular for features that change the floating-point ABI.
4444
Forbidden { reason: &'static str },
4545
}
@@ -590,9 +590,76 @@ const RISCV_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
590590
// tidy-alphabetical-start
591591
("a", STABLE, &["zaamo", "zalrsc"]),
592592
("c", STABLE, &[]),
593-
("d", unstable(sym::riscv_target_feature), &["f"]),
594-
("e", unstable(sym::riscv_target_feature), &[]),
595-
("f", unstable(sym::riscv_target_feature), &[]),
593+
(
594+
"d",
595+
Stability::Unstable {
596+
nightly_feature: sym::riscv_target_feature,
597+
allow_toggle: |target, enable| match &*target.llvm_abiname {
598+
"ilp32d" | "lp64d" if !enable => {
599+
// The ABI requires the `d` feature, so it cannot be disabled.
600+
Err("feature is required by ABI")
601+
}
602+
"ilp32e" if enable => {
603+
// ilp32e is incompatible with features that need aligned load/stores > 32 bits,
604+
// like `d`.
605+
Err("feature is incompatible with ABI")
606+
}
607+
_ => Ok(()),
608+
},
609+
},
610+
&["f"],
611+
),
612+
(
613+
"e",
614+
Stability::Unstable {
615+
// Given that this is a negative feature, consider this before stabilizing:
616+
// does it really make sense to enable this feature in an individual
617+
// function with `#[target_feature]`?
618+
nightly_feature: sym::riscv_target_feature,
619+
allow_toggle: |target, enable| {
620+
match &*target.llvm_abiname {
621+
_ if !enable => {
622+
// Disabling this feature means we can use more registers (x16-x31).
623+
// The "e" ABIs treat them as caller-save, so it is safe to use them only
624+
// in some parts of a program while the rest doesn't know they even exist.
625+
// On other ABIs, the feature is already disabled anyway.
626+
Ok(())
627+
}
628+
"ilp32e" | "lp64e" => {
629+
// Embedded ABIs should already have the feature anyway, it's fine to enable
630+
// it again from an ABI perspective.
631+
Ok(())
632+
}
633+
_ => {
634+
// *Not* an embedded ABI. Enabling `e` is invalid.
635+
Err("feature is incompatible with ABI")
636+
}
637+
}
638+
},
639+
},
640+
&[],
641+
),
642+
(
643+
"f",
644+
Stability::Unstable {
645+
nightly_feature: sym::riscv_target_feature,
646+
allow_toggle: |target, enable| {
647+
match &*target.llvm_abiname {
648+
"ilp32f" | "ilp32d" | "lp64f" | "lp64d" if !enable => {
649+
// The ABI requires the `f` feature, so it cannot be disabled.
650+
Err("feature is required by ABI")
651+
}
652+
_ => Ok(()),
653+
}
654+
},
655+
},
656+
&[],
657+
),
658+
(
659+
"forced-atomics",
660+
Stability::Forbidden { reason: "unsound because it changes the ABI of atomic operations" },
661+
&[],
662+
),
596663
("m", STABLE, &[]),
597664
("relax", unstable(sym::riscv_target_feature), &[]),
598665
("unaligned-scalar-mem", unstable(sym::riscv_target_feature), &[]),

0 commit comments

Comments
 (0)