Skip to content

Commit 99322d8

Browse files
committed
Auto merge of rust-lang#128435 - matthiaskrgr:rollup-l76vu3i, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - rust-lang#126454 (bump-stage0: use IndexMap for determinism) - rust-lang#127681 (derive(SmartPointer): rewrite bounds in where and generic bounds) - rust-lang#127830 (When an archive fails to build, print the path) - rust-lang#128151 (Structured suggestion for `extern crate foo` when `foo` isn't resolved in import) - rust-lang#128387 (More detailed note to deprecate ONCE_INIT) - rust-lang#128388 (Match LLVM ABI in `extern "C"` functions for `f128` on Windows) - rust-lang#128402 (Attribute checking simplifications) - rust-lang#128412 (Remove `crate_level_only` from `ELIDED_LIFETIMES_IN_PATHS`) - rust-lang#128430 (Use a separate pattern type for `rustc_pattern_analysis` diagnostics ) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 0b5eb7b + 031093f commit 99322d8

File tree

55 files changed

+1415
-1030
lines changed

Some content is hidden

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

55 files changed

+1415
-1030
lines changed

compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs

+227-17
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
use std::mem::swap;
22

3+
use ast::ptr::P;
34
use ast::HasAttrs;
5+
use rustc_ast::mut_visit::MutVisitor;
6+
use rustc_ast::visit::BoundKind;
47
use rustc_ast::{
58
self as ast, GenericArg, GenericBound, GenericParamKind, ItemKind, MetaItem,
6-
TraitBoundModifiers, VariantData,
9+
TraitBoundModifiers, VariantData, WherePredicate,
710
};
811
use rustc_attr as attr;
12+
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
913
use rustc_expand::base::{Annotatable, ExtCtxt};
1014
use rustc_span::symbol::{sym, Ident};
11-
use rustc_span::Span;
15+
use rustc_span::{Span, Symbol};
1216
use smallvec::{smallvec, SmallVec};
1317
use thin_vec::{thin_vec, ThinVec};
1418

