Skip to content

Commit 038d115

Browse files
committed
Auto merge of #120170 - GuillaumeGomez:rollup-edqdf30, r=GuillaumeGomez
Rollup of 6 pull requests Successful merges: - #119997 (Fix impl stripped in rustdoc HTML whereas it should not be in case the impl is implemented on a type alias) - #120000 (Ensure `callee_id`s are body owners) - #120063 (Remove special handling of `box` expressions from parser) - #120116 (Remove alignment-changing in-place collect) - #120138 (Increase vscode settings.json `git.detectSubmodulesLimit`) - #120169 (Spelling fix) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 1828461 + 774cd3a commit 038d115

File tree

49 files changed

+97
-76
lines changed

Some content is hidden

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

49 files changed

+97
-76
lines changed

compiler/rustc_parse/src/parser/expr.rs

+7-21
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ use rustc_session::errors::{report_lit_error, ExprParenthesesNeeded};
3333
use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP;
3434
use rustc_session::lint::BuiltinLintDiagnostics;
3535
use rustc_span::source_map::{self, Spanned};
36-
use rustc_span::symbol::kw::PathRoot;
3736
use rustc_span::symbol::{kw, sym, Ident, Symbol};
3837
use rustc_span::{BytePos, Pos, Span};
3938
use thin_vec::{thin_vec, ThinVec};
@@ -642,26 +641,13 @@ impl<'a> Parser<'a> {
642641
}
643642

644643
/// Parse `box expr` - this syntax has been removed, but we still parse this
645-
/// for now to provide an automated way to fix usages of it
646-
fn parse_expr_box(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
647-
let (span, expr) = self.parse_expr_prefix_common(lo)?;
648-
let code = self.sess.source_map().span_to_snippet(span.with_lo(lo.hi())).unwrap();
649-
self.dcx().emit_err(errors::BoxSyntaxRemoved { span, code: code.trim() });
650-
// So typechecking works, parse `box <expr>` as `::std::boxed::Box::new(expr)`
651-
let path = Path {
652-
span,
653-
segments: [
654-
PathSegment::from_ident(Ident::with_dummy_span(PathRoot)),
655-
PathSegment::from_ident(Ident::with_dummy_span(sym::std)),
656-
PathSegment::from_ident(Ident::from_str("boxed")),
657-
PathSegment::from_ident(Ident::from_str("Box")),
658-
PathSegment::from_ident(Ident::with_dummy_span(sym::new)),
659-
]
660-
.into(),
661-
tokens: None,
662-
};
663-
let path = self.mk_expr(span, ExprKind::Path(None, path));
664-
Ok((span, self.mk_call(path, ThinVec::from([expr]))))
644+
/// for now to provide a more useful error
645+
fn parse_expr_box(&mut self, box_kw: Span) -> PResult<'a, (Span, ExprKind)> {
646+
let (span, _) = self.parse_expr_prefix_common(box_kw)?;
647+
let inner_span = span.with_lo(box_kw.hi());
648+
let code = self.sess.source_map().span_to_snippet(inner_span).unwrap();
649+
self.dcx().emit_err(errors::BoxSyntaxRemoved { span: span, code: code.trim() });
650+
Ok((span, ExprKind::Err))
665651
}
666652

