Skip to content

Commit 4fa13b8

Browse files
committed
Auto merge of #147139 - Zalathar:rollup-2r4qvkh, r=Zalathar
Rollup of 6 pull requests Successful merges: - #133477 (Detect tuple structs that are unconstructable due to re-export) - #140916 (Fix unuseful span in type error in some format_args!() invocations) - #146979 (constify Default on Nanoseconds) - #147090 (Skip stack overflow handler for panic=immediate-abort) - #147092 (Do not compute optimized MIR if code does not type-check.) - #147127 (Add a leading dash to linker plugin arguments in the gcc codegen) r? `@ghost` `@rustbot` modify labels: rollup
2 parents f957826 + 2cc598f commit 4fa13b8

File tree

27 files changed

+373
-164
lines changed

27 files changed

+373
-164
lines changed

compiler/rustc_codegen_cranelift/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,10 @@ impl CodegenBackend for CraneliftCodegenBackend {
165165
""
166166
}
167167

168+
fn name(&self) -> &'static str {
169+
"cranelift"
170+
}
171+
168172
fn init(&self, sess: &Session) {
169173
use rustc_session::config::{InstrumentCoverage, Lto};
170174
match sess.lto() {

compiler/rustc_codegen_gcc/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,10 @@ impl CodegenBackend for GccCodegenBackend {
184184
crate::DEFAULT_LOCALE_RESOURCE
185185
}
186186

187+
fn name(&self) -> &'static str {
188+
"gcc"
189+
}
190+
187191
fn init(&self, _sess: &Session) {
188192
#[cfg(feature = "master")]
189193
{

compiler/rustc_codegen_llvm/src/lib.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,10 @@ impl CodegenBackend for LlvmCodegenBackend {
232232
crate::DEFAULT_LOCALE_RESOURCE
233233
}
234234

235+
fn name(&self) -> &'static str {
236+
"llvm"
237+
}
238+
235239
fn init(&self, sess: &Session) {
236240
llvm_util::init(sess); // Make sure llvm is inited
237241
}
@@ -350,7 +354,14 @@ impl CodegenBackend for LlvmCodegenBackend {
350354

351355
// Run the linker on any artifacts that resulted from the LLVM run.
352356
// This should produce either a finished executable or library.
353-
link_binary(sess, &LlvmArchiveBuilderBuilder, codegen_results, metadata, outputs);
357+
link_binary(
358+
sess,
359+
&LlvmArchiveBuilderBuilder,
360+
codegen_results,
361+
metadata,
362+
outputs,
363+
self.name(),
364+
);
354365
}
355366
}
356367

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ pub fn link_binary(
7979
codegen_results: CodegenResults,
8080
metadata: EncodedMetadata,
8181
outputs: &OutputFilenames,
82+
codegen_backend: &'static str,
8283
) {
8384
let _timer = sess.timer("link_binary");
8485
let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata);
@@ -154,6 +155,7 @@ pub fn link_binary(
154155
&codegen_results,
155156
&metadata,
156157
path.as_ref(),
158+
codegen_backend,
157159
);
158160
}
159161
}
@@ -680,6 +682,7 @@ fn link_natively(
680682
codegen_results: &CodegenResults,
681683
metadata: &EncodedMetadata,
682684
tmpdir: &Path,
685+
codegen_backend: &'static str,
683686
) {
684687
info!("preparing {:?} to {:?}", crate_type, out_filename);
685688
let (linker_path, flavor) = linker_and_flavor(sess);
@@ -705,6 +708,7 @@ fn link_natively(
705708
codegen_results,
706709
metadata,
707710
self_contained_components,
711+
codegen_backend,
708712
);
709713

710714
linker::disable_localization(&mut cmd);
@@ -2208,6 +2212,7 @@ fn linker_with_args(
22082212
codegen_results: &CodegenResults,
22092213
metadata: &EncodedMetadata,
22102214
self_contained_components: LinkSelfContainedComponents,
2215+
codegen_backend: &'static str,
22112216
) -> Command {
22122217
let self_contained_crt_objects = self_contained_components.is_crt_objects_enabled();
22132218
let cmd = &mut *super::linker::get_linker(
@@ -2216,6 +2221,7 @@ fn linker_with_args(
22162221
flavor,
22172222
self_contained_components.are_any_components_enabled(),
22182223
&codegen_results.crate_info.target_cpu,
2224+
codegen_backend,
22192225
);
22202226
let link_output_kind = link_output_kind(sess, crate_type);
22212227

compiler/rustc_codegen_ssa/src/back/linker.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ pub(crate) fn get_linker<'a>(
5252
flavor: LinkerFlavor,
5353
self_contained: bool,
5454
target_cpu: &'a str,
55+
codegen_backend: &'static str,
5556
) -> Box<dyn Linker + 'a> {
5657
let msvc_tool = find_msvc_tools::find_tool(&sess.target.arch, "link.exe");
5758

@@ -154,6 +155,7 @@ pub(crate) fn get_linker<'a>(
154155
is_ld: cc == Cc::No,
155156
is_gnu: flavor.is_gnu(),
156157
uses_lld: flavor.uses_lld(),
158+
codegen_backend,
157159
}) as Box<dyn Linker>,
158160
LinkerFlavor::Msvc(..) => Box::new(MsvcLinker { cmd, sess }) as Box<dyn Linker>,
159161
LinkerFlavor::EmCc => Box::new(EmLinker { cmd, sess }) as Box<dyn Linker>,
@@ -367,6 +369,7 @@ struct GccLinker<'a> {
367369
is_ld: bool,
368370
is_gnu: bool,
369371
uses_lld: bool,
372+
codegen_backend: &'static str,
370373
}
371374

