Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 14445aa

Browse files
committedJan 26, 2025·
Auto merge of rust-lang#136017 - cuviper:beta-next, r=cuviper
[beta] backports - Always force non-trimming of path in `unreachable_patterns` lint rust-lang#135310 - Add Profile Override for Non-Git Sources rust-lang#135433 - resolve symlinks of LLVM tool binaries before copying them rust-lang#135585 - add cache to `AmbiguityCausesVisitor` rust-lang#135618 - When LLVM's location discriminator value limit is exceeded, emit locations with dummy spans instead of dropping them entirely rust-lang#135643 - make it possible to use ci-rustc on tarball sources rust-lang#135722 - Remove test panic from File::open rust-lang#135837 - Only assert the `Parser` size on specific arches rust-lang#135855 - [beta] TRPL: more backward-compatible Edition changes rust-lang#135843 r? cuviper
2 parents 4416507 + 130f951 commit 14445aa

File tree

21 files changed

+276
-112
lines changed

21 files changed

+276
-112
lines changed
 

‎compiler/rustc_codegen_gcc/src/debuginfo.rs‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,15 @@ fn make_mir_scope<'gcc, 'tcx>(
113113
let scope_data = &mir.source_scopes[scope];
114114
let parent_scope = if let Some(parent) = scope_data.parent_scope {
115115
make_mir_scope(cx, _instance, mir, variables, debug_context, instantiated, parent);
116-
debug_context.scopes[parent].unwrap()
116+
debug_context.scopes[parent]
117117
} else {
118118
// The root is the function itself.
119119
let file = cx.sess().source_map().lookup_source_file(mir.span.lo());
120-
debug_context.scopes[scope] = Some(DebugScope {
120+
debug_context.scopes[scope] = DebugScope {
121121
file_start_pos: file.start_pos,
122122
file_end_pos: file.end_position(),
123-
..debug_context.scopes[scope].unwrap()
124-
});
123+
..debug_context.scopes[scope]
124+
};
125125
instantiated.insert(scope);
126126
return;
127127
};
@@ -130,7 +130,7 @@ fn make_mir_scope<'gcc, 'tcx>(
130130
if !vars.contains(scope) && scope_data.inlined.is_none() {
131131
// Do not create a DIScope if there are no variables defined in this
132132
// MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat.
133-
debug_context.scopes[scope] = Some(parent_scope);
133+
debug_context.scopes[scope] = parent_scope;
134134
instantiated.insert(scope);
135135
return;
136136
}
@@ -157,12 +157,12 @@ fn make_mir_scope<'gcc, 'tcx>(
157157
// TODO(tempdragon): dbg_scope: Add support for scope extension here.
158158
inlined_at.or(p_inlined_at);
159159

160-
debug_context.scopes[scope] = Some(DebugScope {
160+
debug_context.scopes[scope] = DebugScope {
161161
dbg_scope,
162162
inlined_at,
163163
file_start_pos: loc.file.start_pos,
164164
file_end_pos: loc.file.end_position(),
165-
});
165+
};
166166
instantiated.insert(scope);
167167
}
168168

@@ -232,12 +232,12 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
232232
}
233233

234234
// Initialize fn debug context (including scopes).
235-
let empty_scope = Some(DebugScope {
235+
let empty_scope = DebugScope {
236236
dbg_scope: self.dbg_scope_fn(instance, fn_abi, Some(llfn)),
237237
inlined_at: None,
238238
file_start_pos: BytePos(0),
239239
file_end_pos: BytePos(0),
240-
});
240+
};
241241
let mut fn_debug_context = FunctionDebugContext {
242242
scopes: IndexVec::from_elem(empty_scope, mir.source_scopes.as_slice()),
243243
inlined_function_scopes: Default::default(),

‎compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs‎

Lines changed: 22 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_middle::mir::{Body, SourceScope};
99
use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv};
1010
use rustc_middle::ty::{self, Instance};
1111
use rustc_session::config::DebugInfo;
12-
use rustc_span::{BytePos, hygiene};
12+
use rustc_span::{BytePos, DUMMY_SP, hygiene};
1313

1414
use super::metadata::file_metadata;
1515
use super::utils::DIB;
@@ -85,23 +85,15 @@ fn make_mir_scope<'ll, 'tcx>(
8585
discriminators,
8686
parent,
8787
);
88-
if let Some(parent_scope) = debug_context.scopes[parent] {
89-
parent_scope
90-
} else {
91-
// If the parent scope could not be represented then no children
92-
// can be either.
93-
debug_context.scopes[scope] = None;
94-
instantiated.insert(scope);
95-
return;
96-
}
88+
debug_context.scopes[parent]
9789
} else {
9890
// The root is the function itself.
9991
let file = cx.sess().source_map().lookup_source_file(mir.span.lo());
100-
debug_context.scopes[scope] = Some(DebugScope {
92+
debug_context.scopes[scope] = DebugScope {
10193
file_start_pos: file.start_pos,
10294
file_end_pos: file.end_position(),
103-
..debug_context.scopes[scope].unwrap()
104-
});
95+
..debug_context.scopes[scope]
96+
};
10597
instantiated.insert(scope);
10698
return;
10799
};
@@ -112,7 +104,7 @@ fn make_mir_scope<'ll, 'tcx>(
112104
{
113105
// Do not create a DIScope if there are no variables defined in this
114106
// MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat.
115-
debug_context.scopes[scope] = Some(parent_scope);
107+
debug_context.scopes[scope] = parent_scope;
116108
instantiated.insert(scope);
117109
return;
118110
}
@@ -145,14 +137,7 @@ fn make_mir_scope<'ll, 'tcx>(
145137
},
146138
};
147139