@@ -141,33 +145,239 @@ pub fn expand_deriving_smart_ptr(
141145
alt_self_params[pointee_param_idx] = GenericArg::Type(s_ty.clone());
142146
let alt_self_type = cx.ty_path(cx.path_all(span, false, vec![name_ident], alt_self_params));
143147

148+
// # Add `Unsize<__S>` bound to `#[pointee]` at the generic parameter location
149+
//
144150
// Find the `#[pointee]` parameter and add an `Unsize<__S>` bound to it.
145151
let mut impl_generics = generics.clone();
152+
let pointee_ty_ident = generics.params[pointee_param_idx].ident;
153+
let mut self_bounds;
146154
{
147-
let p = &mut impl_generics.params[pointee_param_idx];
155+
let pointee = &mut impl_generics.params[pointee_param_idx];
156+
self_bounds = pointee.bounds.clone();
148157
let arg = GenericArg::Type(s_ty.clone());
149158
let unsize = cx.path_all(span, true, path!(span, core::marker::Unsize), vec![arg]);
150-
p.bounds.push(cx.trait_bound(unsize, false));
159+
pointee.bounds.push(cx.trait_bound(unsize, false));
151160
let mut attrs = thin_vec![];
152-
swap(&mut p.attrs, &mut attrs);
153-
p.attrs = attrs.into_iter().filter(|attr| !attr.has_name(sym::pointee)).collect();
161+
swap(&mut pointee.attrs, &mut attrs);
162+
// Drop `#[pointee]` attribute since it should not be recognized outside `derive(SmartPointer)`
163+
pointee.attrs = attrs.into_iter().filter(|attr| !attr.has_name(sym::pointee)).collect();
154164
}
155165

156-
// Add the `__S: ?Sized` extra parameter to the impl block.
166+
// # Rewrite generic parameter bounds
167+
// For each bound `U: ..` in `struct<U: ..>`, make a new bound with `__S` in place of `#[pointee]`
168+
// Example:
169+
// ```
170+
// struct<
171+
// U: Trait<T>,
172+
// #[pointee] T: Trait<T>,
173+
// V: Trait<T>> ...
174+
// ```
175+
// ... generates this `impl` generic parameters
176+
// ```
177+
// impl<
178+
// U: Trait<T> + Trait<__S>,
179+
// T: Trait<T> + Unsize<__S>, // (**)
180+
// __S: Trait<__S> + ?Sized, // (*)
181+
// V: Trait<T> + Trait<__S>> ...
182+
// ```
183+
// The new bound marked with (*) has to be done separately.
184+
// See next section
185+
for (idx, (params, orig_params)) in
186+
impl_generics.params.iter_mut().zip(&generics.params).enumerate()
187+
{
188+
// Default type parameters are rejected for `impl` block.
189+
// We should drop them now.
190+
match &mut params.kind {
191+
ast::GenericParamKind::Const { default, .. } => *default = None,
192+
ast::GenericParamKind::Type { default } => *default = None,
193+
ast::GenericParamKind::Lifetime => {}
194+
}
195+
// We CANNOT rewrite `#[pointee]` type parameter bounds.
196+
// This has been set in stone. (**)
197+
// So we skip over it.
198+
// Otherwise, we push extra bounds involving `__S`.
199+
if idx != pointee_param_idx {
200+
for bound in &orig_params.bounds {
201+
let mut bound = bound.clone();
202+
let mut substitution = TypeSubstitution {
203+
from_name: pointee_ty_ident.name,
204+
to_ty: &s_ty,
205+
rewritten: false,
206+
};
207+
substitution.visit_param_bound(&mut bound, BoundKind::Bound);
208+
if substitution.rewritten {
209+
// We found use of `#[pointee]` somewhere,
210+
// so we make a new bound using `__S` in place of `#[pointee]`
211+
params.bounds.push(bound);
212+
}
213+
}
214+
}
215+
}
216+
217+
// # Insert `__S` type parameter
218+
//
219+
// We now insert `__S` with the missing bounds marked with (*) above.
220+
// We should also write the bounds from `#[pointee]` to `__S` as required by `Unsize<__S>`.
157221
let sized = cx.path_global(span, path!(span, core::marker::Sized));
158-
let bound = GenericBound::Trait(
159-
cx.poly_trait_ref(span, sized),
160-
TraitBoundModifiers {
161-
polarity: ast::BoundPolarity::Maybe(span),
162-
constness: ast::BoundConstness::Never,
163-
asyncness: ast::BoundAsyncness::Normal,
164-
},
165-
);
166-
let extra_param = cx.typaram(span, Ident::new(sym::__S, span), vec![bound], None);
167-
impl_generics.params.push(extra_param);
222+
// For some reason, we are not allowed to write `?Sized` bound twice like `__S: ?Sized + ?Sized`.
223+
if !contains_maybe_sized_bound(&self_bounds)
224+
&& !contains_maybe_sized_bound_on_pointee(
225+
&generics.where_clause.predicates,
226+
pointee_ty_ident.name,
227+
)
228+
{
229+
self_bounds.push(GenericBound::Trait(
230+
cx.poly_trait_ref(span, sized),
231+
TraitBoundModifiers {
232+
polarity: ast::BoundPolarity::Maybe(span),
233+
constness: ast::BoundConstness::Never,
234+
asyncness: ast::BoundAsyncness::Normal,
235+
},
236+
));
237+
}
238+
{
239+
let mut substitution =
240+
TypeSubstitution { from_name: pointee_ty_ident.name, to_ty: &s_ty, rewritten: false };
241+
for bound in &mut self_bounds {
242+
substitution.visit_param_bound(bound, BoundKind::Bound);
243+
}
244+
}
245+
246+
// # Rewrite `where` clauses
247+
//
248+
// Move on to `where` clauses.
249+
// Example:
250+
// ```
251+
// struct MyPointer<#[pointee] T, ..>
252+
// where
253+
// U: Trait<V> + Trait<T>,
254+
// Companion<T>: Trait<T>,
255+
// T: Trait<T>,
256+
// { .. }
257+
// ```
258+
// ... will have a impl prelude like so
259+
// ```
260+
// impl<..> ..
261+
// where
262+
// U: Trait<V> + Trait<T>,
263+
// U: Trait<__S>,
264+
// Companion<T>: Trait<T>,
265+
// Companion<__S>: Trait<__S>,
266+
// T: Trait<T>,
267+
// __S: Trait<__S>,
268+
// ```
269+
//
270+
// We should also write a few new `where` bounds from `#[pointee] T` to `__S`
271+
// as well as any bound that indirectly involves the `#[pointee] T` type.
272+
for bound in &generics.where_clause.predicates {
273+
if let ast::WherePredicate::BoundPredicate(bound) = bound {
274+
let mut substitution = TypeSubstitution {
275+
from_name: pointee_ty_ident.name,
276+
to_ty: &s_ty,
277+
rewritten: false,
278+
};
279+
let mut predicate = ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
280+
span: bound.span,
281+
bound_generic_params: bound.bound_generic_params.clone(),
282+
bounded_ty: bound.bounded_ty.clone(),
283+
bounds: bound.bounds.clone(),
284+
});
285+
substitution.visit_where_predicate(&mut predicate);
286+
if substitution.rewritten {
287+
impl_generics.where_clause.predicates.push(predicate);
288+
}
289+
}
290+
}
291+
292+
let extra_param = cx.typaram(span, Ident::new(sym::__S, span), self_bounds, None);
293+
impl_generics.params.insert(pointee_param_idx + 1, extra_param);
168294