372375
impl<'a> GccLinker<'a> {
@@ -423,9 +426,15 @@ impl<'a> GccLinker<'a> {
423426
if let Some(path) = &self.sess.opts.unstable_opts.profile_sample_use {
424427
self.link_arg(&format!("-plugin-opt=sample-profile={}", path.display()));
425428
};
429+
let prefix = if self.codegen_backend == "gcc" {
430+
// The GCC linker plugin requires a leading dash.
431+
"-"
432+
} else {
433+
""
434+
};
426435
self.link_args(&[
427-
&format!("-plugin-opt={opt_level}"),
428-
&format!("-plugin-opt=mcpu={}", self.target_cpu),
436+
&format!("-plugin-opt={prefix}{opt_level}"),
437+
&format!("-plugin-opt={prefix}mcpu={}", self.target_cpu),
429438
]);
430439
}
431440

compiler/rustc_codegen_ssa/src/traits/backend.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ pub trait CodegenBackend {
4141
/// Called before `init` so that all other functions are able to emit translatable diagnostics.
4242
fn locale_resource(&self) -> &'static str;
4343

44+
fn name(&self) -> &'static str;
45+
4446
fn init(&self, _sess: &Session) {}
4547

4648
fn print(&self, _req: &PrintRequest, _out: &mut String, _sess: &Session) {}
@@ -96,7 +98,14 @@ pub trait CodegenBackend {
9698
metadata: EncodedMetadata,
9799
outputs: &OutputFilenames,
98100
) {
99-
link_binary(sess, &ArArchiveBuilderBuilder, codegen_results, metadata, outputs);
101+
link_binary(
102+
sess,
103+
&ArArchiveBuilderBuilder,
104+
codegen_results,
105+
metadata,
106+
outputs,
107+
self.name(),
108+
);
100109
}
101110
}
102111

compiler/rustc_interface/src/passes.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,18 +1122,6 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
11221122

11231123
sess.time("layout_testing", || layout_test::test_layout(tcx));
11241124
sess.time("abi_testing", || abi_test::test_abi(tcx));
1125-
1126-
// If `-Zvalidate-mir` is set, we also want to compute the final MIR for each item
1127-
// (either its `mir_for_ctfe` or `optimized_mir`) since that helps uncover any bugs
1128-
// in MIR optimizations that may only be reachable through codegen, or other codepaths
1129-
// that requires the optimized/ctfe MIR, coroutine bodies, or evaluating consts.
1130-
if tcx.sess.opts.unstable_opts.validate_mir {
1131-
sess.time("ensuring_final_MIR_is_computable", || {
1132-
tcx.par_hir_body_owners(|def_id| {
1133-
tcx.instance_mir(ty::InstanceKind::Item(def_id.into()));
1134-
});
1135-
});
1136-
}
11371125
}
11381126