148-
let mut debug_scope = Some(DebugScope {
149-
dbg_scope,
150-
inlined_at: parent_scope.inlined_at,
151-
file_start_pos: loc.file.start_pos,
152-
file_end_pos: loc.file.end_position(),
153-
});
154-
155-
if let Some((_, callsite_span)) = scope_data.inlined {
140+
let inlined_at = scope_data.inlined.map(|(_, callsite_span)| {
156141
let callsite_span = hygiene::walk_chain_collapsed(callsite_span, mir.span);
157142
let callsite_scope = parent_scope.adjust_dbg_scope_for_span(cx, callsite_span);
158143
let loc = cx.dbg_loc(callsite_scope, parent_scope.inlined_at, callsite_span);
@@ -175,29 +160,29 @@ fn make_mir_scope<'ll, 'tcx>(
175160
// Note further that we can't key this hashtable on the span itself,
176161
// because these spans could have distinct SyntaxContexts. We have
177162
// to key on exactly what we're giving to LLVM.
178-
let inlined_at = match discriminators.entry(callsite_span.lo()) {
163+
match discriminators.entry(callsite_span.lo()) {
179164
Entry::Occupied(mut o) => {
180165
*o.get_mut() += 1;
166+
// NB: We have to emit *something* here or we'll fail LLVM IR verification
167+
// in at least some circumstances (see issue #135322) so if the required
168+
// discriminant cannot be encoded fall back to the dummy location.
181169
unsafe { llvm::LLVMRustDILocationCloneWithBaseDiscriminator(loc, *o.get()) }
170+
.unwrap_or_else(|| {
171+
cx.dbg_loc(callsite_scope, parent_scope.inlined_at, DUMMY_SP)
172+
})
182173
}
183174
Entry::Vacant(v) => {
184175
v.insert(0);
185-
Some(loc)
186-
}
187-
};
188-
match inlined_at {
189-
Some(inlined_at) => {
190-
debug_scope.as_mut().unwrap().inlined_at = Some(inlined_at);
191-
}
192-
None => {
193-
// LLVM has a maximum discriminator that it can encode (currently
194-
// it uses 12 bits for 4096 possible values). If we exceed that
195-
// there is little we can do but drop the debug info.
196-
debug_scope = None;
176+
loc
197177
}
198178
}
199-
}
179+
});
200180

201-
debug_context.scopes[scope] = debug_scope;
181+
debug_context.scopes[scope] = DebugScope {
182+
dbg_scope,
183+
inlined_at: inlined_at.or(parent_scope.inlined_at),
184+
file_start_pos: loc.file.start_pos,
185+
file_end_pos: loc.file.end_position(),
186+
};
202187
instantiated.insert(scope);
203188
}

‎compiler/rustc_codegen_llvm/src/debuginfo/mod.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,12 +293,12 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
293293
}
294294