169295
// Add the impl blocks for `DispatchFromDyn` and `CoerceUnsized`.
170296
let gen_args = vec![GenericArg::Type(alt_self_type.clone())];
171297
add_impl_block(impl_generics.clone(), sym::DispatchFromDyn, gen_args.clone());
172298
add_impl_block(impl_generics.clone(), sym::CoerceUnsized, gen_args.clone());
173299
}
300+
301+
fn contains_maybe_sized_bound_on_pointee(predicates: &[WherePredicate], pointee: Symbol) -> bool {
302+
for bound in predicates {
303+
if let ast::WherePredicate::BoundPredicate(bound) = bound
304+
&& bound.bounded_ty.kind.is_simple_path().is_some_and(|name| name == pointee)
305+
{
306+
for bound in &bound.bounds {
307+
if is_maybe_sized_bound(bound) {
308+
return true;
309+
}
310+
}
311+
}
312+
}
313+
false
314+
}
315+
316+
fn is_maybe_sized_bound(bound: &GenericBound) -> bool {
317+
if let GenericBound::Trait(
318+
trait_ref,
319+
TraitBoundModifiers { polarity: ast::BoundPolarity::Maybe(_), .. },
320+
) = bound
321+
{
322+
is_sized_marker(&trait_ref.trait_ref.path)
323+
} else {
324+
false
325+
}
326+
}
327+
328+
fn contains_maybe_sized_bound(bounds: &[GenericBound]) -> bool {
329+
bounds.iter().any(is_maybe_sized_bound)
330+
}
331+
332+
fn path_segment_is_exact_match(path_segments: &[ast::PathSegment], syms: &[Symbol]) -> bool {
333+
path_segments.iter().zip(syms).all(|(segment, &symbol)| segment.ident.name == symbol)
334+
}
335+
336+
fn is_sized_marker(path: &ast::Path) -> bool {
337+
const CORE_UNSIZE: [Symbol; 3] = [sym::core, sym::marker, sym::Sized];
338+
const STD_UNSIZE: [Symbol; 3] = [sym::std, sym::marker, sym::Sized];
339+
if path.segments.len() == 4 && path.is_global() {
340+
path_segment_is_exact_match(&path.segments[1..], &CORE_UNSIZE)
341+
|| path_segment_is_exact_match(&path.segments[1..], &STD_UNSIZE)
342+
} else if path.segments.len() == 3 {
343+
path_segment_is_exact_match(&path.segments, &CORE_UNSIZE)
344+
|| path_segment_is_exact_match(&path.segments, &STD_UNSIZE)
345+
} else {
346+
*path == sym::Sized
347+
}
348+
}
349+
350+
struct TypeSubstitution<'a> {
351+
from_name: Symbol,
352+
to_ty: &'a ast::Ty,
353+
rewritten: bool,
354+
}
355+
356+
impl<'a> ast::mut_visit::MutVisitor for TypeSubstitution<'a> {
357+
fn visit_ty(&mut self, ty: &mut P<ast::Ty>) {
358+
if let Some(name) = ty.kind.is_simple_path()
359+
&& name == self.from_name
360+
{
361+
**ty = self.to_ty.clone();
362+
self.rewritten = true;
363+
} else {
364+
ast::mut_visit::walk_ty(self, ty);
365+
}
366+
}
367+
368+
fn visit_where_predicate(&mut self, where_predicate: &mut ast::WherePredicate) {
369+
match where_predicate {
370+
rustc_ast::WherePredicate::BoundPredicate(bound) => {
371+
bound
372+
.bound_generic_params
373+
.flat_map_in_place(|param| self.flat_map_generic_param(param));
374+
self.visit_ty(&mut bound.bounded_ty);
375+
for bound in &mut bound.bounds {
376+
self.visit_param_bound(bound, BoundKind::Bound)
377+
}
378+
}
379+
rustc_ast::WherePredicate::RegionPredicate(_)
380+
| rustc_ast::WherePredicate::EqPredicate(_) => {}
381+
}
382+
}
383+
}

