mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-29 20:46:07 +03:00
Auto merge of #136017 - cuviper:beta-next, r=cuviper
[beta] backports - Always force non-trimming of path in `unreachable_patterns` lint #135310 - Add Profile Override for Non-Git Sources #135433 - resolve symlinks of LLVM tool binaries before copying them #135585 - add cache to `AmbiguityCausesVisitor` #135618 - When LLVM's location discriminator value limit is exceeded, emit locations with dummy spans instead of dropping them entirely #135643 - make it possible to use ci-rustc on tarball sources #135722 - Remove test panic from File::open #135837 - Only assert the `Parser` size on specific arches #135855 - [beta] TRPL: more backward-compatible Edition changes #135843 r? cuviper
This commit is contained in:
@@ -113,15 +113,15 @@ fn make_mir_scope<'gcc, 'tcx>(
|
||||
let scope_data = &mir.source_scopes[scope];
|
||||
let parent_scope = if let Some(parent) = scope_data.parent_scope {
|
||||
make_mir_scope(cx, _instance, mir, variables, debug_context, instantiated, parent);
|
||||
debug_context.scopes[parent].unwrap()
|
||||
debug_context.scopes[parent]
|
||||
} else {
|
||||
// The root is the function itself.
|
||||
let file = cx.sess().source_map().lookup_source_file(mir.span.lo());
|
||||
debug_context.scopes[scope] = Some(DebugScope {
|
||||
debug_context.scopes[scope] = DebugScope {
|
||||
file_start_pos: file.start_pos,
|
||||
file_end_pos: file.end_position(),
|
||||
..debug_context.scopes[scope].unwrap()
|
||||
});
|
||||
..debug_context.scopes[scope]
|
||||
};
|
||||
instantiated.insert(scope);
|
||||
return;
|
||||
};
|
||||
@@ -130,7 +130,7 @@ fn make_mir_scope<'gcc, 'tcx>(
|
||||
if !vars.contains(scope) && scope_data.inlined.is_none() {
|
||||
// Do not create a DIScope if there are no variables defined in this
|
||||
// MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat.
|
||||
debug_context.scopes[scope] = Some(parent_scope);
|
||||
debug_context.scopes[scope] = parent_scope;
|
||||
instantiated.insert(scope);
|
||||
return;
|
||||
}
|
||||
@@ -157,12 +157,12 @@ fn make_mir_scope<'gcc, 'tcx>(
|
||||
// TODO(tempdragon): dbg_scope: Add support for scope extension here.
|
||||
inlined_at.or(p_inlined_at);
|
||||
|
||||
debug_context.scopes[scope] = Some(DebugScope {
|
||||
debug_context.scopes[scope] = DebugScope {
|
||||
dbg_scope,
|
||||
inlined_at,
|
||||
file_start_pos: loc.file.start_pos,
|
||||
file_end_pos: loc.file.end_position(),
|
||||
});
|
||||
};
|
||||
instantiated.insert(scope);
|
||||
}
|
||||
|
||||
@@ -232,12 +232,12 @@ fn create_function_debug_context(
|
||||
}
|
||||
|
||||
// Initialize fn debug context (including scopes).
|
||||
let empty_scope = Some(DebugScope {
|
||||
let empty_scope = DebugScope {
|
||||
dbg_scope: self.dbg_scope_fn(instance, fn_abi, Some(llfn)),
|
||||
inlined_at: None,
|
||||
file_start_pos: BytePos(0),
|
||||
file_end_pos: BytePos(0),
|
||||
});
|
||||
};
|
||||
let mut fn_debug_context = FunctionDebugContext {
|
||||
scopes: IndexVec::from_elem(empty_scope, mir.source_scopes.as_slice()),
|
||||
inlined_function_scopes: Default::default(),
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv};
|
||||
use rustc_middle::ty::{self, Instance};
|
||||
use rustc_session::config::DebugInfo;
|
||||
use rustc_span::{BytePos, hygiene};
|
||||
use rustc_span::{BytePos, DUMMY_SP, hygiene};
|
||||
|
||||
use super::metadata::file_metadata;
|
||||
use super::utils::DIB;
|
||||
@@ -85,23 +85,15 @@ fn make_mir_scope<'ll, 'tcx>(
|
||||
discriminators,
|
||||
parent,
|
||||
);
|
||||
if let Some(parent_scope) = debug_context.scopes[parent] {
|
||||
parent_scope
|
||||
} else {
|
||||
// If the parent scope could not be represented then no children
|
||||
// can be either.
|
||||
debug_context.scopes[scope] = None;
|
||||
instantiated.insert(scope);
|
||||
return;
|
||||
}
|
||||
debug_context.scopes[parent]
|
||||
} else {
|
||||
// The root is the function itself.
|
||||
let file = cx.sess().source_map().lookup_source_file(mir.span.lo());
|
||||
debug_context.scopes[scope] = Some(DebugScope {
|
||||
debug_context.scopes[scope] = DebugScope {
|
||||
file_start_pos: file.start_pos,
|
||||
file_end_pos: file.end_position(),
|
||||
..debug_context.scopes[scope].unwrap()
|
||||
});
|
||||
..debug_context.scopes[scope]
|
||||
};
|
||||
instantiated.insert(scope);
|
||||
return;
|
||||
};
|
||||
@@ -112,7 +104,7 @@ fn make_mir_scope<'ll, 'tcx>(
|
||||
{
|
||||
// Do not create a DIScope if there are no variables defined in this
|
||||
// MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat.
|
||||
debug_context.scopes[scope] = Some(parent_scope);
|
||||
debug_context.scopes[scope] = parent_scope;
|
||||
instantiated.insert(scope);
|
||||
return;
|
||||
}
|
||||
@@ -145,14 +137,7 @@ fn make_mir_scope<'ll, 'tcx>(
|
||||
},
|
||||
};
|
||||
|
||||
let mut debug_scope = Some(DebugScope {
|
||||
dbg_scope,
|
||||
inlined_at: parent_scope.inlined_at,
|
||||
file_start_pos: loc.file.start_pos,
|
||||
file_end_pos: loc.file.end_position(),
|
||||
});
|
||||
|
||||
if let Some((_, callsite_span)) = scope_data.inlined {
|
||||
let inlined_at = scope_data.inlined.map(|(_, callsite_span)| {
|
||||
let callsite_span = hygiene::walk_chain_collapsed(callsite_span, mir.span);
|
||||
let callsite_scope = parent_scope.adjust_dbg_scope_for_span(cx, callsite_span);
|
||||
let loc = cx.dbg_loc(callsite_scope, parent_scope.inlined_at, callsite_span);
|
||||
@@ -175,29 +160,29 @@ fn make_mir_scope<'ll, 'tcx>(
|
||||
// Note further that we can't key this hashtable on the span itself,
|
||||
// because these spans could have distinct SyntaxContexts. We have
|
||||
// to key on exactly what we're giving to LLVM.
|
||||
let inlined_at = match discriminators.entry(callsite_span.lo()) {
|
||||
match discriminators.entry(callsite_span.lo()) {
|
||||
Entry::Occupied(mut o) => {
|
||||
*o.get_mut() += 1;
|
||||
// NB: We have to emit *something* here or we'll fail LLVM IR verification
|
||||
// in at least some circumstances (see issue #135322) so if the required
|
||||
// discriminant cannot be encoded fall back to the dummy location.
|
||||
unsafe { llvm::LLVMRustDILocationCloneWithBaseDiscriminator(loc, *o.get()) }
|
||||
.unwrap_or_else(|| {
|
||||
cx.dbg_loc(callsite_scope, parent_scope.inlined_at, DUMMY_SP)
|
||||
})
|
||||
}
|
||||
Entry::Vacant(v) => {
|
||||
v.insert(0);
|
||||
Some(loc)
|
||||
}
|
||||
};
|
||||
match inlined_at {
|
||||
Some(inlined_at) => {
|
||||
debug_scope.as_mut().unwrap().inlined_at = Some(inlined_at);
|
||||
}
|
||||
None => {
|
||||
// LLVM has a maximum discriminator that it can encode (currently
|
||||
// it uses 12 bits for 4096 possible values). If we exceed that
|
||||
// there is little we can do but drop the debug info.
|
||||
debug_scope = None;
|
||||
loc
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
debug_context.scopes[scope] = debug_scope;
|
||||
debug_context.scopes[scope] = DebugScope {
|
||||
dbg_scope,
|
||||
inlined_at: inlined_at.or(parent_scope.inlined_at),
|
||||
file_start_pos: loc.file.start_pos,
|
||||
file_end_pos: loc.file.end_position(),
|
||||
};
|
||||
instantiated.insert(scope);
|
||||
}
|
||||
|
||||
@@ -293,12 +293,12 @@ fn create_function_debug_context(
|
||||
}
|
||||
|
||||
// Initialize fn debug context (including scopes).
|
||||
let empty_scope = Some(DebugScope {
|
||||
let empty_scope = DebugScope {
|
||||
dbg_scope: self.dbg_scope_fn(instance, fn_abi, Some(llfn)),
|
||||
inlined_at: None,
|
||||
file_start_pos: BytePos(0),
|
||||
file_end_pos: BytePos(0),
|
||||
});
|
||||
};
|
||||
let mut fn_debug_context = FunctionDebugContext {
|
||||
scopes: IndexVec::from_elem(empty_scope, &mir.source_scopes),
|
||||
inlined_function_scopes: Default::default(),
|
||||
|
||||
@@ -19,9 +19,7 @@
|
||||
|
||||
pub struct FunctionDebugContext<'tcx, S, L> {
|
||||
/// Maps from source code to the corresponding debug info scope.
|
||||
/// May be None if the backend is not capable of representing the scope for
|
||||
/// some reason.
|
||||
pub scopes: IndexVec<mir::SourceScope, Option<DebugScope<S, L>>>,
|
||||
pub scopes: IndexVec<mir::SourceScope, DebugScope<S, L>>,
|
||||
|
||||
/// Maps from an inlined function to its debug info declaration.
|
||||
pub inlined_function_scopes: FxHashMap<Instance<'tcx>, S>,
|
||||
@@ -232,7 +230,7 @@ fn adjusted_span_and_dbg_scope(
|
||||
&self,
|
||||
source_info: mir::SourceInfo,
|
||||
) -> Option<(Bx::DIScope, Option<Bx::DILocation>, Span)> {
|
||||
let scope = &self.debug_context.as_ref()?.scopes[source_info.scope]?;
|
||||
let scope = &self.debug_context.as_ref()?.scopes[source_info.scope];
|
||||
let span = hygiene::walk_chain_collapsed(source_info.span, self.mir.span);
|
||||
Some((scope.adjust_dbg_scope_for_span(self.cx, span), scope.inlined_at, span))
|
||||
}
|
||||
|
||||
@@ -1086,14 +1086,7 @@ fn find_fallback_pattern_typo<'tcx>(
|
||||
let vis = cx.tcx.visibility(item.owner_id);
|
||||
if vis.is_accessible_from(parent, cx.tcx) {
|
||||
accessible.push(item_name);
|
||||
let path = if item_name == name {
|
||||
// We know that the const wasn't in scope because it has the exact
|
||||
// same name, so we suggest the full path.
|
||||
with_no_trimmed_paths!(cx.tcx.def_path_str(item.owner_id))
|
||||
} else {
|
||||
// The const is likely just typoed, and nothing else.
|
||||
cx.tcx.def_path_str(item.owner_id)
|
||||
};
|
||||
let path = with_no_trimmed_paths!(cx.tcx.def_path_str(item.owner_id));
|
||||
accessible_path.push(path);
|
||||
} else if name == item_name {
|
||||
// The const exists somewhere in this crate, but it can't be imported
|
||||
|
||||
@@ -189,8 +189,9 @@ pub struct Parser<'a> {
|
||||
}
|
||||
|
||||
// This type is used a lot, e.g. it's cloned when matching many declarative macro rules with
|
||||
// nonterminals. Make sure it doesn't unintentionally get bigger.
|
||||
#[cfg(all(target_pointer_width = "64", not(target_arch = "s390x")))]
|
||||
// nonterminals. Make sure it doesn't unintentionally get bigger. We only check a few arches
|
||||
// though, because `TokenTypeSet(u128)` alignment varies on others, changing the total size.
|
||||
#[cfg(all(target_pointer_width = "64", any(target_arch = "aarch64", target_arch = "x86_64")))]
|
||||
rustc_data_structures::static_assert_size!(Parser<'_>, 288);
|
||||
|
||||
/// Stores span information about a closure.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
|
||||
use rustc_errors::{Diag, EmissionGuarantee};
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::DefId;
|
||||
@@ -116,28 +116,39 @@ pub fn overlapping_impls(
|
||||
return None;
|
||||
}
|
||||
|
||||
let _overlap_with_bad_diagnostics = overlap(
|
||||
tcx,
|
||||
TrackAmbiguityCauses::No,
|
||||
skip_leak_check,
|
||||
impl1_def_id,
|
||||
impl2_def_id,
|
||||
overlap_mode,
|
||||
)?;
|
||||
if tcx.next_trait_solver_in_coherence() {
|
||||
overlap(
|
||||
tcx,
|
||||
TrackAmbiguityCauses::Yes,
|
||||
skip_leak_check,
|
||||
impl1_def_id,
|
||||
impl2_def_id,
|
||||
overlap_mode,
|
||||
)
|
||||
} else {
|
||||
let _overlap_with_bad_diagnostics = overlap(
|
||||
tcx,
|
||||
TrackAmbiguityCauses::No,
|
||||
skip_leak_check,
|
||||
impl1_def_id,
|
||||
impl2_def_id,
|
||||
overlap_mode,
|
||||
)?;
|
||||
|
||||
// In the case where we detect an error, run the check again, but
|
||||
// this time tracking intercrate ambiguity causes for better
|
||||
// diagnostics. (These take time and can lead to false errors.)
|
||||
let overlap = overlap(
|
||||
tcx,
|
||||
TrackAmbiguityCauses::Yes,
|
||||
skip_leak_check,
|
||||
impl1_def_id,
|
||||
impl2_def_id,
|
||||
overlap_mode,
|
||||
)
|
||||
.unwrap();
|
||||
Some(overlap)
|
||||
// In the case where we detect an error, run the check again, but
|
||||
// this time tracking intercrate ambiguity causes for better
|
||||
// diagnostics. (These take time and can lead to false errors.)
|
||||
let overlap = overlap(
|
||||
tcx,
|
||||
TrackAmbiguityCauses::Yes,
|
||||
skip_leak_check,
|
||||
impl1_def_id,
|
||||
impl2_def_id,
|
||||
overlap_mode,
|
||||
)
|
||||
.unwrap();
|
||||
Some(overlap)
|
||||
}
|
||||
}
|
||||
|
||||
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>(
|
||||
}
|
||||
|
||||
struct AmbiguityCausesVisitor<'a, 'tcx> {
|
||||
cache: FxHashSet<Goal<'tcx, ty::Predicate<'tcx>>>,
|
||||
causes: &'a mut FxIndexSet<IntercrateAmbiguityCause<'tcx>>,
|
||||
}
|
||||
|
||||
@@ -624,6 +636,10 @@ fn span(&self) -> Span {
|
||||
}
|
||||
|
||||
fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) {
|
||||
if !self.cache.insert(goal.goal()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let infcx = goal.infcx();
|
||||
for cand in goal.candidates() {
|
||||
cand.visit_nested_in_probe(self);
|
||||
@@ -748,5 +764,10 @@ fn search_ambiguity_causes<'tcx>(
|
||||
goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
||||
causes: &mut FxIndexSet<IntercrateAmbiguityCause<'tcx>>,
|
||||
) {
|
||||
infcx.probe(|_| infcx.visit_proof_tree(goal, &mut AmbiguityCausesVisitor { causes }));
|
||||
infcx.probe(|_| {
|
||||
infcx.visit_proof_tree(goal, &mut AmbiguityCausesVisitor {
|
||||
cache: Default::default(),
|
||||
causes,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
@@ -328,9 +328,6 @@ pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
|
||||
mem::size_of::<c::FILE_ALLOCATION_INFO>() as u32,
|
||||
);
|
||||
if result == 0 {
|
||||
if api::get_last_error().code != 0 {
|
||||
panic!("FILE_ALLOCATION_INFO failed!!!");
|
||||
}
|
||||
let eof = c::FILE_END_OF_FILE_INFO { EndOfFile: 0 };
|
||||
let result = c::SetFileInformationByHandle(
|
||||
handle.as_raw_handle(),
|
||||
|
||||
@@ -1264,6 +1264,11 @@ def bootstrap(args):
|
||||
config_toml = ""
|
||||
|
||||
profile = RustBuild.get_toml_static(config_toml, "profile")
|
||||
is_non_git_source = not os.path.exists(os.path.join(rust_root, ".git"))
|
||||
|
||||
if profile is None and is_non_git_source:
|
||||
profile = "dist"
|
||||
|
||||
if profile is not None:
|
||||
# Allows creating alias for profile names, allowing
|
||||
# profiles to be renamed while maintaining back compatibility
|
||||
|
||||
@@ -1790,7 +1790,13 @@ fn run(self, builder: &Builder<'_>) -> Compiler {
|
||||
// When using `download-ci-llvm`, some of the tools
|
||||
// may not exist, so skip trying to copy them.
|
||||
if src_path.exists() {
|
||||
builder.copy_link(&src_path, &libdir_bin.join(&tool_exe));
|
||||
// There is a chance that these tools are being installed from an external LLVM.
|
||||
// Use `Builder::resolve_symlink_and_copy` instead of `Builder::copy_link` to ensure
|
||||
// we are copying the original file not the symlinked path, which causes issues for
|
||||
// tarball distribution.
|
||||
//
|
||||
// See https://github.com/rust-lang/rust/issues/135554.
|
||||
builder.resolve_symlink_and_copy(&src_path, &libdir_bin.join(&tool_exe));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2863,21 +2863,26 @@ fn download_ci_rustc_commit(
|
||||
allowed_paths.push(":!library");
|
||||
}
|
||||
|
||||
// Look for a version to compare to based on the current commit.
|
||||
// Only commits merged by bors will have CI artifacts.
|
||||
let commit = match self.last_modified_commit(&allowed_paths, "download-rustc", if_unchanged)
|
||||
{
|
||||
Some(commit) => commit,
|
||||
None => {
|
||||
if if_unchanged {
|
||||
return None;
|
||||
let commit = if self.rust_info.is_managed_git_subrepository() {
|
||||
// Look for a version to compare to based on the current commit.
|
||||
// Only commits merged by bors will have CI artifacts.
|
||||
match self.last_modified_commit(&allowed_paths, "download-rustc", if_unchanged) {
|
||||
Some(commit) => commit,
|
||||
None => {
|
||||
if if_unchanged {
|
||||
return None;
|
||||
}
|
||||
println!("ERROR: could not find commit hash for downloading rustc");
|
||||
println!("HELP: maybe your repository history is too shallow?");
|
||||
println!("HELP: consider setting `rust.download-rustc=false` in config.toml");
|
||||
println!("HELP: or fetch enough history to include one upstream commit");
|
||||
crate::exit!(1);
|
||||
}
|
||||
println!("ERROR: could not find commit hash for downloading rustc");
|
||||
println!("HELP: maybe your repository history is too shallow?");
|
||||
println!("HELP: consider setting `rust.download-rustc=false` in config.toml");
|
||||
println!("HELP: or fetch enough history to include one upstream commit");
|
||||
crate::exit!(1);
|
||||
}
|
||||
} else {
|
||||
channel::read_commit_info_file(&self.src)
|
||||
.map(|info| info.sha.trim().to_owned())
|
||||
.expect("git-commit-info is missing in the project root")
|
||||
};
|
||||
|
||||
if CiEnv::is_ci() && {
|
||||
@@ -2914,10 +2919,8 @@ fn parse_download_ci_llvm(
|
||||
let if_unchanged = || {
|
||||
if self.rust_info.is_from_tarball() {
|
||||
// Git is needed for running "if-unchanged" logic.
|
||||
println!(
|
||||
"WARNING: 'if-unchanged' has no effect on tarball sources; ignoring `download-ci-llvm`."
|
||||
);
|
||||
return false;
|
||||
println!("ERROR: 'if-unchanged' is only compatible with Git managed sources.");
|
||||
crate::exit!(1);
|
||||
}
|
||||
|
||||
// Fetching the LLVM submodule is unnecessary for self-tests.
|
||||
@@ -2959,6 +2962,11 @@ pub fn last_modified_commit(
|
||||
option_name: &str,
|
||||
if_unchanged: bool,
|
||||
) -> Option<String> {
|
||||
assert!(
|
||||
self.rust_info.is_managed_git_subrepository(),
|
||||
"Can't run `Config::last_modified_commit` on a non-git source."
|
||||
);
|
||||
|
||||
// Look for a version to compare to based on the current commit.
|
||||
// Only commits merged by bors will have CI artifacts.
|
||||
let commit = get_closest_merge_commit(Some(&self.src), &self.git_config(), &[]).unwrap();
|
||||
|
||||
@@ -1657,6 +1657,14 @@ fn read_stamp_file(&self, stamp: &Path) -> Vec<(PathBuf, DependencyType)> {
|
||||
paths
|
||||
}
|
||||
|
||||
/// Copies a file from `src` to `dst`.
|
||||
///
|
||||
/// If `src` is a symlink, `src` will be resolved to the actual path
|
||||
/// and copied to `dst` instead of the symlink itself.
|
||||
pub fn resolve_symlink_and_copy(&self, src: &Path, dst: &Path) {
|
||||
self.copy_link_internal(src, dst, true);
|
||||
}
|
||||
|
||||
/// Links a file from `src` to `dst`.
|
||||
/// Attempts to use hard links if possible, falling back to copying.
|
||||
/// You can neither rely on this being a copy nor it being a link,
|
||||
|
||||
+1
-1
Submodule src/doc/book updated: 8a0eee28f7...82a4a49789
@@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
other::big_function();
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
proc::declare_big_function!();
|
||||
@@ -0,0 +1,7 @@
|
||||
extern crate proc_macro;
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
#[proc_macro]
|
||||
pub fn declare_big_function(_input: TokenStream) -> TokenStream {
|
||||
include_str!("./generated.rs").parse().unwrap()
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
//! Regression test for <https://github.com/rust-lang/rust/issues/135332>.
|
||||
//!
|
||||
//! We can't simply drop debuginfo location spans when LLVM's location discriminator value limit is
|
||||
//! reached. Otherwise, with `-Z verify-llvm-ir` and fat LTO, LLVM will report a broken module for
|
||||
//!
|
||||
//! ```text
|
||||
//! inlinable function call in a function with debug info must have a !dbg location
|
||||
//! ```
|
||||
|
||||
//@ ignore-cross-compile
|
||||
//@ needs-dynamic-linking
|
||||
//@ only-nightly (requires unstable rustc flag)
|
||||
|
||||
#![deny(warnings)]
|
||||
|
||||
use run_make_support::{dynamic_lib_name, rfs, rust_lib_name, rustc};
|
||||
|
||||
// Synthesize a function that will have a large (`n`) number of functions
|
||||
// MIR-inlined into it. When combined with a proc-macro, all of these inline
|
||||
// callsites will have the same span, forcing rustc to use the DWARF
|
||||
// discriminator to distinguish between them. LLVM's capacity to store that
|
||||
// discriminator is not infinite (currently it allocates 12 bits for a
|
||||
// maximum value of 4096) so if this function gets big enough rustc's error
|
||||
// handling path will be exercised.
|
||||
fn generate_program(n: u32) -> String {
|
||||
let mut program = String::from("pub type BigType = Vec<Vec<String>>;\n\n");
|
||||
program.push_str("pub fn big_function() -> BigType {\n");
|
||||
program.push_str(" vec![\n");
|
||||
for i in 1..=n {
|
||||
program.push_str(&format!("vec![\"string{}\".to_owned()],\n", i));
|
||||
}
|
||||
program.push_str(" ]\n");
|
||||
program.push_str("}\n");
|
||||
program
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// The reported threshold is around 1366 (4096/3), but let's bump it to
|
||||
// around 1500 to be less sensitive.
|
||||
rfs::write("generated.rs", generate_program(1500));
|
||||
|
||||
rustc()
|
||||
.input("proc.rs")
|
||||
.crate_type("proc-macro")
|
||||
.edition("2021")
|
||||
.arg("-Cdebuginfo=line-tables-only")
|
||||
.run();
|
||||
rustc()
|
||||
.extern_("proc", dynamic_lib_name("proc"))
|
||||
.input("other.rs")
|
||||
.crate_type("rlib")
|
||||
.edition("2021")
|
||||
.opt_level("3")
|
||||
.arg("-Cdebuginfo=line-tables-only")
|
||||
.run();
|
||||
rustc()
|
||||
.extern_("other", rust_lib_name("other"))
|
||||
.input("main.rs")
|
||||
.edition("2021")
|
||||
.opt_level("3")
|
||||
.arg("-Cdebuginfo=line-tables-only")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-Zverify-llvm-ir")
|
||||
.run();
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
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), .. }
|
||||
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), .. }
|
||||
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), .. }
|
||||
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), .. }
|
||||
error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())`
|
||||
--> $DIR/associated-type.rs:32:1
|
||||
|
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
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), .. }
|
||||
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), .. }
|
||||
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), .. }
|
||||
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), .. }
|
||||
error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())`
|
||||
--> $DIR/associated-type.rs:32:1
|
||||
|
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
// Computing the ambiguity causes for the overlap ended up
|
||||
// causing an exponential blowup when recursing into the normalization
|
||||
// goals for `<Box<?t> as RecursiveSuper>::Assoc`. This test
|
||||
// takes multiple minutes when doing so and less than a second
|
||||
// otherwise.
|
||||
|
||||
//@ compile-flags: -Znext-solver=coherence
|
||||
|
||||
trait RecursiveSuper:
|
||||
Super<
|
||||
A0 = Self::Assoc,
|
||||
A1 = Self::Assoc,
|
||||
A2 = Self::Assoc,
|
||||
A3 = Self::Assoc,
|
||||
A4 = Self::Assoc,
|
||||
A5 = Self::Assoc,
|
||||
A6 = Self::Assoc,
|
||||
A7 = Self::Assoc,
|
||||
A8 = Self::Assoc,
|
||||
A9 = Self::Assoc,
|
||||
A10 = Self::Assoc,
|
||||
A11 = Self::Assoc,
|
||||
A12 = Self::Assoc,
|
||||
A13 = Self::Assoc,
|
||||
A14 = Self::Assoc,
|
||||
A15 = Self::Assoc,
|
||||
>
|
||||
{
|
||||
type Assoc;
|
||||
}
|
||||
|
||||
trait Super {
|
||||
type A0;
|
||||
type A1;
|
||||
type A2;
|
||||
type A3;
|
||||
type A4;
|
||||
type A5;
|
||||
type A6;
|
||||
type A7;
|
||||
type A8;
|
||||
type A9;
|
||||
type A10;
|
||||
type A11;
|
||||
type A12;
|
||||
type A13;
|
||||
type A14;
|
||||
type A15;
|
||||
}
|
||||
|
||||
trait Overlap {}
|
||||
impl<T: RecursiveSuper> Overlap for T {}
|
||||
impl<T> Overlap for Box<T> {}
|
||||
//~^ ERROR conflicting implementations of trait `Overlap` for type `Box<_>`
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,14 @@
|
||||
error[E0119]: conflicting implementations of trait `Overlap` for type `Box<_>`
|
||||
--> $DIR/ambiguity-causes-visitor-hang.rs:53:1
|
||||
|
|
||||
LL | impl<T: RecursiveSuper> Overlap for T {}
|
||||
| ------------------------------------- first implementation here
|
||||
LL | impl<T> Overlap for Box<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>`
|
||||
|
|
||||
= note: downstream crates may implement trait `Super` for type `std::boxed::Box<_>`
|
||||
= note: downstream crates may implement trait `RecursiveSuper` for type `std::boxed::Box<_>`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
||||
Reference in New Issue
Block a user