295295
// Initialize fn debug context (including scopes).
296-
let empty_scope = Some(DebugScope {
296+
let empty_scope = DebugScope {
297297
dbg_scope: self.dbg_scope_fn(instance, fn_abi, Some(llfn)),
298298
inlined_at: None,
299299
file_start_pos: BytePos(0),
300300
file_end_pos: BytePos(0),
301-
});
301+
};
302302
let mut fn_debug_context = FunctionDebugContext {
303303
scopes: IndexVec::from_elem(empty_scope, &mir.source_scopes),
304304
inlined_function_scopes: Default::default(),

‎compiler/rustc_codegen_ssa/src/mir/debuginfo.rs‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@ use crate::traits::*;
1919

2020
pub struct FunctionDebugContext<'tcx, S, L> {
2121
/// Maps from source code to the corresponding debug info scope.
22-
/// May be None if the backend is not capable of representing the scope for
23-
/// some reason.
24-
pub scopes: IndexVec<mir::SourceScope, Option<DebugScope<S, L>>>,
22+
pub scopes: IndexVec<mir::SourceScope, DebugScope<S, L>>,
2523

2624
/// Maps from an inlined function to its debug info declaration.
2725
pub inlined_function_scopes: FxHashMap<Instance<'tcx>, S>,
@@ -232,7 +230,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
232230
&self,
233231
source_info: mir::SourceInfo,
234232
) -> Option<(Bx::DIScope, Option<Bx::DILocation>, Span)> {
235-
let scope = &self.debug_context.as_ref()?.scopes[source_info.scope]?;
233+
let scope = &self.debug_context.as_ref()?.scopes[source_info.scope];
236234
let span = hygiene::walk_chain_collapsed(source_info.span, self.mir.span);
237235
Some((scope.adjust_dbg_scope_for_span(self.cx, span), scope.inlined_at, span))
238236
}

‎compiler/rustc_mir_build/src/thir/pattern/check_match.rs‎

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,14 +1086,7 @@ fn find_fallback_pattern_typo<'tcx>(
10861086
let vis = cx.tcx.visibility(item.owner_id);
10871087
if vis.is_accessible_from(parent, cx.tcx) {
10881088
accessible.push(item_name);
1089-
let path = if item_name == name {
1090-
// We know that the const wasn't in scope because it has the exact
1091-
// same name, so we suggest the full path.
1092-
with_no_trimmed_paths!(cx.tcx.def_path_str(item.owner_id))
1093-
} else {
1094-
// The const is likely just typoed, and nothing else.
1095-
cx.tcx.def_path_str(item.owner_id)
1096-
};
1089+
let path = with_no_trimmed_paths!(cx.tcx.def_path_str(item.owner_id));
10971090
accessible_path.push(path);
10981091
} else if name == item_name {
10991092
// The const exists somewhere in this crate, but it can't be imported

‎compiler/rustc_parse/src/parser/mod.rs‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,9 @@ pub struct Parser<'a> {
189189
}
190190