11391127
/// Runs the type-checking, region checking and other miscellaneous analysis
@@ -1199,6 +1187,20 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) {
11991187
// we will fail to emit overlap diagnostics. Thus we invoke it here unconditionally.
12001188
let _ = tcx.all_diagnostic_items(());
12011189
});
1190+
1191+
// If `-Zvalidate-mir` is set, we also want to compute the final MIR for each item
1192+
// (either its `mir_for_ctfe` or `optimized_mir`) since that helps uncover any bugs
1193+
// in MIR optimizations that may only be reachable through codegen, or other codepaths
1194+
// that requires the optimized/ctfe MIR, coroutine bodies, or evaluating consts.
1195+
// Nevertheless, wait after type checking is finished, as optimizing code that does not
1196+
// type-check is very prone to ICEs.
1197+
if tcx.sess.opts.unstable_opts.validate_mir {
1198+
sess.time("ensuring_final_MIR_is_computable", || {
1199+
tcx.par_hir_body_owners(|def_id| {
1200+
tcx.instance_mir(ty::InstanceKind::Item(def_id.into()));
1201+
});
1202+
});
1203+
}
12021204
}
12031205

12041206
/// Runs the codegen backend, after which the AST and analysis can

compiler/rustc_resolve/src/ident.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
901901
binding,
902902
if resolution.non_glob_binding.is_some() { resolution.glob_binding } else { None },
903903
parent_scope,
904+
module,
904905
finalize,
905906
shadowing,
906907
);
@@ -1025,6 +1026,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
10251026
binding: Option<NameBinding<'ra>>,
10261027
shadowed_glob: Option<NameBinding<'ra>>,
10271028
parent_scope: &ParentScope<'ra>,
1029+
module: Module<'ra>,
10281030
finalize: Finalize,
10291031
shadowing: Shadowing,
10301032
) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
@@ -1076,6 +1078,37 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
10761078
self.macro_expanded_macro_export_errors.insert((path_span, binding.span));
10771079
}
10781080

1081+
// If we encounter a re-export for a type with private fields, it will not be able to
1082+
// be constructed through this re-export. We track that case here to expand later
1083+
// privacy errors with appropriate information.
1084+
if let Res::Def(_, def_id) = binding.res() {
1085+
let struct_ctor = match def_id.as_local() {
1086+
Some(def_id) => self.struct_constructors.get(&def_id).cloned(),
1087+
None => {
1088+
let ctor = self.cstore().ctor_untracked(def_id);
1089+
ctor.map(|(ctor_kind, ctor_def_id)| {
1090+
let ctor_res = Res::Def(
1091+
DefKind::Ctor(rustc_hir::def::CtorOf::Struct, ctor_kind),
1092+
ctor_def_id,
1093+
);
1094+
let ctor_vis = self.tcx.visibility(ctor_def_id);
1095+
let field_visibilities = self
1096+
.tcx
1097+
.associated_item_def_ids(def_id)
1098+
.iter()
1099+
.map(|field_id| self.tcx.visibility(field_id))
1100+
.collect();
1101+
(ctor_res, ctor_vis, field_visibilities)
1102+
})
1103+
}
1104+
};
1105+
if let Some((_, _, fields)) = struct_ctor
1106+
&& fields.iter().any(|vis| !self.is_accessible_from(*vis, module))
1107+
{
1108+
self.inaccessible_ctor_reexport.insert(path_span, binding.span);
1109+
}
1110+
}
1111+
10791112
self.record_use(ident, binding, used);
10801113
return Ok(binding);
10811114
}

compiler/rustc_resolve/src/late/diagnostics.rs

Lines changed: 66 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,44 +1942,77 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
19421942
return true;
19431943
};
19441944