667653
fn is_mistaken_not_ident_negation(&self) -> bool {

library/alloc/src/vec/in_place_collect.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,9 @@ const fn in_place_collectible<DEST, SRC>(
168168
step_merge: Option<NonZeroUsize>,
169169
step_expand: Option<NonZeroUsize>,
170170
) -> bool {
171-
if const { SRC::IS_ZST || DEST::IS_ZST || mem::align_of::<SRC>() < mem::align_of::<DEST>() } {
171+
// Require matching alignments because an alignment-changing realloc is inefficient on many
172+
// system allocators and better implementations would require the unstable Allocator trait.
173+
if const { SRC::IS_ZST || DEST::IS_ZST || mem::align_of::<SRC>() != mem::align_of::<DEST>() } {
172174
return false;
173175
}
174176

@@ -188,7 +190,8 @@ const fn in_place_collectible<DEST, SRC>(
188190

189191
const fn needs_realloc<SRC, DEST>(src_cap: usize, dst_cap: usize) -> bool {
190192
if const { mem::align_of::<SRC>() != mem::align_of::<DEST>() } {
191-
return src_cap > 0;
193+
// FIXME: use unreachable! once that works in const
194+
panic!("in_place_collectible() prevents this");
192195
}
193196

194197
// If src type size is an integer multiple of the destination type size then
@@ -276,8 +279,8 @@ where
276279
let dst_guard = InPlaceDstBufDrop { ptr: dst_buf, len, cap: dst_cap };
277280
src.forget_allocation_drop_remaining();
278281

279-
// Adjust the allocation if the alignment didn't match or the source had a capacity in bytes
280-
// that wasn't a multiple of the destination type size.
282+
// Adjust the allocation if the source had a capacity in bytes that wasn't a multiple
283+
// of the destination type size.
281284
// Since the discrepancy should generally be small this should only result in some
282285
// bookkeeping updates and no memmove.
283286
if needs_realloc::<I::Src, T>(src_cap, dst_cap) {
@@ -290,7 +293,7 @@ where
290293
let src_size = mem::size_of::<I::Src>().unchecked_mul(src_cap);
291294
let old_layout = Layout::from_size_align_unchecked(src_size, src_align);
292295

293-
// The must be equal or smaller for in-place iteration to be possible
296+
// The allocation must be equal or smaller for in-place iteration to be possible
294297
// therefore the new layout must be ≤ the old one and therefore valid.
295298
let dst_align = mem::align_of::<T>();
296299
let dst_size = mem::size_of::<T>().unchecked_mul(dst_cap);

library/alloc/src/vec/spec_from_iter.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ use super::{IntoIter, SpecExtend, SpecFromIterNested, Vec};
1313
/// +-+-----------+
1414
/// |
1515
/// v
16-
/// +-+-------------------------------+ +---------------------+
17-
/// |SpecFromIter +---->+SpecFromIterNested |
18-
/// |where I: | | |where I: |
19-
/// | Iterator (default)----------+ | | Iterator (default) |
20-
/// | vec::IntoIter | | | TrustedLen |
21-
/// | SourceIterMarker---fallback-+ | +---------------------+
22-
/// +---------------------------------+
16+
/// +-+---------------------------------+ +---------------------+
17+
/// |SpecFromIter +---->+SpecFromIterNested |
18+
/// |where I: | | |where I: |
19+
/// | Iterator (default)------------+ | | Iterator (default) |
20+
/// | vec::IntoIter | | | TrustedLen |
21+
/// | InPlaceCollect--(fallback to)-+ | +---------------------+
22+
/// +-----------------------------------+
2323
/// ```
2424
pub(super) trait SpecFromIter<T, I> {
2525
fn from_iter(iter: I) -> Self;

library/core/src/error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ where
415415
// Request and its methods
416416
///////////////////////////////////////////////////////////////////////////////
417417

418-
/// `Request` supports generic, type-driven access to data. It's use is currently restricted to the
418+
/// `Request` supports generic, type-driven access to data. Its use is currently restricted to the
419419
/// standard library in cases where trait authors wish to allow trait implementors to share generic
420420
/// information across trait boundaries. The motivating and prototypical use case is
421421
/// `core::error::Error` which would otherwise require a method per concrete type (eg.

src/bootstrap/src/core/build_steps/setup.rs

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ static SETTINGS_HASHES: &[&str] = &[
3737
"3468fea433c25fff60be6b71e8a215a732a7b1268b6a83bf10d024344e140541",
3838
"47d227f424bf889b0d899b9cc992d5695e1b78c406e183cd78eafefbe5488923",
3939
"b526bd58d0262dd4dda2bff5bc5515b705fb668a46235ace3e057f807963a11a",
40+
"828666b021d837a33e78d870b56d34c88a5e2c85de58b693607ec574f0c27000",
4041
];
4142
static RUST_ANALYZER_SETTINGS: &str = include_str!("../../../../etc/rust_analyzer_settings.json");
4243

src/etc/rust_analyzer_settings.json

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
"git.detectSubmodulesLimit": 20,
23
"rust-analyzer.check.invocationLocation": "root",
34
"rust-analyzer.check.invocationStrategy": "once",
45
"rust-analyzer.check.overrideCommand": [

src/librustdoc/passes/stripper.rs

+19-12
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,10 @@ impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> {
5656
| clean::TraitItem(..)
5757
| clean::FunctionItem(..)
5858
| clean::VariantItem(..)
59-
| clean::MethodItem(..)
6059
| clean::ForeignFunctionItem(..)
6160
| clean::ForeignStaticItem(..)
6261
| clean::ConstantItem(..)
6362
| clean::UnionItem(..)
64-
| clean::AssocConstItem(..)
65-
| clean::AssocTypeItem(..)
6663
| clean::TraitAliasItem(..)
6764
| clean::MacroItem(..)
6865
| clean::ForeignTypeItem => {
@@ -80,6 +77,16 @@ impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> {
8077
}
8178
}
8279

80+
clean::MethodItem(..) | clean::AssocConstItem(..) | clean::AssocTypeItem(..) => {
81+
let item_id = i.item_id;
82+
if item_id.is_local()
83+
&& !self.effective_visibilities.is_reachable(self.tcx, item_id.expect_def_id())
84+
{
85+
debug!("Stripper: stripping {:?} {:?}", i.type_(), i.name);
86+
return None;
87+
}
88+
}
89+
8390
clean::StructFieldItem(..) => {
8491
if i.visibility(self.tcx) != Some(Visibility::Public) {
8592
return Some(strip_item(i));
@@ -192,16 +199,16 @@ impl<'a> DocFolder for ImplStripper<'a, '_> {
192199
&& imp.items.iter().all(|i| {
193200
let item_id = i.item_id;
194201
item_id.is_local()
195-
&& !is_item_reachable(
196-
self.tcx,
197-
self.is_json_output,
198-
&self.cache.effective_visibilities,
199-
item_id,
200-
)
202+
&& !self
203+
.cache
204+
.effective_visibilities
205+
.is_reachable(self.tcx, item_id.expect_def_id())
201206
})
202207
{
208+
debug!("ImplStripper: no public item; removing {imp:?}");
203209
return None;
204210
} else if imp.items.is_empty() && i.doc_value().is_empty() {
211+
debug!("ImplStripper: no item and no doc; removing {imp:?}");
205212
return None;
206213
}
207214
}
@@ -212,21 +219,21 @@ impl<'a> DocFolder for ImplStripper<'a, '_> {
212219
&& !imp.for_.is_assoc_ty()
213220
&& !self.should_keep_impl(&i, did)
214221
{
215-
debug!("ImplStripper: impl item for stripped type; removing");
222+
debug!("ImplStripper: impl item for stripped type; removing {imp:?}");
216223
return None;
217224
}
218225
if let Some(did) = imp.trait_.as_ref().map(|t| t.def_id())
219226
&& !self.should_keep_impl(&i, did)
220227
{
221-
debug!("ImplStripper: impl item for stripped trait; removing");
228+
debug!("ImplStripper: impl item for stripped trait; removing {imp:?}");
222229
return None;
223230
}
224231
if let Some(generics) = imp.trait_.as_ref().and_then(|t| t.generics()) {
225232
for typaram in generics {
226233
if let Some(did) = typaram.def_id(self.cache)
227234
&& !self.should_keep_impl(&i, did)
228235
{
229-
debug!("ImplStripper: stripped item in trait's generics; removing impl");
236+
debug!("ImplStripper: stripped item in trait's generics; removing {imp:?}");
230237
return None;
231238
}
232239
}

src/tools/clippy/clippy_lints/src/derive.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -451,12 +451,12 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
451451
&& let Some(def_id) = trait_ref.trait_def_id()
452452
&& cx.tcx.is_diagnostic_item(sym::PartialEq, def_id)
453453
&& let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id)
454-
&& !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, adt.did(),&[])
454+
&& !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, None, &[])
455455
// If all of our fields implement `Eq`, we can implement `Eq` too
456456
&& adt
457457
.all_fields()
458458
.map(|f| f.ty(cx.tcx, args))
459-
.all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, adt.did(), &[]))
459+
.all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, None, &[]))
460460
{
461461
span_lint_and_sugg(
462462
cx,

src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ fn is_ref_iterable<'tcx>(
118118
.liberate_late_bound_regions(fn_id, cx.tcx.fn_sig(fn_id).skip_binder())
119119
&& let &[req_self_ty, req_res_ty] = &**sig.inputs_and_output
120120
&& let param_env = cx.tcx.param_env(fn_id)
121-
&& implements_trait_with_env(cx.tcx, param_env, req_self_ty, trait_id, fn_id, &[])
121+
&& implements_trait_with_env(cx.tcx, param_env, req_self_ty, trait_id, Some(fn_id), &[])
122122
&& let Some(into_iter_ty) =
123123
make_normalized_projection_with_regions(cx.tcx, param_env, trait_id, sym!(IntoIter), [req_self_ty])
124124
&& let req_res_ty = normalize_with_regions(cx.tcx, param_env, req_res_ty)

src/tools/clippy/clippy_utils/src/ty.rs

+12-20
Original file line numberDiff line numberDiff line change
@@ -214,36 +214,21 @@ pub fn implements_trait<'tcx>(
214214
trait_id: DefId,
215215
args: &[GenericArg<'tcx>],
216216
) -> bool {
217-
let callee_id = cx
218-
.enclosing_body
219-
.map(|body| cx.tcx.hir().body_owner(body).owner.to_def_id());
220-
implements_trait_with_env_from_iter(
221-
cx.tcx,
222-
cx.param_env,
223-
ty,
224-
trait_id,
225-
callee_id,
226-
args.iter().map(|&x| Some(x)),
227-
)
217+
implements_trait_with_env_from_iter(cx.tcx, cx.param_env, ty, trait_id, None, args.iter().map(|&x| Some(x)))
228218
}
229219

230220
/// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context.
221+
///
222+
/// The `callee_id` argument is used to determine whether this is a function call in a `const fn` environment, used for checking const traits.
231223
pub fn implements_trait_with_env<'tcx>(
232224
tcx: TyCtxt<'tcx>,
233225
param_env: ParamEnv<'tcx>,
234226
ty: Ty<'tcx>,
235227
trait_id: DefId,
236-
callee_id: DefId,
228+
callee_id: Option<DefId>,
237229
args: &[GenericArg<'tcx>],
238230
) -> bool {
239-
implements_trait_with_env_from_iter(
240-
tcx,
241-
param_env,
242-
ty,
243-
trait_id,
244-
Some(callee_id),
245-
args.iter().map(|&x| Some(x)),
246-
)
231+
implements_trait_with_env_from_iter(tcx, param_env, ty, trait_id, callee_id, args.iter().map(|&x| Some(x)))
247232
}
248233

249234
/// Same as `implements_trait_from_env` but takes the arguments as an iterator.
@@ -258,6 +243,13 @@ pub fn implements_trait_with_env_from_iter<'tcx>(
258243
// Clippy shouldn't have infer types
259244
assert!(!ty.has_infer());
260245

246+
// If a `callee_id` is passed, then we assert that it is a body owner
247+
// through calling `body_owner_kind`, which would panic if the callee
248+
// does not have a body.
249+
if let Some(callee_id) = callee_id {
250+
let _ = tcx.hir().body_owner_kind(callee_id);
251+
}
252+
261253
let ty = tcx.erase_regions(ty);
262254
if ty.has_escaping_bound_vars() {
263255
return false;

tests/rustdoc/async-fn.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ impl Foo {
4848

4949
pub trait Pattern<'a> {}
5050

51+
impl Pattern<'_> for () {}
52+
5153
pub trait Trait<const N: usize> {}
5254
// @has async_fn/fn.const_generics.html
5355
// @has - '//pre[@class="rust item-decl"]' 'pub async fn const_generics<const N: usize>(_: impl Trait<N>)'
@@ -57,18 +59,18 @@ pub async fn const_generics<const N: usize>(_: impl Trait<N>) {}
5759
// regression test for #63037
5860
// @has async_fn/fn.elided.html
5961
// @has - '//pre[@class="rust item-decl"]' 'pub async fn elided(foo: &str) -> &str'
60-
pub async fn elided(foo: &str) -> &str {}
62+
pub async fn elided(foo: &str) -> &str { "" }
6163
// This should really be shown as written, but for implementation reasons it's difficult.
6264
// See `impl Clean for TyKind::Ref`.
6365
// @has async_fn/fn.user_elided.html
6466
// @has - '//pre[@class="rust item-decl"]' 'pub async fn user_elided(foo: &str) -> &str'
65-
pub async fn user_elided(foo: &'_ str) -> &str {}
67+
pub async fn user_elided(foo: &'_ str) -> &str { "" }
6668
// @has async_fn/fn.static_trait.html
6769
// @has - '//pre[@class="rust item-decl"]' 'pub async fn static_trait(foo: &str) -> Box<dyn Bar>'
68-
pub async fn static_trait(foo: &str) -> Box<dyn Bar> {}
70+
pub async fn static_trait(foo: &str) -> Box<dyn Bar> { Box::new(()) }
6971
// @has async_fn/fn.lifetime_for_trait.html
7072
// @has - '//pre[@class="rust item-decl"]' "pub async fn lifetime_for_trait(foo: &str) -> Box<dyn Bar + '_>"
71-
pub async fn lifetime_for_trait(foo: &str) -> Box<dyn Bar + '_> {}
73+
pub async fn lifetime_for_trait(foo: &str) -> Box<dyn Bar + '_> { Box::new(()) }
7274
// @has async_fn/fn.elided_in_input_trait.html
7375
// @has - '//pre[@class="rust item-decl"]' "pub async fn elided_in_input_trait(t: impl Pattern<'_>)"
7476
pub async fn elided_in_input_trait(t: impl Pattern<'_>) {}
@@ -78,18 +80,20 @@ struct AsyncFdReadyGuard<'a, T> { x: &'a T }
7880
impl Foo {
7981
// @has async_fn/struct.Foo.html
8082
// @has - '//*[@class="method"]' 'pub async fn complicated_lifetimes( &self, context: &impl Bar ) -> impl Iterator<Item = &usize>'
81-
pub async fn complicated_lifetimes(&self, context: &impl Bar) -> impl Iterator<Item = &usize> {}
83+
pub async fn complicated_lifetimes(&self, context: &impl Bar) -> impl Iterator<Item = &usize> {
84+
[0].iter()
85+
}
8286
// taken from `tokio` as an example of a method that was particularly bad before
8387
// @has - '//*[@class="method"]' "pub async fn readable<T>(&self) -> Result<AsyncFdReadyGuard<'_, T>, ()>"
84-
pub async fn readable<T>(&self) -> Result<AsyncFdReadyGuard<'_, T>, ()> {}
88+
pub async fn readable<T>(&self) -> Result<AsyncFdReadyGuard<'_, T>, ()> { Err(()) }
8589
// @has - '//*[@class="method"]' "pub async fn mut_self(&mut self)"
8690
pub async fn mut_self(&mut self) {}
8791
}
8892

8993
// test named lifetimes, just in case
9094
// @has async_fn/fn.named.html
9195
// @has - '//pre[@class="rust item-decl"]' "pub async fn named<'a, 'b>(foo: &'a str) -> &'b str"
92-
pub async fn named<'a, 'b>(foo: &'a str) -> &'b str {}
96+
pub async fn named<'a, 'b>(foo: &'a str) -> &'b str { "" }
9397
// @has async_fn/fn.named_trait.html
9498
// @has - '//pre[@class="rust item-decl"]' "pub async fn named_trait<'a, 'b>(foo: impl Pattern<'a>) -> impl Pattern<'b>"
9599
pub async fn named_trait<'a, 'b>(foo: impl Pattern<'a>) -> impl Pattern<'b> {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#![crate_name = "foo"]
2+
3+
// @has 'foo/index.html'
4+
// There should be only `type A`.
5+
// @count - '//*[@class="item-table"]//*[@class="item-name"]' 1
6+
// @has - '//*[@class="item-name"]/a[@href="type.A.html"]' 'A'
7+
8+
mod foo {
9+
pub struct S;
10+
}
11+
12+
use foo::S;
13+
14+
pub type A = S;
15+
16+
// @has 'foo/type.A.html'
17+
// @has - '//*[@id="method.default"]/h4' 'fn default() -> Self'
18+
impl Default for A {
19+
fn default() -> Self {
20+
S
21+
}
22+
}
23+
24+
// @has - '//*[@id="method.a"]/h4' 'pub fn a(&self)'
25+
impl A {
26+
pub fn a(&self) {}
27+
}

0 commit comments

Comments
 (0)