Skip to content

Commit ecf7299

Browse files
committed
Auto merge of #93173 - matthiaskrgr:rollup-49bj7ta, r=matthiaskrgr
Rollup of 10 pull requests Successful merges: - #91965 (Add more granular `--exclude` in `x.py`) - #92467 (Ensure that early-bound function lifetimes are always 'local') - #92586 (Set the allocation MIN_ALIGN for espidf to 4.) - #92835 (Improve error message for key="value" cfg arguments.) - #92843 (Improve string concatenation suggestion) - #92963 (Implement tuple array diagnostic) - #93046 (Use let_else in even more places) - #93109 (Improve `Arc` and `Rc` documentation) - #93134 (delete `Stdin::split` forwarder) - #93139 (rustdoc: fix overflow-wrap for table layouts) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 17d29dc + 26e9357 commit ecf7299

File tree

77 files changed

+643
-509
lines changed

Some content is hidden

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

77 files changed

+643
-509
lines changed

compiler/rustc_borrowck/src/universal_regions.rs

+25-16
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,9 @@ pub enum RegionClassification {
180180
/// anywhere. There is only one, `'static`.
181181
Global,
182182

183-
/// An **external** region is only relevant for closures. In that
184-
/// case, it refers to regions that are free in the closure type
183+
/// An **external** region is only relevant for
184+
/// closures, generators, and inline consts. In that
185+
/// case, it refers to regions that are free in the type
185186
/// -- basically, something bound in the surrounding context.
186187
///
187188
/// Consider this example:
@@ -198,8 +199,8 @@ pub enum RegionClassification {
198199
/// Here, the lifetimes `'a` and `'b` would be **external** to the
199200
/// closure.
200201
///
201-
/// If we are not analyzing a closure, there are no external
202-
/// lifetimes.
202+
/// If we are not analyzing a closure/generator/inline-const,
203+
/// there are no external lifetimes.
203204
External,
204205

205206
/// A **local** lifetime is one about which we know the full set
@@ -424,22 +425,30 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
424425

425426
let typeck_root_def_id = self.infcx.tcx.typeck_root_def_id(self.mir_def.did.to_def_id());
426427

427-
// If this is a closure or generator, then the late-bound regions from the enclosing
428-
// function are actually external regions to us. For example, here, 'a is not local
429-
// to the closure c (although it is local to the fn foo):
430-
// fn foo<'a>() {
431-
// let c = || { let x: &'a u32 = ...; }
432-
// }
433-
if self.mir_def.did.to_def_id() != typeck_root_def_id {
428+
// If this is is a 'root' body (not a closure/generator/inline const), then
429+
// there are no extern regions, so the local regions start at the same
430+
// position as the (empty) sub-list of extern regions
431+
let first_local_index = if self.mir_def.did.to_def_id() == typeck_root_def_id {
432+
first_extern_index
433+
} else {
434+
// If this is a closure, generator, or inline-const, then the late-bound regions from the enclosing
435+
// function are actually external regions to us. For example, here, 'a is not local
436+
// to the closure c (although it is local to the fn foo):
437+
// fn foo<'a>() {
438+
// let c = || { let x: &'a u32 = ...; }
439+
// }
434440
self.infcx
435-
.replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices)
436-
}
437-
438-
let bound_inputs_and_output = self.compute_inputs_and_output(&indices, defining_ty);
441+
.replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices);
442+
// Any regions created during the execution of `defining_ty` or during the above
443+
// late-bound region replacement are all considered 'extern' regions
444+
self.infcx.num_region_vars()
445+
};
439446