1945+
let update_message =
1946+
|this: &mut Self, err: &mut Diag<'_>, source: &PathSource<'_, '_, '_>| {
1947+
match source {
1948+
// e.g. `if let Enum::TupleVariant(field1, field2) = _`
1949+
PathSource::TupleStruct(_, pattern_spans) => {
1950+
err.primary_message(
1951+
"cannot match against a tuple struct which contains private fields",
1952+
);
1953+
1954+
// Use spans of the tuple struct pattern.
1955+
Some(Vec::from(*pattern_spans))
1956+
}
1957+
// e.g. `let _ = Enum::TupleVariant(field1, field2);`
1958+
PathSource::Expr(Some(Expr {
1959+
kind: ExprKind::Call(path, args),
1960+
span: call_span,
1961+
..
1962+
})) => {
1963+
err.primary_message(
1964+
"cannot initialize a tuple struct which contains private fields",
1965+
);
1966+
this.suggest_alternative_construction_methods(
1967+
def_id,
1968+
err,
1969+
path.span,
1970+
*call_span,
1971+
&args[..],
1972+
);
1973+
// Use spans of the tuple struct definition.
1974+
this.r
1975+
.field_idents(def_id)
1976+
.map(|fields| fields.iter().map(|f| f.span).collect::<Vec<_>>())
1977+
}
1978+
_ => None,
1979+
}
1980+
};
19451981
let is_accessible = self.r.is_accessible_from(ctor_vis, self.parent_scope.module);
1982+
if let Some(use_span) = self.r.inaccessible_ctor_reexport.get(&span)
1983+
&& is_accessible
1984+
{
1985+
err.span_note(
1986+
*use_span,
1987+
"the type is accessed through this re-export, but the type's constructor \
1988+
is not visible in this import's scope due to private fields",
1989+
);
1990+
if is_accessible
1991+
&& fields
1992+
.iter()
1993+
.all(|vis| self.r.is_accessible_from(*vis, self.parent_scope.module))
1994+
{
1995+
err.span_suggestion_verbose(
1996+
span,
1997+
"the type can be constructed directly, because its fields are \
1998+
available from the current scope",
1999+
// Using `tcx.def_path_str` causes the compiler to hang.
2000+
// We don't need to handle foreign crate types because in that case you
2001+
// can't access the ctor either way.
2002+
format!(
2003+
"crate{}", // The method already has leading `::`.
2004+
self.r.tcx.def_path(def_id).to_string_no_crate_verbose(),
2005+
),
2006+
Applicability::MachineApplicable,
2007+
);
2008+
}
2009+
update_message(self, err, &source);
2010+
}
19462011
if !is_expected(ctor_def) || is_accessible {
19472012
return true;
19482013
}
19492014

1950-
let field_spans = match source {
1951-
// e.g. `if let Enum::TupleVariant(field1, field2) = _`
1952-
PathSource::TupleStruct(_, pattern_spans) => {
1953-
err.primary_message(
1954-
"cannot match against a tuple struct which contains private fields",
1955-
);
1956-
1957-
// Use spans of the tuple struct pattern.
1958-
Some(Vec::from(pattern_spans))
1959-
}
1960-
// e.g. `let _ = Enum::TupleVariant(field1, field2);`
1961-
PathSource::Expr(Some(Expr {
1962-
kind: ExprKind::Call(path, args),
1963-
span: call_span,
1964-
..
1965-
})) => {
1966-
err.primary_message(
1967-
"cannot initialize a tuple struct which contains private fields",
1968-
);
1969-
self.suggest_alternative_construction_methods(
1970-
def_id,
1971-
err,
1972-
path.span,
1973-
*call_span,
1974-
&args[..],
1975-
);
1976-
// Use spans of the tuple struct definition.
1977-
self.r
1978-
.field_idents(def_id)
1979-
.map(|fields| fields.iter().map(|f| f.span).collect::<Vec<_>>())
1980-
}
1981-
_ => None,
1982-
};
2015+
let field_spans = update_message(self, err, &source);
19832016

19842017
if let Some(spans) =
19852018
field_spans.filter(|spans| spans.len() > 0 && fields.len() == spans.len())

compiler/rustc_resolve/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,6 +1167,11 @@ pub struct Resolver<'ra, 'tcx> {
11671167
/// Crate-local macro expanded `macro_export` referred to by a module-relative path.
11681168
macro_expanded_macro_export_errors: BTreeSet<(Span, Span)> = BTreeSet::new(),
11691169

1170+
/// When a type is re-exported that has an inaccessible constructor because it has fields that
1171+
/// are inaccessible from the import's scope, we mark that as the type won't be able to be built
1172+
/// through the re-export. We use this information to extend the existing diagnostic.
1173+
inaccessible_ctor_reexport: FxHashMap<Span, Span>,
1174+
11701175
arenas: &'ra ResolverArenas<'ra>,
11711176
dummy_binding: NameBinding<'ra>,
11721177
builtin_types_bindings: FxHashMap<Symbol, NameBinding<'ra>>,
@@ -1595,6 +1600,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
15951600
glob_map: Default::default(),
15961601
used_imports: FxHashSet::default(),
15971602
maybe_unused_trait_imports: Default::default(),
1603+
inaccessible_ctor_reexport: Default::default(),
15981604

15991605
arenas,
16001606
dummy_binding: arenas.new_pub_res_binding(Res::Err, DUMMY_SP, LocalExpnId::ROOT),

0 commit comments

Comments
 (0)