Skip to content

Commit 051d0e8

Browse files
committed
Auto merge of #144488 - tgross35:rollup-vn0fpot, r=tgross35
Rollup of 9 pull requests Successful merges: - #144089 (Rehome 35 `tests/ui/issues/` tests to other subdirectories under `tests/ui/`) - #144171 (pattern_analysis: add option to get a full set of witnesses) - #144201 (Mention type that could be `Clone` but isn't in more cases) - #144316 (bootstrap: Move musl-root fallback out of sanity check) - #144339 (Enable dwarf-mixed-versions-lto.rs test on RISC-V (riscv64)) - #144341 (Enable const-vector.rs test on RISC-V (riscv64)) - #144352 (RustWrapper: Suppress getNextNonDebugInfoInstruction) - #144356 (Add `ignore-backends` annotations in failing GCC backend ui tests) - #144364 (Update `dlmalloc` dependency of libstd) r? `@ghost` `@rustbot` modify labels: rollup
2 parents f32b232 + a230b4f commit 051d0e8

File tree

171 files changed

+788
-125
lines changed

Some content is hidden

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

171 files changed

+788
-125
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,6 +1290,58 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
12901290
span,
12911291
format!("if `{ty}` implemented `Clone`, you could clone the value"),
12921292
);
1293+
} else if let ty::Adt(_, _) = ty.kind()
1294+
&& let Some(clone_trait) = self.infcx.tcx.lang_items().clone_trait()
1295+
{
1296+
// For cases like `Option<NonClone>`, where `Option<T>: Clone` if `T: Clone`, we point
1297+
// at the types that should be `Clone`.
1298+
let ocx = ObligationCtxt::new_with_diagnostics(self.infcx);
1299+
let cause = ObligationCause::misc(expr.span, self.mir_def_id());
1300+
ocx.register_bound(cause, self.infcx.param_env, ty, clone_trait);
1301+
let errors = ocx.select_all_or_error();
1302+
if errors.iter().all(|error| {
1303+
match error.obligation.predicate.as_clause().and_then(|c| c.as_trait_clause()) {
1304+
Some(clause) => match clause.self_ty().skip_binder().kind() {
1305+
ty::Adt(def, _) => def.did().is_local() && clause.def_id() == clone_trait,
1306+
_ => false,
1307+
},
1308+
None => false,
1309+
}
1310+
}) {
1311+
let mut type_spans = vec![];
1312+
let mut types = FxIndexSet::default();
1313+
for clause in errors
1314+
.iter()
1315+
.filter_map(|e| e.obligation.predicate.as_clause())
1316+
.filter_map(|c| c.as_trait_clause())
1317+
{
1318+
let ty::Adt(def, _) = clause.self_ty().skip_binder().kind() else { continue };
1319+
type_spans.push(self.infcx.tcx.def_span(def.did()));
1320+
types.insert(
1321+
self.infcx
1322+
.tcx
1323+
.short_string(clause.self_ty().skip_binder(), &mut err.long_ty_path()),
1324+
);
1325+
}
1326+
let mut span: MultiSpan = type_spans.clone().into();
1327+
for sp in type_spans {
1328+
span.push_span_label(sp, "consider implementing `Clone` for this type");
1329+
}
1330+
span.push_span_label(expr.span, "you could clone this value");
1331+
let types: Vec<_> = types.into_iter().collect();
1332+
let msg = match &types[..] {
1333+
[only] => format!("`{only}`"),
1334+
[head @ .., last] => format!(
1335+
"{} and `{last}`",
1336+
head.iter().map(|t| format!("`{t}`")).collect::<Vec<_>>().join(", ")
1337+
),
1338+
[] => unreachable!(),
1339+
};
1340+
err.span_note(
1341+
span,
1342+
format!("if {msg} implemented `Clone`, you could clone the value"),
1343+
);
1344+
}
12931345
}
12941346
}
12951347

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1610,7 +1610,7 @@ extern "C" void LLVMRustPositionBefore(LLVMBuilderRef B, LLVMValueRef Instr) {
16101610

16111611
extern "C" void LLVMRustPositionAfter(LLVMBuilderRef B, LLVMValueRef Instr) {
16121612
if (auto I = dyn_cast<Instruction>(unwrap<Value>(Instr))) {
1613-
auto J = I->getNextNonDebugInstruction();
1613+
auto J = I->getNextNode();
16141614
unwrap(B)->SetInsertPoint(J);
16151615
}
16161616
}

compiler/rustc_pattern_analysis/src/constructor.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -950,9 +950,7 @@ impl<Cx: PatCx> Constructor<Cx> {
950950
}
951951
}
952952
Never => write!(f, "!")?,
953-
Wildcard | Missing | NonExhaustive | Hidden | PrivateUninhabited => {
954-
write!(f, "_ : {:?}", ty)?
955-
}
953+
Wildcard | Missing | NonExhaustive | Hidden | PrivateUninhabited => write!(f, "_")?,
956954
}
957955
Ok(())
958956
}