191191
// This type is used a lot, e.g. it's cloned when matching many declarative macro rules with
192-
// nonterminals. Make sure it doesn't unintentionally get bigger.
193-
#[cfg(all(target_pointer_width = "64", not(target_arch = "s390x")))]
192+
// nonterminals. Make sure it doesn't unintentionally get bigger. We only check a few arches
193+
// though, because `TokenTypeSet(u128)` alignment varies on others, changing the total size.
194+
#[cfg(all(target_pointer_width = "64", any(target_arch = "aarch64", target_arch = "x86_64")))]
194195
rustc_data_structures::static_assert_size!(Parser<'_>, 288);
195196

196197
/// Stores span information about a closure.

‎compiler/rustc_trait_selection/src/traits/coherence.rs‎

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
77
use std::fmt::Debug;
88

9-
use rustc_data_structures::fx::FxIndexSet;
9+
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
1010
use rustc_errors::{Diag, EmissionGuarantee};
1111
use rustc_hir::def::DefKind;
1212
use rustc_hir::def_id::DefId;
@@ -116,28 +116,39 @@ pub fn overlapping_impls(
116116
return None;
117117
}
118118

119-
let _overlap_with_bad_diagnostics = overlap(
120-
tcx,
121-
TrackAmbiguityCauses::No,
122-
skip_leak_check,
123-
impl1_def_id,
124-
impl2_def_id,
125-
overlap_mode,
126-
)?;
127-
128-
// In the case where we detect an error, run the check again, but
129-
// this time tracking intercrate ambiguity causes for better
130-
// diagnostics. (These take time and can lead to false errors.)
131-
let overlap = overlap(
132-
tcx,
133-
TrackAmbiguityCauses::Yes,
134-
skip_leak_check,
135-
impl1_def_id,
136-
impl2_def_id,
137-
overlap_mode,
138-
)
139-
.unwrap();
140-
Some(overlap)
119+
if tcx.next_trait_solver_in_coherence() {
120+
overlap(
121+
tcx,
122+
TrackAmbiguityCauses::Yes,
123+
skip_leak_check,
124+
impl1_def_id,
125+
impl2_def_id,
126+
overlap_mode,
127+
)
128+
} else {
129+
let _overlap_with_bad_diagnostics = overlap(
130+
tcx,
131+
TrackAmbiguityCauses::No,
132+
skip_leak_check,
133+
impl1_def_id,
134+
impl2_def_id,
135+
overlap_mode,
136+
)?;
137+
138+
// In the case where we detect an error, run the check again, but
139+
// this time tracking intercrate ambiguity causes for better
140+
// diagnostics. (These take time and can lead to false errors.)
141+
let overlap = overlap(
142+
tcx,
143+
TrackAmbiguityCauses::Yes,
144+
skip_leak_check,
145+
impl1_def_id,
146+
impl2_def_id,
147+
overlap_mode,
148+
)
149+
.unwrap();
150+
Some(overlap)
151+
}
141152
}
142153

143154
fn fresh_impl_header<'tcx>(infcx: &InferCtxt<'tcx>, impl_def_id: DefId) -> ty::ImplHeader<'tcx> {
@@ -615,6 +626,7 @@ fn compute_intercrate_ambiguity_causes<'tcx>(
615626
}
616627

617628
struct AmbiguityCausesVisitor<'a, 'tcx> {
629+
cache: FxHashSet<Goal<'tcx, ty::Predicate<'tcx>>>,
618630
causes: &'a mut FxIndexSet<IntercrateAmbiguityCause<'tcx>>,
619631
}
620632

@@ -624,6 +636,10 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
624636
}
625637