440447
// "Liberate" the late-bound regions. These correspond to
441448
// "local" free regions.
442-
let first_local_index = self.infcx.num_region_vars();
449+
450+
let bound_inputs_and_output = self.compute_inputs_and_output(&indices, defining_ty);
451+
443452
let inputs_and_output = self.infcx.replace_bound_regions_with_nll_infer_vars(
444453
FR,
445454
self.mir_def.did,

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1493,7 +1493,7 @@ fn generator_layout_and_saved_local_names<'tcx>(
14931493

14941494
let state_arg = mir::Local::new(1);
14951495
for var in &body.var_debug_info {
1496-
let place = if let mir::VarDebugInfoContents::Place(p) = var.value { p } else { continue };
1496+
let mir::VarDebugInfoContents::Place(place) = &var.value else { continue };
14971497
if place.local != state_arg {
14981498
continue;
14991499
}

compiler/rustc_codegen_llvm/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
88
#![feature(bool_to_option)]
99
#![feature(crate_visibility_modifier)]
10+
#![feature(let_else)]
1011
#![feature(extern_types)]
1112
#![feature(nll)]
1213
#![recursion_limit = "256"]

compiler/rustc_interface/src/interface.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,16 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String
124124
Err(errs) => errs.into_iter().for_each(|mut err| err.cancel()),
125125
}
126126

127-
error!(r#"expected `key` or `key="value"`"#);
127+
// If the user tried to use a key="value" flag, but is missing the quotes, provide
128+
// a hint about how to resolve this.
129+
if s.contains("=") && !s.contains("=\"") && !s.ends_with("\"") {
130+
error!(concat!(
131+
r#"expected `key` or `key="value"`, ensure escaping is appropriate"#,
132+
r#" for your shell, try 'key="value"' or key=\"value\""#
133+
));
134+
} else {
135+
error!(r#"expected `key` or `key="value"`"#);
136+
}
128137
})
129138
.collect::<CrateConfig>();
130139
cfg.into_iter().map(|(a, b)| (a.to_string(), b.map(|b| b.to_string()))).collect()

compiler/rustc_interface/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![feature(bool_to_option)]
22
#![feature(box_patterns)]
3+
#![feature(let_else)]
34
#![feature(internal_output_capture)]
45
#![feature(thread_spawn_unchecked)]
56
#![feature(nll)]

compiler/rustc_interface/src/util.rs

+46-46
Original file line numberDiff line numberDiff line change
@@ -717,57 +717,57 @@ impl<'a, 'b> ReplaceBodyWithLoop<'a, 'b> {
717717
}
718718

719719
fn should_ignore_fn(ret_ty: &ast::FnRetTy) -> bool {
720-
if let ast::FnRetTy::Ty(ref ty) = ret_ty {
721-
fn involves_impl_trait(ty: &ast::Ty) -> bool {
722-
match ty.kind {
723-
ast::TyKind::ImplTrait(..) => true,
724-
ast::TyKind::Slice(ref subty)
725-
| ast::TyKind::Array(ref subty, _)
726-
| ast::TyKind::Ptr(ast::MutTy { ty: ref subty, .. })
727-
| ast::TyKind::Rptr(_, ast::MutTy { ty: ref subty, .. })
728-
| ast::TyKind::Paren(ref subty) => involves_impl_trait(subty),
729-
ast::TyKind::Tup(ref tys) => any_involves_impl_trait(tys.iter()),
730-
ast::TyKind::Path(_, ref path) => {
731-
path.segments.iter().any(|seg| match seg.args.as_deref() {
732-
None => false,
733-
Some(&ast::GenericArgs::AngleBracketed(ref data)) => {
734-
data.args.iter().any(|arg| match arg {
735-
ast::AngleBracketedArg::Arg(arg) => match arg {
736-
ast::GenericArg::Type(ty) => involves_impl_trait(ty),
737-
ast::GenericArg::Lifetime(_)
738-
| ast::GenericArg::Const(_) => false,
739-
},
740-
ast::AngleBracketedArg::Constraint(c) => match c.kind {
741-
ast::AssocConstraintKind::Bound { .. } => true,
742-
ast::AssocConstraintKind::Equality { ref term } => {
743-
match term {
744-
Term::Ty(ty) => involves_impl_trait(ty),
745-
// FIXME(...): This should check if the constant
746-
// involves a trait impl, but for now ignore.
747-
Term::Const(_) => false,
748-
}
720+
let ast::FnRetTy::Ty(ref ty) = ret_ty else {
721+
return false;
722+
};
723+
fn involves_impl_trait(ty: &ast::Ty) -> bool {
724+
match ty.kind {
725+
ast::TyKind::ImplTrait(..) => true,
726+
ast::TyKind::Slice(ref subty)
727+
| ast::TyKind::Array(ref subty, _)
728+
| ast::TyKind::Ptr(ast::MutTy { ty: ref subty, .. })
729+
| ast::TyKind::Rptr(_, ast::MutTy { ty: ref subty, .. })
730+
| ast::TyKind::Paren(ref subty) => involves_impl_trait(subty),
731+
ast::TyKind::Tup(ref tys) => any_involves_impl_trait(tys.iter()),
732+
ast::TyKind::Path(_, ref path) => {
733+
path.segments.iter().any(|seg| match seg.args.as_deref() {
734+
None => false,
735+
Some(&ast::GenericArgs::AngleBracketed(ref data)) => {
736+
data.args.iter().any(|arg| match arg {
737+
ast::AngleBracketedArg::Arg(arg) => match arg {
738+
ast::GenericArg::Type(ty) => involves_impl_trait(ty),
739+
ast::GenericArg::Lifetime(_) | ast::GenericArg::Const(_) => {
740+
false
741+
}
742+
},
743+
ast::AngleBracketedArg::Constraint(c) => match c.kind {
744+
ast::AssocConstraintKind::Bound { .. } => true,
745+
ast::AssocConstraintKind::Equality { ref term } => {
746+
match term {
747+
Term::Ty(ty) => involves_impl_trait(ty),
748+
// FIXME(...): This should check if the constant
749+
// involves a trait impl, but for now ignore.
750+
Term::Const(_) => false,
749751
}
750-
},
751-
})
752-
}
753-
Some(&ast::GenericArgs::Parenthesized(ref data)) => {
754-
any_involves_impl_trait(data.inputs.iter())
755-
|| ReplaceBodyWithLoop::should_ignore_fn(&data.output)
756-
}
757-
})
758-
}
759-
_ => false,
752+
}
753+
},
754+
})
755+
}
756+
Some(&ast::GenericArgs::Parenthesized(ref data)) => {
757+
any_involves_impl_trait(data.inputs.iter())
758+
|| ReplaceBodyWithLoop::should_ignore_fn(&data.output)
759+
}
760+
})
760761
}
762+
_ => false,
761763
}
764+
}
762765

763-
fn any_involves_impl_trait<'a, I: Iterator<Item = &'a P<ast::Ty>>>(mut it: I) -> bool {
764-
it.any(|subty| involves_impl_trait(subty))
765-
}
766-
767-
involves_impl_trait(ty)
768-
} else {
769-
false
766+
fn any_involves_impl_trait<'a, I: Iterator<Item = &'a P<ast::Ty>>>(mut it: I) -> bool {
767+
it.any(|subty| involves_impl_trait(subty))
770768
}
769+
770+
involves_impl_trait(ty)
771771
}
772772

773773
fn is_sig_const(sig: &ast::FnSig) -> bool {

compiler/rustc_mir_build/src/build/matches/mod.rs

+15-16
Original file line numberDiff line numberDiff line change
@@ -1347,23 +1347,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
13471347

13481348
let mut otherwise = None;
13491349
for match_pair in match_pairs {
1350-
if let PatKind::Or { ref pats } = *match_pair.pattern.kind {
1351-
let or_span = match_pair.pattern.span;
1352-
let place = match_pair.place;
1353-
1354-
first_candidate.visit_leaves(|leaf_candidate| {
1355-
self.test_or_pattern(
1356-
leaf_candidate,
1357-
&mut otherwise,
1358-
pats,
1359-
or_span,
1360-
place.clone(),
1361-
fake_borrows,
1362-
);
1363-
});
1364-
} else {
1350+
let PatKind::Or { ref pats } = &*match_pair.pattern.kind else {
13651351
bug!("Or-patterns should have been sorted to the end");
1366-
}
1352+
};
1353+
let or_span = match_pair.pattern.span;
1354+
let place = match_pair.place;
1355+
1356+
first_candidate.visit_leaves(|leaf_candidate| {
1357+
self.test_or_pattern(
1358+
leaf_candidate,
1359+
&mut otherwise,
1360+
pats,
1361+
or_span,
1362+
place.clone(),
1363+
fake_borrows,
1364+
);
1365+
});
13671366
}
13681367

13691368
let remainder_start = otherwise.unwrap_or_else(|| self.cfg.start_new_block());

compiler/rustc_mir_build/src/build/matches/test.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
8888
switch_ty: Ty<'tcx>,
8989
options: &mut FxIndexMap<&'tcx ty::Const<'tcx>, u128>,
9090
) -> bool {
91-
let match_pair = match candidate.match_pairs.iter().find(|mp| mp.place == *test_place) {
92-
Some(match_pair) => match_pair,
93-
_ => {
94-
return false;
95-
}
91+
let Some(match_pair) = candidate.match_pairs.iter().find(|mp| mp.place == *test_place) else {
92+
return false;
9693
};
9794

9895
match *match_pair.pattern.kind {

compiler/rustc_resolve/src/late/diagnostics.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1171,9 +1171,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
11711171
ident: Symbol,
11721172
kind: &AssocItemKind,
11731173
) -> Option<Symbol> {
1174-
let module = if let Some((module, _)) = self.current_trait_ref {
1175-
module
1176-
} else {
1174+
let Some((module, _)) = &self.current_trait_ref else {
11771175
return None;
11781176
};
11791177
if ident == kw::Underscore {

compiler/rustc_resolve/src/late/lifetimes.rs

+37-38
Original file line numberDiff line numberDiff line change
@@ -1000,46 +1000,45 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
10001000
// `fn foo<'a>() -> MyAnonTy<'a> { ... }`
10011001
// ^ ^this gets resolved in the current scope
10021002
for lifetime in lifetimes {
1003-
if let hir::GenericArg::Lifetime(lifetime) = lifetime {
1004-
self.visit_lifetime(lifetime);
1003+
let hir::GenericArg::Lifetime(lifetime) = lifetime else {
1004+
continue
1005+
};
1006+
self.visit_lifetime(lifetime);
1007+
1008+
// Check for predicates like `impl for<'a> Trait<impl OtherTrait<'a>>`
1009+
// and ban them. Type variables instantiated inside binders aren't
1010+
// well-supported at the moment, so this doesn't work.
1011+
// In the future, this should be fixed and this error should be removed.
1012+
let def = self.map.defs.get(&lifetime.hir_id).cloned();
1013+
let Some(Region::LateBound(_, _, def_id, _)) = def else {
1014+
continue
1015+
};
1016+
let Some(def_id) = def_id.as_local() else {
1017+
continue
1018+
};
1019+
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
1020+
// Ensure that the parent of the def is an item, not HRTB
1021+
let parent_id = self.tcx.hir().get_parent_node(hir_id);
1022+
// FIXME(cjgillot) Can this check be replaced by
1023+
// `let parent_is_item = parent_id.is_owner();`?
1024+
let parent_is_item = if let Some(parent_def_id) = parent_id.as_owner() {
1025+
matches!(self.tcx.hir().krate().owners.get(parent_def_id), Some(Some(_)),)
1026+
} else {
1027+
false
1028+
};
10051029

1006-
// Check for predicates like `impl for<'a> Trait<impl OtherTrait<'a>>`
1007-
// and ban them. Type variables instantiated inside binders aren't
1008-
// well-supported at the moment, so this doesn't work.
1009-
// In the future, this should be fixed and this error should be removed.
1010-
let def = self.map.defs.get(&lifetime.hir_id).cloned();
1011-
if let Some(Region::LateBound(_, _, def_id, _)) = def {
1012-
if let Some(def_id) = def_id.as_local() {
1013-
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
1014-
// Ensure that the parent of the def is an item, not HRTB
1015-
let parent_id = self.tcx.hir().get_parent_node(hir_id);
1016-
// FIXME(cjgillot) Can this check be replaced by
1017-
// `let parent_is_item = parent_id.is_owner();`?
1018-
let parent_is_item =
1019-
if let Some(parent_def_id) = parent_id.as_owner() {
1020-
matches!(
1021-
self.tcx.hir().krate().owners.get(parent_def_id),
1022-
Some(Some(_)),
1023-
)
1024-
} else {
1025-
false
1026-
};
1027-
1028-
if !parent_is_item {
1029-
if !self.trait_definition_only {
1030-
struct_span_err!(
1031-
self.tcx.sess,
1032-
lifetime.span,
1033-
E0657,
1034-
"`impl Trait` can only capture lifetimes \
1035-
bound at the fn or impl level"
1036-
)
1037-
.emit();
1038-
}
1039-
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
1040-
}
1041-
}
1030+
if !parent_is_item {
1031+
if !self.trait_definition_only {
1032+
struct_span_err!(
1033+
self.tcx.sess,
1034+
lifetime.span,
1035+
E0657,
1036+
"`impl Trait` can only capture lifetimes \
1037+
bound at the fn or impl level"
1038+
)
1039+
.emit();
10421040
}
1041+
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
10431042
}
10441043
}
10451044

0 commit comments

Comments
 (0)