compiler/rustc_codegen_llvm/src/back/archive.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ impl<'a> ArchiveBuilder for LlvmArchiveBuilder<'a> {
9797
fn build(mut self: Box<Self>, output: &Path) -> bool {
9898
match self.build_with_llvm(output) {
9999
Ok(any_members) => any_members,
100-
Err(e) => self.sess.dcx().emit_fatal(ArchiveBuildFailure { error: e }),
100+
Err(error) => {
101+
self.sess.dcx().emit_fatal(ArchiveBuildFailure { path: output.to_owned(), error })
102+
}
101103
}
102104
}
103105
}

compiler/rustc_codegen_ssa/messages.ftl

+2-3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ codegen_ssa_add_native_library = failed to add native library {$library_path}: {
44
55
codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {$error}
66
7-
codegen_ssa_archive_build_failure =
8-
failed to build archive: {$error}
7+
codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$error}
98
109
codegen_ssa_atomic_compare_exchange = Atomic compare-exchange intrinsic missing failure memory ordering
1110
@@ -198,7 +197,7 @@ codegen_ssa_read_file = failed to read file: {$message}
198197
199198
codegen_ssa_repair_vs_build_tools = the Visual Studio build tools may need to be repaired using the Visual Studio installer
200199
201-
codegen_ssa_rlib_archive_build_failure = failed to build archive from rlib: {$error}
200+
codegen_ssa_rlib_archive_build_failure = failed to build archive from rlib at `{$path}`: {$error}
202201
203202
codegen_ssa_rlib_incompatible_dependency_formats = `{$ty1}` and `{$ty2}` do not have equivalent dependency formats (`{$list1}` vs `{$list2}`)
204203

compiler/rustc_codegen_ssa/src/back/archive.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,9 @@ impl<'a> ArchiveBuilder for ArArchiveBuilder<'a> {
207207
let sess = self.sess;
208208
match self.build_inner(output) {
209209
Ok(any_members) => any_members,
210-
Err(e) => sess.dcx().emit_fatal(ArchiveBuildFailure { error: e }),
210+
Err(error) => {
211+
sess.dcx().emit_fatal(ArchiveBuildFailure { path: output.to_owned(), error })
212+
}
211213
}
212214
}
213215
}

compiler/rustc_codegen_ssa/src/back/link.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2911,7 +2911,8 @@ fn add_static_crate(
29112911
false
29122912
}),
29132913
) {
2914-
sess.dcx().emit_fatal(errors::RlibArchiveBuildFailure { error });
2914+
sess.dcx()
2915+
.emit_fatal(errors::RlibArchiveBuildFailure { path: cratepath.clone(), error });
29152916
}
29162917
if archive.build(&dst) {
29172918
link_upstream(&dst);

compiler/rustc_codegen_ssa/src/errors.rs

+2
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,7 @@ pub struct UnableToWriteDebuggerVisualizer {
500500
#[derive(Diagnostic)]
501501
#[diag(codegen_ssa_rlib_archive_build_failure)]
502502
pub struct RlibArchiveBuildFailure {
503+
pub path: PathBuf,
503504
pub error: Error,
504505
}
505506

@@ -557,6 +558,7 @@ pub struct UnsupportedLinkSelfContained;
557558
#[diag(codegen_ssa_archive_build_failure)]
558559
// Public for rustc_codegen_llvm::back::archive
559560
pub struct ArchiveBuildFailure {
561+
pub path: PathBuf,
560562
pub error: std::io::Error,
561563
}
562564

compiler/rustc_interface/src/passes.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,13 @@ fn resolver_for_lowering_raw<'tcx>(
544544
let arenas = Resolver::arenas();
545545
let _ = tcx.registered_tools(()); // Uses `crate_for_resolver`.
546546
let (krate, pre_configured_attrs) = tcx.crate_for_resolver(()).steal();
547-
let mut resolver = Resolver::new(tcx, &pre_configured_attrs, krate.spans.inner_span, &arenas);
547+
let mut resolver = Resolver::new(
548+
tcx,
549+
&pre_configured_attrs,
550+
krate.spans.inner_span,
551+
krate.spans.inject_use_span,
552+
&arenas,
553+
);
548554
let krate = configure_and_expand(krate, &pre_configured_attrs, &mut resolver);
549555

550556
// Make sure we don't mutate the cstore from here on.

compiler/rustc_lint_defs/src/builtin.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1834,8 +1834,7 @@ declare_lint! {
18341834
/// [placeholder lifetime]: https://doc.rust-lang.org/reference/lifetime-elision.html#lifetime-elision-in-functions
18351835
pub ELIDED_LIFETIMES_IN_PATHS,
18361836
Allow,
1837-
"hidden lifetime parameters in types are deprecated",
1838-
crate_level_only
1837+
"hidden lifetime parameters in types are deprecated"
18391838
}
18401839

18411840
declare_lint! {

0 commit comments

Comments
 (0)