626638
fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) {
639+
if !self.cache.insert(goal.goal()) {
640+
return;
641+
}
642+
627643
let infcx = goal.infcx();
628644
for cand in goal.candidates() {
629645
cand.visit_nested_in_probe(self);
@@ -748,5 +764,10 @@ fn search_ambiguity_causes<'tcx>(
748764
goal: Goal<'tcx, ty::Predicate<'tcx>>,
749765
causes: &mut FxIndexSet<IntercrateAmbiguityCause<'tcx>>,
750766
) {
751-
infcx.probe(|_| infcx.visit_proof_tree(goal, &mut AmbiguityCausesVisitor { causes }));
767+
infcx.probe(|_| {
768+
infcx.visit_proof_tree(goal, &mut AmbiguityCausesVisitor {
769+
cache: Default::default(),
770+
causes,
771+
})
772+
});
752773
}

‎library/std/src/sys/pal/windows/fs.rs‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,9 +328,6 @@ impl File {
328328
mem::size_of::<c::FILE_ALLOCATION_INFO>() as u32,
329329
);
330330
if result == 0 {
331-
if api::get_last_error().code != 0 {
332-
panic!("FILE_ALLOCATION_INFO failed!!!");
333-
}
334331
let eof = c::FILE_END_OF_FILE_INFO { EndOfFile: 0 };
335332
let result = c::SetFileInformationByHandle(
336333
handle.as_raw_handle(),

‎src/bootstrap/bootstrap.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,6 +1264,11 @@ def bootstrap(args):
12641264
config_toml = ""
12651265

12661266
profile = RustBuild.get_toml_static(config_toml, "profile")
1267+
is_non_git_source = not os.path.exists(os.path.join(rust_root, ".git"))
1268+
1269+
if profile is None and is_non_git_source:
1270+
profile = "dist"
1271+
12671272
if profile is not None:
12681273
# Allows creating alias for profile names, allowing
12691274
# profiles to be renamed while maintaining back compatibility

‎src/bootstrap/src/core/build_steps/compile.rs‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1790,7 +1790,13 @@ impl Step for Assemble {
17901790
// When using `download-ci-llvm`, some of the tools
17911791
// may not exist, so skip trying to copy them.
17921792
if src_path.exists() {
1793-
builder.copy_link(&src_path, &libdir_bin.join(&tool_exe));
1793+
// There is a chance that these tools are being installed from an external LLVM.
1794+
// Use `Builder::resolve_symlink_and_copy` instead of `Builder::copy_link` to ensure
1795+
// we are copying the original file not the symlinked path, which causes issues for
1796+
// tarball distribution.
1797+
//
1798+
// See https://github.com/rust-lang/rust/issues/135554.
1799+
builder.resolve_symlink_and_copy(&src_path, &libdir_bin.join(&tool_exe));
17941800
}
17951801
}
17961802
}

‎src/bootstrap/src/core/config/config.rs‎

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2863,21 +2863,26 @@ impl Config {
28632863
allowed_paths.push(":!library");
28642864
}
28652865

2866-
// Look for a version to compare to based on the current commit.
2867-
// Only commits merged by bors will have CI artifacts.
2868-
let commit = match self.last_modified_commit(&allowed_paths, "download-rustc", if_unchanged)
2869-
{
2870-
Some(commit) => commit,
2871-
None => {
2872-
if if_unchanged {
2873-
return None;
2866+
let commit = if self.rust_info.is_managed_git_subrepository() {
2867+
// Look for a version to compare to based on the current commit.
2868+
// Only commits merged by bors will have CI artifacts.
2869+
match self.last_modified_commit(&allowed_paths, "download-rustc", if_unchanged) {
2870+
Some(commit) => commit,
2871+
None => {
2872+
if if_unchanged {
2873+
return None;
2874+
}
2875+
println!("ERROR: could not find commit hash for downloading rustc");
2876+
println!("HELP: maybe your repository history is too shallow?");
2877+
println!("HELP: consider setting `rust.download-rustc=false` in config.toml");
2878+
println!("HELP: or fetch enough history to include one upstream commit");
2879+
crate::exit!(1);
28742880
}
2875-
println!("ERROR: could not find commit hash for downloading rustc");
2876-
println!("HELP: maybe your repository history is too shallow?");
2877-
println!("HELP: consider setting `rust.download-rustc=false` in config.toml");
2878-
println!("HELP: or fetch enough history to include one upstream commit");
2879-
crate::exit!(1);
28802881
}
2882+
} else {
2883+
channel::read_commit_info_file(&self.src)
2884+
.map(|info| info.sha.trim().to_owned())
2885+
.expect("git-commit-info is missing in the project root")
28812886
};
28822887

28832888
if CiEnv::is_ci() && {
@@ -2914,10 +2919,8 @@ impl Config {
29142919
let if_unchanged = || {
29152920
if self.rust_info.is_from_tarball() {
29162921
// Git is needed for running "if-unchanged" logic.
2917-
println!(
2918-
"WARNING: 'if-unchanged' has no effect on tarball sources; ignoring `download-ci-llvm`."
2919-
);
2920-
return false;
2922+
println!("ERROR: 'if-unchanged' is only compatible with Git managed sources.");
2923+
crate::exit!(1);
29212924
}
29222925

29232926
// Fetching the LLVM submodule is unnecessary for self-tests.
@@ -2959,6 +2962,11 @@ impl Config {
29592962
option_name: &str,
29602963
if_unchanged: bool,
29612964
) -> Option<String> {
2965+
assert!(
2966+
self.rust_info.is_managed_git_subrepository(),
2967+
"Can't run `Config::last_modified_commit` on a non-git source."
2968+
);
2969+
29622970
// Look for a version to compare to based on the current commit.
29632971
// Only commits merged by bors will have CI artifacts.
29642972
let commit = get_closest_merge_commit(Some(&self.src), &self.git_config(), &[]).unwrap();

‎src/bootstrap/src/lib.rs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1657,6 +1657,14 @@ Executed at: {executed_at}"#,
16571657
paths
16581658
}
16591659

1660+
/// Copies a file from `src` to `dst`.
1661+
///
1662+
/// If `src` is a symlink, `src` will be resolved to the actual path
1663+
/// and copied to `dst` instead of the symlink itself.
1664+
pub fn resolve_symlink_and_copy(&self, src: &Path, dst: &Path) {
1665+
self.copy_link_internal(src, dst, true);
1666+
}
1667+
16601668
/// Links a file from `src` to `dst`.
16611669
/// Attempts to use hard links if possible, falling back to copying.
16621670
/// You can neither rely on this being a copy nor it being a link,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
other::big_function();
3+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
proc::declare_big_function!();
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
extern crate proc_macro;
2+
use proc_macro::TokenStream;
3+
4+
#[proc_macro]
5+
pub fn declare_big_function(_input: TokenStream) -> TokenStream {
6+
include_str!("./generated.rs").parse().unwrap()
7+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//! Regression test for <https://github.com/rust-lang/rust/issues/135332>.
2+
//!
3+
//! We can't simply drop debuginfo location spans when LLVM's location discriminator value limit is
4+
//! reached. Otherwise, with `-Z verify-llvm-ir` and fat LTO, LLVM will report a broken module for
5+
//!
6+
//! ```text
7+
//! inlinable function call in a function with debug info must have a !dbg location
8+
//! ```
9+
10+
//@ ignore-cross-compile
11+
//@ needs-dynamic-linking
12+
//@ only-nightly (requires unstable rustc flag)
13+
14+
#![deny(warnings)]
15+
16+
use run_make_support::{dynamic_lib_name, rfs, rust_lib_name, rustc};
17+
18+
// Synthesize a function that will have a large (`n`) number of functions
19+
// MIR-inlined into it. When combined with a proc-macro, all of these inline
20+
// callsites will have the same span, forcing rustc to use the DWARF
21+
// discriminator to distinguish between them. LLVM's capacity to store that
22+
// discriminator is not infinite (currently it allocates 12 bits for a
23+
// maximum value of 4096) so if this function gets big enough rustc's error
24+
// handling path will be exercised.
25+
fn generate_program(n: u32) -> String {
26+
let mut program = String::from("pub type BigType = Vec<Vec<String>>;\n\n");
27+
program.push_str("pub fn big_function() -> BigType {\n");
28+
program.push_str(" vec![\n");
29+
for i in 1..=n {
30+
program.push_str(&format!("vec![\"string{}\".to_owned()],\n", i));
31+
}
32+
program.push_str(" ]\n");
33+
program.push_str("}\n");
34+
program
35+
}
36+
37+
fn main() {
38+
// The reported threshold is around 1366 (4096/3), but let's bump it to
39+
// around 1500 to be less sensitive.
40+
rfs::write("generated.rs", generate_program(1500));
41+
42+
rustc()
43+
.input("proc.rs")
44+
.crate_type("proc-macro")
45+
.edition("2021")
46+
.arg("-Cdebuginfo=line-tables-only")
47+
.run();
48+
rustc()
49+
.extern_("proc", dynamic_lib_name("proc"))
50+
.input("other.rs")
51+
.crate_type("rlib")
52+
.edition("2021")
53+
.opt_level("3")
54+
.arg("-Cdebuginfo=line-tables-only")
55+
.run();
56+
rustc()
57+
.extern_("other", rust_lib_name("other"))
58+
.input("main.rs")
59+
.edition("2021")
60+
.opt_level("3")
61+
.arg("-Cdebuginfo=line-tables-only")
62+
.arg("-Clto=fat")
63+
.arg("-Zverify-llvm-ir")
64+
.run();
65+
}

‎tests/ui/coherence/occurs-check/associated-type.next.stderr‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
22
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
3-
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
4-
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
53
error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())`
64
--> $DIR/associated-type.rs:32:1
75
|

‎tests/ui/coherence/occurs-check/associated-type.old.stderr‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
22
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
3-
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
4-
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
53
error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())`
64
--> $DIR/associated-type.rs:32:1
75
|
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Computing the ambiguity causes for the overlap ended up
2+
// causing an exponential blowup when recursing into the normalization
3+
// goals for `<Box<?t> as RecursiveSuper>::Assoc`. This test
4+
// takes multiple minutes when doing so and less than a second
5+
// otherwise.
6+
7+
//@ compile-flags: -Znext-solver=coherence
8+
9+
trait RecursiveSuper:
10+
Super<
11+
A0 = Self::Assoc,
12+
A1 = Self::Assoc,
13+
A2 = Self::Assoc,
14+
A3 = Self::Assoc,
15+
A4 = Self::Assoc,
16+
A5 = Self::Assoc,
17+
A6 = Self::Assoc,
18+
A7 = Self::Assoc,
19+
A8 = Self::Assoc,
20+
A9 = Self::Assoc,
21+
A10 = Self::Assoc,
22+
A11 = Self::Assoc,
23+
A12 = Self::Assoc,
24+
A13 = Self::Assoc,
25+
A14 = Self::Assoc,
26+
A15 = Self::Assoc,
27+
>
28+
{
29+
type Assoc;
30+
}
31+
32+
trait Super {
33+
type A0;
34+
type A1;
35+
type A2;
36+
type A3;
37+
type A4;
38+
type A5;
39+
type A6;
40+
type A7;
41+
type A8;
42+
type A9;
43+
type A10;
44+
type A11;
45+
type A12;
46+
type A13;
47+
type A14;
48+
type A15;
49+
}
50+
51+
trait Overlap {}
52+
impl<T: RecursiveSuper> Overlap for T {}
53+
impl<T> Overlap for Box<T> {}
54+
//~^ ERROR conflicting implementations of trait `Overlap` for type `Box<_>`
55+
56+
fn main() {}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0119]: conflicting implementations of trait `Overlap` for type `Box<_>`
2+
--> $DIR/ambiguity-causes-visitor-hang.rs:53:1
3+
|
4+
LL | impl<T: RecursiveSuper> Overlap for T {}
5+
| ------------------------------------- first implementation here
6+
LL | impl<T> Overlap for Box<T> {}
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>`
8+
|
9+
= note: downstream crates may implement trait `Super` for type `std::boxed::Box<_>`
10+
= note: downstream crates may implement trait `RecursiveSuper` for type `std::boxed::Box<_>`
11+
12+
error: aborting due to 1 previous error
13+
14+
For more information about this error, try `rustc --explain E0119`.

0 commit comments

Comments
 (0)
This repository has been archived.