compiler/rustc_pattern_analysis/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ pub trait PatCx: Sized + fmt::Debug {
5757

5858
fn is_exhaustive_patterns_feature_on(&self) -> bool;
5959

60+
/// Whether to ensure the non-exhaustiveness witnesses we report for a complete set. This is
61+
/// `false` by default to avoid some exponential blowup cases such as
62+
/// <https://github.com/rust-lang/rust/issues/118437>.
63+
fn exhaustive_witnesses(&self) -> bool {
64+
false
65+
}
66+
6067
/// The number of fields for this constructor.
6168
fn ctor_arity(&self, ctor: &Constructor<Self>, ty: &Self::Ty) -> usize;
6269

compiler/rustc_pattern_analysis/src/usefulness.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -994,7 +994,8 @@ impl<Cx: PatCx> PlaceInfo<Cx> {
994994
if !missing_ctors.is_empty() && !report_individual_missing_ctors {
995995
// Report `_` as missing.
996996
missing_ctors = vec![Constructor::Wildcard];
997-
} else if missing_ctors.iter().any(|c| c.is_non_exhaustive()) {
997+
} else if missing_ctors.iter().any(|c| c.is_non_exhaustive()) && !cx.exhaustive_witnesses()
998+
{
998999
// We need to report a `_` anyway, so listing other constructors would be redundant.
9991000
// `NonExhaustive` is displayed as `_` just like `Wildcard`, but it will be picked
10001001
// up by diagnostics to add a note about why `_` is required here.
@@ -1747,7 +1748,9 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: PatCx>(
17471748
// `ctor` is *irrelevant* if there's another constructor in `split_ctors` that matches
17481749
// strictly fewer rows. In that case we can sometimes skip it. See the top of the file for
17491750
// details.
1750-
let ctor_is_relevant = matches!(ctor, Constructor::Missing) || missing_ctors.is_empty();
1751+
let ctor_is_relevant = matches!(ctor, Constructor::Missing)
1752+
|| missing_ctors.is_empty()
1753+
|| mcx.tycx.exhaustive_witnesses();
17511754
let mut spec_matrix = matrix.specialize_constructor(pcx, &ctor, ctor_is_relevant)?;
17521755
let mut witnesses = ensure_sufficient_stack(|| {
17531756
compute_exhaustiveness_and_usefulness(mcx, &mut spec_matrix)

compiler/rustc_pattern_analysis/tests/common/mod.rs

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![allow(dead_code, unreachable_pub)]
12
use rustc_pattern_analysis::constructor::{
23
Constructor, ConstructorSet, IntRange, MaybeInfiniteInt, RangeEnd, VariantVisibility,
34
};
@@ -22,8 +23,10 @@ fn init_tracing() {
2223
.try_init();
2324
}
2425

26+
pub(super) const UNIT: Ty = Ty::Tuple(&[]);
27+
pub(super) const NEVER: Ty = Ty::Enum(&[]);
28+
2529
/// A simple set of types.
26-
#[allow(dead_code)]
2730
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
2831
pub(super) enum Ty {
2932
/// Booleans
@@ -38,6 +41,8 @@ pub(super) enum Ty {
3841
BigStruct { arity: usize, ty: &'static Ty },
3942
/// A enum with `arity` variants of type `ty`.
4043
BigEnum { arity: usize, ty: &'static Ty },
44+
/// Like `Enum` but non-exhaustive.
45+
NonExhaustiveEnum(&'static [Ty]),
4146
}
4247

4348
/// The important logic.
@@ -47,7 +52,7 @@ impl Ty {
4752
match (ctor, *self) {
4853
(Struct, Ty::Tuple(tys)) => tys.iter().copied().collect(),
4954
(Struct, Ty::BigStruct { arity, ty }) => (0..arity).map(|_| *ty).collect(),
50-
(Variant(i), Ty::Enum(tys)) => vec![tys[*i]],
55+
(Variant(i), Ty::Enum(tys) | Ty::NonExhaustiveEnum(tys)) => vec![tys[*i]],
5156
(Variant(_), Ty::BigEnum { ty, .. }) => vec![*ty],
5257
(Bool(..) | IntRange(..) | NonExhaustive | Missing | Wildcard, _) => vec![],
5358
_ => panic!("Unexpected ctor {ctor:?} for type {self:?}"),
@@ -61,6 +66,7 @@ impl Ty {
6166
Ty::Enum(tys) => tys.iter().all(|ty| ty.is_empty()),
6267
Ty::BigStruct { arity, ty } => arity != 0 && ty.is_empty(),
6368
Ty::BigEnum { arity, ty } => arity == 0 || ty.is_empty(),
69+
Ty::NonExhaustiveEnum(..) => false,
6470
}
6571
}
6672

@@ -90,6 +96,19 @@ impl Ty {
9096
.collect(),
9197
non_exhaustive: false,
9298
},
99+
Ty::NonExhaustiveEnum(tys) => ConstructorSet::Variants {
100+
variants: tys
101+
.iter()
102+
.map(|ty| {
103+
if ty.is_empty() {
104+
VariantVisibility::Empty
105+
} else {
106+
VariantVisibility::Visible
107+
}
108+
})
109+
.collect(),
110+
non_exhaustive: true,
111+
},
93112
Ty::BigEnum { arity: 0, .. } => ConstructorSet::NoConstructors,
94113
Ty::BigEnum { arity, ty } => {
95114
let vis = if ty.is_empty() {
@@ -113,7 +132,9 @@ impl Ty {
113132
match (*self, ctor) {
114133
(Ty::Tuple(..), _) => Ok(()),
115134
(Ty::BigStruct { .. }, _) => write!(f, "BigStruct"),
116-
(Ty::Enum(..), Constructor::Variant(i)) => write!(f, "Enum::Variant{i}"),
135+
(Ty::Enum(..) | Ty::NonExhaustiveEnum(..), Constructor::Variant(i)) => {
136+
write!(f, "Enum::Variant{i}")
137+
}
117138
(Ty::BigEnum { .. }, Constructor::Variant(i)) => write!(f, "BigEnum::Variant{i}"),
118139
_ => write!(f, "{:?}::{:?}", self, ctor),
119140
}
@@ -126,10 +147,11 @@ pub(super) fn compute_match_usefulness<'p>(
126147
ty: Ty,
127148
scrut_validity: PlaceValidity,
128149
complexity_limit: usize,
150+
exhaustive_witnesses: bool,
129151
) -> Result<UsefulnessReport<'p, Cx>, ()> {
130152
init_tracing();
131153
rustc_pattern_analysis::usefulness::compute_match_usefulness(
132-
&Cx,
154+
&Cx { exhaustive_witnesses },
133155
arms,
134156
ty,
135157
scrut_validity,
@@ -138,7 +160,9 @@ pub(super) fn compute_match_usefulness<'p>(
138160
}
139161

140162
#[derive(Debug)]
141-
pub(super) struct Cx;
163+
pub(super) struct Cx {
164+
exhaustive_witnesses: bool,
165+
}
142166

143167
/// The context for pattern analysis. Forwards anything interesting to `Ty` methods.
144168
impl PatCx for Cx {
@@ -153,6 +177,10 @@ impl PatCx for Cx {
153177
false
154178
}
155179

180+
fn exhaustive_witnesses(&self) -> bool {
181+
self.exhaustive_witnesses
182+
}
183+
156184
fn ctor_arity(&self, ctor: &Constructor<Self>, ty: &Self::Ty) -> usize {
157185
ty.sub_tys(ctor).len()
158186
}
@@ -219,16 +247,18 @@ macro_rules! pats {
219247
// Entrypoint
220248
// Parse `type; ..`
221249
($ty:expr; $($rest:tt)*) => {{
222-
#[allow(unused_imports)]
250+
#[allow(unused)]
223251
use rustc_pattern_analysis::{
224252
constructor::{Constructor, IntRange, MaybeInfiniteInt, RangeEnd},
225-
pat::DeconstructedPat,
253+
pat::{DeconstructedPat, IndexedPat},
226254
};
227255
let ty = $ty;
228256
// The heart of the macro is designed to push `IndexedPat`s into a `Vec`, so we work around
229257
// that.
258+
#[allow(unused)]
230259
let sub_tys = ::std::iter::repeat(&ty);
231-
let mut vec = Vec::new();
260+
#[allow(unused)]
261+
let mut vec: Vec<IndexedPat<_>> = Vec::new();
232262
pats!(@ctor(vec:vec, sub_tys:sub_tys, idx:0) $($rest)*);
233263
vec.into_iter().map(|ipat| ipat.pat).collect::<Vec<_>>()
234264
}};
@@ -263,6 +293,8 @@ macro_rules! pats {
263293
let ctor = Constructor::Wildcard;
264294
pats!(@pat($($args)*, ctor:ctor) $($rest)*)
265295
}};
296+
// Nothing
297+
(@ctor($($args:tt)*)) => {};
266298

267299
// Integers and int ranges
268300
(@ctor($($args:tt)*) $($start:literal)?..$end:literal $($rest:tt)*) => {{

compiler/rustc_pattern_analysis/tests/complexity.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ fn check(patterns: &[DeconstructedPat<Cx>], complexity_limit: usize) -> Result<(
1616
let ty = *patterns[0].ty();
1717
let arms: Vec<_> =
1818
patterns.iter().map(|pat| MatchArm { pat, has_guard: false, arm_data: () }).collect();
19-
compute_match_usefulness(arms.as_slice(), ty, PlaceValidity::ValidOnly, complexity_limit)
19+
compute_match_usefulness(arms.as_slice(), ty, PlaceValidity::ValidOnly, complexity_limit, false)
2020
.map(|_report| ())
2121
}
2222

0 commit comments

Comments
 (0)