Auto merge of #114718 - compiler-errors:rollup-1am5rpn, r=compiler-errors
Rollup of 7 pull requests Successful merges: - #114599 (Add impl trait declarations to SMIR) - #114622 (rustc: Move `crate_types` and `stable_crate_id` from `Session` to `GlobalCtxt`) - #114662 (Unlock trailing where-clauses for lazy type aliases) - #114693 (Remove myself from the review rotation) - #114694 (make the provisional cache slightly less broken) - #114705 (Add spastorino to mailmap) - #114712 (Fix a couple of bad comments) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
a07bc13e14
3
.mailmap
3
.mailmap
@ -458,6 +458,7 @@ Philipp Matthias Schäfer <philipp.matthias.schaefer@posteo.de>
|
||||
phosphorus <steepout@qq.com>
|
||||
Pierre Krieger <pierre.krieger1708@gmail.com>
|
||||
pierwill <pierwill@users.noreply.github.com> <19642016+pierwill@users.noreply.github.com>
|
||||
Pietro Albini <pietro@pietroalbini.org> <pietro@pietroalbini.io> <pietro.albini@ferrous-systems.com>
|
||||
Pradyumna Rahul <prkinformed@gmail.com>
|
||||
Przemysław Wesołek <jest@go.art.pl> Przemek Wesołek <jest@go.art.pl>
|
||||
r00ster <r00ster91@protonmail.com>
|
||||
@ -495,6 +496,8 @@ Ryan Wiedemann <Ryan1729@gmail.com>
|
||||
S Pradeep Kumar <gohanpra@gmail.com>
|
||||
Sam Radhakrishnan <sk09idm@gmail.com>
|
||||
Samuel Tardieu <sam@rfc1149.net>
|
||||
Santiago Pastorino <spastorino@gmail.com>
|
||||
Santiago Pastorino <spastorino@gmail.com> <santiago@wyeworks.com>
|
||||
Scott McMurray <scottmcm@users.noreply.github.com>
|
||||
Scott Olson <scott@solson.me> Scott Olson <scott@scott-olson.org>
|
||||
Sean Gillespie <sean.william.g@gmail.com> swgillespie <sean.william.g@gmail.com>
|
||||
|
@ -457,7 +457,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
|
||||
|
||||
// Don't hash unless necessary, because it's expensive.
|
||||
let opt_hir_hash =
|
||||
if tcx.sess.needs_crate_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None };
|
||||
if tcx.needs_crate_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None };
|
||||
hir::Crate { owners, opt_hir_hash }
|
||||
}
|
||||
|
||||
@ -648,7 +648,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
let bodies = SortedMap::from_presorted_elements(bodies);
|
||||
|
||||
// Don't hash unless necessary, because it's expensive.
|
||||
let (opt_hash_including_bodies, attrs_hash) = if self.tcx.sess.needs_crate_hash() {
|
||||
let (opt_hash_including_bodies, attrs_hash) = if self.tcx.needs_crate_hash() {
|
||||
self.tcx.with_stable_hashing_context(|mut hcx| {
|
||||
let mut stable_hasher = StableHasher::new();
|
||||
hcx.with_hir_bodies(node.def_id(), &bodies, |hcx| {
|
||||
|
@ -239,5 +239,10 @@ ast_passes_visibility_not_permitted =
|
||||
.individual_impl_items = place qualifiers on individual impl items instead
|
||||
.individual_foreign_items = place qualifiers on individual foreign items instead
|
||||
|
||||
ast_passes_where_after_type_alias = where clauses are not allowed after the type for type aliases
|
||||
ast_passes_where_clause_after_type_alias = where clauses are not allowed after the type for type aliases
|
||||
.note = see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
|
||||
.help = add `#![feature(lazy_type_alias)]` to the crate attributes to enable
|
||||
|
||||
ast_passes_where_clause_before_type_alias = where clauses are not allowed before the type for type aliases
|
||||
.note = see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
|
||||
.suggestion = move it to the end of the type declaration
|
||||
|
@ -136,40 +136,42 @@ impl<'a> AstValidator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_gat_where(
|
||||
fn check_type_alias_where_clause_location(
|
||||
&mut self,
|
||||
id: NodeId,
|
||||
before_predicates: &[WherePredicate],
|
||||
where_clauses: (ast::TyAliasWhereClause, ast::TyAliasWhereClause),
|
||||
) {
|
||||
if !before_predicates.is_empty() {
|
||||
let mut state = State::new();
|
||||
if !where_clauses.1.0 {
|
||||
state.space();
|
||||
state.word_space("where");
|
||||
} else {
|
||||
ty_alias: &TyAlias,
|
||||
) -> Result<(), errors::WhereClauseBeforeTypeAlias> {
|
||||
let before_predicates =
|
||||
ty_alias.generics.where_clause.predicates.split_at(ty_alias.where_predicates_split).0;
|
||||
|
||||
if ty_alias.ty.is_none() || before_predicates.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut state = State::new();
|
||||
if !ty_alias.where_clauses.1.0 {
|
||||
state.space();
|
||||
state.word_space("where");
|
||||
} else {
|
||||
state.word_space(",");
|
||||
}
|
||||
let mut first = true;
|
||||
for p in before_predicates {
|
||||
if !first {
|
||||
state.word_space(",");
|
||||
}
|
||||
let mut first = true;
|
||||
for p in before_predicates.iter() {
|
||||
if !first {
|
||||
state.word_space(",");
|
||||
}
|
||||
first = false;
|
||||
state.print_where_predicate(p);
|
||||
}
|
||||
let suggestion = state.s.eof();
|
||||
self.lint_buffer.buffer_lint_with_diagnostic(
|
||||
DEPRECATED_WHERE_CLAUSE_LOCATION,
|
||||
id,
|
||||
where_clauses.0.1,
|
||||
fluent::ast_passes_deprecated_where_clause_location,
|
||||
BuiltinLintDiagnostics::DeprecatedWhereclauseLocation(
|
||||
where_clauses.1.1.shrink_to_hi(),
|
||||
suggestion,
|
||||
),
|
||||
);
|
||||
first = false;
|
||||
state.print_where_predicate(p);
|
||||
}
|
||||
|
||||
let span = ty_alias.where_clauses.0.1;
|
||||
Err(errors::WhereClauseBeforeTypeAlias {
|
||||
span,
|
||||
sugg: errors::WhereClauseBeforeTypeAliasSugg {
|
||||
left: span,
|
||||
snippet: state.s.eof(),
|
||||
right: ty_alias.where_clauses.1.1.shrink_to_hi(),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
fn with_impl_trait(&mut self, outer: Option<Span>, f: impl FnOnce(&mut Self)) {
|
||||
@ -1009,7 +1011,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
});
|
||||
}
|
||||
ItemKind::TyAlias(box TyAlias { defaultness, where_clauses, bounds, ty, .. }) => {
|
||||
ItemKind::TyAlias(
|
||||
ty_alias @ box TyAlias { defaultness, bounds, where_clauses, ty, .. },
|
||||
) => {
|
||||
self.check_defaultness(item.span, *defaultness);
|
||||
if ty.is_none() {
|
||||
self.session.emit_err(errors::TyAliasWithoutBody {
|
||||
@ -1018,9 +1022,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
});
|
||||
}
|
||||
self.check_type_no_bounds(bounds, "this context");
|
||||
if where_clauses.1.0 {
|
||||
self.err_handler()
|
||||
.emit_err(errors::WhereAfterTypeAlias { span: where_clauses.1.1 });
|
||||
|
||||
if self.session.features_untracked().lazy_type_alias {
|
||||
if let Err(err) = self.check_type_alias_where_clause_location(ty_alias) {
|
||||
self.err_handler().emit_err(err);
|
||||
}
|
||||
} else if where_clauses.1.0 {
|
||||
self.err_handler().emit_err(errors::WhereClauseAfterTypeAlias {
|
||||
span: where_clauses.1.1,
|
||||
help: self.session.is_nightly_build().then_some(()),
|
||||
});
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@ -1313,18 +1324,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
if let AssocItemKind::Type(box TyAlias {
|
||||
generics,
|
||||
where_clauses,
|
||||
where_predicates_split,
|
||||
ty: Some(_),
|
||||
..
|
||||
}) = &item.kind
|
||||
if let AssocItemKind::Type(ty_alias) = &item.kind
|
||||
&& let Err(err) = self.check_type_alias_where_clause_location(ty_alias)
|
||||
{
|
||||
self.check_gat_where(
|
||||
self.lint_buffer.buffer_lint_with_diagnostic(
|
||||
DEPRECATED_WHERE_CLAUSE_LOCATION,
|
||||
item.id,
|
||||
generics.where_clause.predicates.split_at(*where_predicates_split).0,
|
||||
*where_clauses,
|
||||
err.span,
|
||||
fluent::ast_passes_deprecated_where_clause_location,
|
||||
BuiltinLintDiagnostics::DeprecatedWhereclauseLocation(
|
||||
err.sugg.right,
|
||||
err.sugg.snippet,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -496,11 +496,37 @@ pub struct FieldlessUnion {
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ast_passes_where_after_type_alias)]
|
||||
#[diag(ast_passes_where_clause_after_type_alias)]
|
||||
#[note]
|
||||
pub struct WhereAfterTypeAlias {
|
||||
pub struct WhereClauseAfterTypeAlias {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[help]
|
||||
pub help: Option<()>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ast_passes_where_clause_before_type_alias)]
|
||||
#[note]
|
||||
pub struct WhereClauseBeforeTypeAlias {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub sugg: WhereClauseBeforeTypeAliasSugg,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(
|
||||
ast_passes_suggestion,
|
||||
applicability = "machine-applicable",
|
||||
style = "verbose"
|
||||
)]
|
||||
pub struct WhereClauseBeforeTypeAliasSugg {
|
||||
#[suggestion_part(code = "")]
|
||||
pub left: Span,
|
||||
pub snippet: String,
|
||||
#[suggestion_part(code = "{snippet}")]
|
||||
pub right: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
@ -98,7 +98,7 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
|
||||
tcx.sess.fatal("JIT mode doesn't work with `cargo check`");
|
||||
}
|
||||
|
||||
if !tcx.sess.crate_types().contains(&rustc_session::config::CrateType::Executable) {
|
||||
if !tcx.crate_types().contains(&rustc_session::config::CrateType::Executable) {
|
||||
tcx.sess.fatal("can't jit non-executable crate");
|
||||
}
|
||||
|
||||
|
@ -209,7 +209,7 @@ pub unsafe fn create_module<'ll>(
|
||||
// PIE is potentially more effective than PIC, but can only be used in executables.
|
||||
// If all our outputs are executables, then we can relax PIC to PIE.
|
||||
if reloc_model == RelocModel::Pie
|
||||
|| sess.crate_types().iter().all(|ty| *ty == CrateType::Executable)
|
||||
|| tcx.crate_types().iter().all(|ty| *ty == CrateType::Executable)
|
||||
{
|
||||
llvm::LLVMRustSetModulePIELevel(llmod);
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ pub fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
|
||||
// each rlib could produce a different set of visualizers that would be embedded
|
||||
// in the `.debug_gdb_scripts` section. For that reason, we make sure that the
|
||||
// section is only emitted for leaf crates.
|
||||
let embed_visualizers = cx.sess().crate_types().iter().any(|&crate_type| match crate_type {
|
||||
let embed_visualizers = cx.tcx.crate_types().iter().any(|&crate_type| match crate_type {
|
||||
CrateType::Executable | CrateType::Dylib | CrateType::Cdylib | CrateType::Staticlib => {
|
||||
// These are crate types for which we will embed pretty printers since they
|
||||
// are treated as leaf crates.
|
||||
|
@ -111,7 +111,7 @@ impl CodegenCx<'_, '_> {
|
||||
}
|
||||
|
||||
// Symbols from executables can't really be imported any further.
|
||||
let all_exe = self.tcx.sess.crate_types().iter().all(|ty| *ty == CrateType::Executable);
|
||||
let all_exe = self.tcx.crate_types().iter().all(|ty| *ty == CrateType::Executable);
|
||||
let is_declaration_for_linker =
|
||||
is_declaration || linkage == llvm::Linkage::AvailableExternallyLinkage;
|
||||
if all_exe && !is_declaration_for_linker {
|
||||
|
@ -69,7 +69,7 @@ pub fn link_binary<'a>(
|
||||
let _timer = sess.timer("link_binary");
|
||||
let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata);
|
||||
let mut tempfiles_for_stdout_output: Vec<PathBuf> = Vec::new();
|
||||
for &crate_type in sess.crate_types().iter() {
|
||||
for &crate_type in &codegen_results.crate_info.crate_types {
|
||||
// Ignore executable crates if we have -Z no-codegen, as they will error.
|
||||
if (sess.opts.unstable_opts.no_codegen || !sess.opts.output_types.should_codegen())
|
||||
&& !output_metadata
|
||||
|
@ -1703,7 +1703,7 @@ fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<String> {
|
||||
return Vec::new();
|
||||
}
|
||||
|
||||
let stable_crate_id = tcx.sess.local_stable_crate_id();
|
||||
let stable_crate_id = tcx.stable_crate_id(LOCAL_CRATE);
|
||||
let proc_macro_decls_name = tcx.sess.generate_proc_macro_decls_symbol(stable_crate_id);
|
||||
let metadata_symbol_name = exported_symbols::metadata_symbol_name(tcx);
|
||||
|
||||
|
@ -19,7 +19,7 @@ use rustc_session::config::{CrateType, OomStrategy};
|
||||
use rustc_target::spec::SanitizerSet;
|
||||
|
||||
pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel {
|
||||
crates_export_threshold(&tcx.sess.crate_types())
|
||||
crates_export_threshold(tcx.crate_types())
|
||||
}
|
||||
|
||||
fn crate_export_threshold(crate_type: CrateType) -> SymbolExportLevel {
|
||||
@ -290,8 +290,8 @@ fn exported_symbols_provider_local(
|
||||
}));
|
||||
}
|
||||
|
||||
if tcx.sess.crate_types().contains(&CrateType::Dylib)
|
||||
|| tcx.sess.crate_types().contains(&CrateType::ProcMacro)
|
||||
if tcx.crate_types().contains(&CrateType::Dylib)
|
||||
|| tcx.crate_types().contains(&CrateType::ProcMacro)
|
||||
{
|
||||
let symbol_name = metadata_symbol_name(tcx);
|
||||
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name));
|
||||
|
@ -123,7 +123,7 @@ pub struct ModuleConfig {
|
||||
impl ModuleConfig {
|
||||
fn new(
|
||||
kind: ModuleKind,
|
||||
sess: &Session,
|
||||
tcx: TyCtxt<'_>,
|
||||
no_builtins: bool,
|
||||
is_compiler_builtins: bool,
|
||||
) -> ModuleConfig {
|
||||
@ -135,6 +135,7 @@ impl ModuleConfig {
|
||||
};
|
||||
}
|
||||
|
||||
let sess = tcx.sess;
|
||||
let opt_level_and_size = if_regular!(Some(sess.opts.optimize), None);
|
||||
|
||||
let save_temps = sess.opts.cg.save_temps;
|
||||
@ -166,7 +167,7 @@ impl ModuleConfig {
|
||||
// `#![no_builtins]` is assumed to not participate in LTO and
|
||||
// instead goes on to generate object code.
|
||||
EmitObj::Bitcode
|
||||
} else if need_bitcode_in_object(sess) {
|
||||
} else if need_bitcode_in_object(tcx) {
|
||||
EmitObj::ObjectCode(BitcodeSection::Full)
|
||||
} else {
|
||||
EmitObj::ObjectCode(BitcodeSection::None)
|
||||
@ -414,9 +415,10 @@ pub struct CompiledModules {
|
||||
pub allocator_module: Option<CompiledModule>,
|
||||
}
|
||||
|
||||
fn need_bitcode_in_object(sess: &Session) -> bool {
|
||||
fn need_bitcode_in_object(tcx: TyCtxt<'_>) -> bool {
|
||||
let sess = tcx.sess;
|
||||
let requested_for_rlib = sess.opts.cg.embed_bitcode
|
||||
&& sess.crate_types().contains(&CrateType::Rlib)
|
||||
&& tcx.crate_types().contains(&CrateType::Rlib)
|
||||
&& sess.opts.output_types.contains_key(&OutputType::Exe);
|
||||
let forced_by_target = sess.target.forces_embed_bitcode;
|
||||
requested_for_rlib || forced_by_target
|
||||
@ -450,11 +452,11 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
|
||||
let crate_info = CrateInfo::new(tcx, target_cpu);
|
||||
|
||||
let regular_config =
|
||||
ModuleConfig::new(ModuleKind::Regular, sess, no_builtins, is_compiler_builtins);
|
||||
ModuleConfig::new(ModuleKind::Regular, tcx, no_builtins, is_compiler_builtins);
|
||||
let metadata_config =
|
||||
ModuleConfig::new(ModuleKind::Metadata, sess, no_builtins, is_compiler_builtins);
|
||||
ModuleConfig::new(ModuleKind::Metadata, tcx, no_builtins, is_compiler_builtins);
|
||||
let allocator_config =
|
||||
ModuleConfig::new(ModuleKind::Allocator, sess, no_builtins, is_compiler_builtins);
|
||||
ModuleConfig::new(ModuleKind::Allocator, tcx, no_builtins, is_compiler_builtins);
|
||||
|
||||
let (shared_emitter, shared_emitter_main) = SharedEmitter::new();
|
||||
let (codegen_worker_send, codegen_worker_receive) = channel();
|
||||
@ -1092,7 +1094,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
|
||||
};
|
||||
|
||||
let cgcx = CodegenContext::<B> {
|
||||
crate_types: sess.crate_types().to_vec(),
|
||||
crate_types: tcx.crate_types().to_vec(),
|
||||
each_linked_rlib_for_lto,
|
||||
lto: sess.lto(),
|
||||
fewer_names: sess.fewer_names(),
|
||||
@ -2063,7 +2065,7 @@ fn msvc_imps_needed(tcx: TyCtxt<'_>) -> bool {
|
||||
);
|
||||
|
||||
tcx.sess.target.is_like_windows &&
|
||||
tcx.sess.crate_types().iter().any(|ct| *ct == CrateType::Rlib) &&
|
||||
tcx.crate_types().iter().any(|ct| *ct == CrateType::Rlib) &&
|
||||
// ThinLTO can't handle this workaround in all cases, so we don't
|
||||
// emit the `__imp_` symbols. Instead we make them unnecessary by disallowing
|
||||
// dynamic linking when linker plugin LTO is enabled.
|
||||
|
@ -779,18 +779,13 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
|
||||
|
||||
impl CrateInfo {
|
||||
pub fn new(tcx: TyCtxt<'_>, target_cpu: String) -> CrateInfo {
|
||||
let exported_symbols = tcx
|
||||
.sess
|
||||
.crate_types()
|
||||
let crate_types = tcx.crate_types().to_vec();
|
||||
let exported_symbols = crate_types
|
||||
.iter()
|
||||
.map(|&c| (c, crate::back::linker::exported_symbols(tcx, c)))
|
||||
.collect();
|
||||
let linked_symbols = tcx
|
||||
.sess
|
||||
.crate_types()
|
||||
.iter()
|
||||
.map(|&c| (c, crate::back::linker::linked_symbols(tcx, c)))
|
||||
.collect();
|
||||
let linked_symbols =
|
||||
crate_types.iter().map(|&c| (c, crate::back::linker::linked_symbols(tcx, c))).collect();
|
||||
let local_crate_name = tcx.crate_name(LOCAL_CRATE);
|
||||
let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID);
|
||||
let subsystem = attr::first_attr_value_str_by_name(crate_attrs, sym::windows_subsystem);
|
||||
@ -829,6 +824,7 @@ impl CrateInfo {
|
||||
|
||||
let mut info = CrateInfo {
|
||||
target_cpu,
|
||||
crate_types,
|
||||
exported_symbols,
|
||||
linked_symbols,
|
||||
local_crate_name,
|
||||
@ -916,7 +912,7 @@ impl CrateInfo {
|
||||
});
|
||||
}
|
||||
|
||||
let embed_visualizers = tcx.sess.crate_types().iter().any(|&crate_type| match crate_type {
|
||||
let embed_visualizers = tcx.crate_types().iter().any(|&crate_type| match crate_type {
|
||||
CrateType::Executable | CrateType::Dylib | CrateType::Cdylib => {
|
||||
// These are crate types for which we invoke the linker and can embed
|
||||
// NatVis visualizers.
|
||||
@ -1013,7 +1009,7 @@ fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguR
|
||||
match compute_per_cgu_lto_type(
|
||||
&tcx.sess.lto(),
|
||||
&tcx.sess.opts,
|
||||
&tcx.sess.crate_types(),
|
||||
tcx.crate_types(),
|
||||
ModuleKind::Regular,
|
||||
) {
|
||||
ComputedLtoType::No => CguReuse::PostLto,
|
||||
|
@ -150,6 +150,7 @@ impl From<&cstore::NativeLib> for NativeLib {
|
||||
#[derive(Debug, Encodable, Decodable)]
|
||||
pub struct CrateInfo {
|
||||
pub target_cpu: String,
|
||||
pub crate_types: Vec<CrateType>,
|
||||
pub exported_symbols: FxHashMap<CrateType, Vec<String>>,
|
||||
pub linked_symbols: FxHashMap<CrateType, Vec<(String, SymbolExportKind)>>,
|
||||
pub local_crate_name: Symbol,
|
||||
|
@ -653,8 +653,6 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) {
|
||||
pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Compilation {
|
||||
if sess.opts.unstable_opts.link_only {
|
||||
if let Input::File(file) = &sess.io.input {
|
||||
// FIXME: #![crate_type] and #![crate_name] support not implemented yet
|
||||
sess.init_crate_types(collect_crate_types(sess, &[]));
|
||||
let outputs = compiler.build_output_filenames(sess, &[]);
|
||||
let rlink_data = fs::read(file).unwrap_or_else(|err| {
|
||||
sess.emit_fatal(RlinkUnableToRead { err });
|
||||
|
@ -510,9 +510,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
success(adjustments, ty, obligations)
|
||||
}
|
||||
|
||||
// &[T; n] or &mut [T; n] -> &[T]
|
||||
// or &mut [T; n] -> &mut [T]
|
||||
// or &Concrete -> &Trait, etc.
|
||||
/// Performs [unsized coercion] by emulating a fulfillment loop on a
|
||||
/// `CoerceUnsized` goal until all `CoerceUnsized` and `Unsize` goals
|
||||
/// are successfully selected.
|
||||
///
|
||||
/// [unsized coercion](https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions)
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn coerce_unsized(&self, mut source: Ty<'tcx>, mut target: Ty<'tcx>) -> CoerceResult<'tcx> {
|
||||
source = self.shallow_resolve(source);
|
||||
|
@ -618,8 +618,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
match *self_ty.kind() {
|
||||
ty::Infer(ty::TyVar(found_vid)) => {
|
||||
// FIXME: consider using `sub_root_var` here so we
|
||||
// can see through subtyping.
|
||||
let found_vid = self.root_var(found_vid);
|
||||
debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
|
||||
expected_vid == found_vid
|
||||
@ -634,8 +632,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self_ty: ty::TyVid,
|
||||
) -> impl DoubleEndedIterator<Item = traits::PredicateObligation<'tcx>> + Captures<'tcx> + 'b
|
||||
{
|
||||
// FIXME: consider using `sub_root_var` here so we
|
||||
// can see through subtyping.
|
||||
let ty_var_root = self.root_var(self_ty);
|
||||
trace!("pending_obligations = {:#?}", self.fulfillment_cx.borrow().pending_obligations());
|
||||
|
||||
|
@ -12,7 +12,7 @@ use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
|
||||
use rustc_errors::PResult;
|
||||
use rustc_expand::base::{ExtCtxt, LintStoreExpand};
|
||||
use rustc_fs_util::try_canonicalize;
|
||||
use rustc_hir::def_id::LOCAL_CRATE;
|
||||
use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE};
|
||||
use rustc_lint::{unerased_lint_store, BufferedEarlyLint, EarlyCheckNode, LintStore};
|
||||
use rustc_metadata::creader::CStore;
|
||||
use rustc_middle::arena::Arena;
|
||||
@ -248,7 +248,7 @@ fn configure_and_expand(
|
||||
rustc_ast_passes::ast_validation::check_crate(sess, &krate, resolver.lint_buffer())
|
||||
});
|
||||
|
||||
let crate_types = sess.crate_types();
|
||||
let crate_types = tcx.crate_types();
|
||||
let is_executable_crate = crate_types.contains(&CrateType::Executable);
|
||||
let is_proc_macro_crate = crate_types.contains(&CrateType::ProcMacro);
|
||||
|
||||
@ -340,11 +340,12 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
|
||||
|
||||
// Returns all the paths that correspond to generated files.
|
||||
fn generated_output_paths(
|
||||
sess: &Session,
|
||||
tcx: TyCtxt<'_>,
|
||||
outputs: &OutputFilenames,
|
||||
exact_name: bool,
|
||||
crate_name: Symbol,
|
||||
) -> Vec<PathBuf> {
|
||||
let sess = tcx.sess;
|
||||
let mut out_filenames = Vec::new();
|
||||
for output_type in sess.opts.output_types.keys() {
|
||||
let out_filename = outputs.path(*output_type);
|
||||
@ -353,7 +354,7 @@ fn generated_output_paths(
|
||||
// If the filename has been overridden using `-o`, it will not be modified
|
||||
// by appending `.rlib`, `.exe`, etc., so we can skip this transformation.
|
||||
OutputType::Exe if !exact_name => {
|
||||
for crate_type in sess.crate_types().iter() {
|
||||
for crate_type in tcx.crate_types().iter() {
|
||||
let p = filename_for_input(sess, *crate_type, crate_name, outputs);
|
||||
out_filenames.push(p.as_path().to_path_buf());
|
||||
}
|
||||
@ -586,7 +587,7 @@ fn output_filenames(tcx: TyCtxt<'_>, (): ()) -> Arc<OutputFilenames> {
|
||||
let outputs = util::build_output_filenames(&krate.attrs, sess);
|
||||
|
||||
let output_paths =
|
||||
generated_output_paths(sess, &outputs, sess.io.output_file.is_some(), crate_name);
|
||||
generated_output_paths(tcx, &outputs, sess.io.output_file.is_some(), crate_name);
|
||||
|
||||
// Ensure the source file isn't accidentally overwritten during compilation.
|
||||
if let Some(ref input_path) = sess.io.input.opt_path() {
|
||||
@ -664,6 +665,8 @@ pub static DEFAULT_EXTERN_QUERY_PROVIDERS: LazyLock<ExternProviders> = LazyLock:
|
||||
|
||||
pub fn create_global_ctxt<'tcx>(
|
||||
compiler: &'tcx Compiler,
|
||||
crate_types: Vec<CrateType>,
|
||||
stable_crate_id: StableCrateId,
|
||||
lint_store: Lrc<LintStore>,
|
||||
dep_graph: DepGraph,
|
||||
untracked: Untracked,
|
||||
@ -696,6 +699,8 @@ pub fn create_global_ctxt<'tcx>(
|
||||
gcx_cell.get_or_init(move || {
|
||||
TyCtxt::create_global_ctxt(
|
||||
sess,
|
||||
crate_types,
|
||||
stable_crate_id,
|
||||
lint_store,
|
||||
arena,
|
||||
hir_arena,
|
||||
|
@ -234,13 +234,13 @@ impl<'tcx> Queries<'tcx> {
|
||||
debug_assert_eq!(_id, CRATE_DEF_ID);
|
||||
let untracked = Untracked { cstore, source_span, definitions };
|
||||
|
||||
// FIXME: Move these fields from session to tcx and make them immutable.
|
||||
sess.init_crate_types(crate_types);
|
||||
sess.stable_crate_id.set(stable_crate_id).expect("not yet initialized");
|
||||
// FIXME: Move features from session to tcx and make them immutable.
|
||||
sess.init_features(rustc_expand::config::features(sess, &pre_configured_attrs));
|
||||
|
||||
let qcx = passes::create_global_ctxt(
|
||||
self.compiler,
|
||||
crate_types,
|
||||
stable_crate_id,
|
||||
lint_store,
|
||||
self.dep_graph(dep_graph_future),
|
||||
untracked,
|
||||
@ -320,7 +320,7 @@ impl<'tcx> Queries<'tcx> {
|
||||
|
||||
let (crate_hash, prepare_outputs, dep_graph) = self.global_ctxt()?.enter(|tcx| {
|
||||
(
|
||||
if tcx.sess.needs_crate_hash() { Some(tcx.crate_hash(LOCAL_CRATE)) } else { None },
|
||||
if tcx.needs_crate_hash() { Some(tcx.crate_hash(LOCAL_CRATE)) } else { None },
|
||||
tcx.output_filenames(()).clone(),
|
||||
tcx.dep_graph.clone(),
|
||||
)
|
||||
|
@ -545,7 +545,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
|
||||
name,
|
||||
// The all loop is because `--crate-type=rlib --crate-type=rlib` is
|
||||
// legal and produces both inside this type.
|
||||
self.sess.crate_types().iter().all(|c| *c == CrateType::Rlib),
|
||||
self.tcx.crate_types().iter().all(|c| *c == CrateType::Rlib),
|
||||
hash,
|
||||
extra_filename,
|
||||
false, // is_host
|
||||
@ -689,7 +689,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
|
||||
fn inject_panic_runtime(&mut self, krate: &ast::Crate) {
|
||||
// If we're only compiling an rlib, then there's no need to select a
|
||||
// panic runtime, so we just skip this section entirely.
|
||||
let any_non_rlib = self.sess.crate_types().iter().any(|ct| *ct != CrateType::Rlib);
|
||||
let any_non_rlib = self.tcx.crate_types().iter().any(|ct| *ct != CrateType::Rlib);
|
||||
if !any_non_rlib {
|
||||
info!("panic runtime injection skipped, only generating rlib");
|
||||
return;
|
||||
@ -818,7 +818,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
|
||||
// At this point we've determined that we need an allocator. Let's see
|
||||
// if our compilation session actually needs an allocator based on what
|
||||
// we're emitting.
|
||||
let all_rlib = self.sess.crate_types().iter().all(|ct| matches!(*ct, CrateType::Rlib));
|
||||
let all_rlib = self.tcx.crate_types().iter().all(|ct| matches!(*ct, CrateType::Rlib));
|
||||
if all_rlib {
|
||||
return;
|
||||
}
|
||||
|
@ -66,8 +66,7 @@ use rustc_session::cstore::CrateDepKind;
|
||||
use rustc_session::cstore::LinkagePreference::{self, RequireDynamic, RequireStatic};
|
||||
|
||||
pub(crate) fn calculate(tcx: TyCtxt<'_>) -> Dependencies {
|
||||
tcx.sess
|
||||
.crate_types()
|
||||
tcx.crate_types()
|
||||
.iter()
|
||||
.map(|&ty| {
|
||||
let linkage = calculate_type(tcx, ty);
|
||||
|
@ -56,7 +56,7 @@ pub fn encode_and_write_metadata(tcx: TyCtxt<'_>) -> (EncodedMetadata, bool) {
|
||||
|
||||
// Always create a file at `metadata_filename`, even if we have nothing to write to it.
|
||||
// This simplifies the creation of the output `out_filename` when requested.
|
||||
let metadata_kind = tcx.sess.metadata_kind();
|
||||
let metadata_kind = tcx.metadata_kind();
|
||||
match metadata_kind {
|
||||
MetadataKind::None => {
|
||||
std::fs::File::create(&metadata_filename).unwrap_or_else(|err| {
|
||||
|
@ -52,10 +52,11 @@ fn find_bundled_library(
|
||||
verbatim: Option<bool>,
|
||||
kind: NativeLibKind,
|
||||
has_cfg: bool,
|
||||
sess: &Session,
|
||||
tcx: TyCtxt<'_>,
|
||||
) -> Option<Symbol> {
|
||||
let sess = tcx.sess;
|
||||
if let NativeLibKind::Static { bundle: Some(true) | None, whole_archive } = kind
|
||||
&& sess.crate_types().iter().any(|t| matches!(t, &CrateType::Rlib | CrateType::Staticlib))
|
||||
&& tcx.crate_types().iter().any(|t| matches!(t, &CrateType::Rlib | CrateType::Staticlib))
|
||||
&& (sess.opts.unstable_opts.packed_bundled_libs || has_cfg || whole_archive == Some(true))
|
||||
{
|
||||
let verbatim = verbatim.unwrap_or(false);
|
||||
@ -364,7 +365,7 @@ impl<'tcx> Collector<'tcx> {
|
||||
};
|
||||
|
||||
let kind = kind.unwrap_or(NativeLibKind::Unspecified);
|
||||
let filename = find_bundled_library(name, verbatim, kind, cfg.is_some(), sess);
|
||||
let filename = find_bundled_library(name, verbatim, kind, cfg.is_some(), self.tcx);
|
||||
self.libs.push(NativeLib {
|
||||
name,
|
||||
filename,
|
||||
@ -442,9 +443,13 @@ impl<'tcx> Collector<'tcx> {
|
||||
// Add if not found
|
||||
let new_name: Option<&str> = passed_lib.new_name.as_deref();
|
||||
let name = Symbol::intern(new_name.unwrap_or(&passed_lib.name));
|
||||
let sess = self.tcx.sess;
|
||||
let filename =
|
||||
find_bundled_library(name, passed_lib.verbatim, passed_lib.kind, false, sess);
|
||||
let filename = find_bundled_library(
|
||||
name,
|
||||
passed_lib.verbatim,
|
||||
passed_lib.kind,
|
||||
false,
|
||||
self.tcx,
|
||||
);
|
||||
self.libs.push(NativeLib {
|
||||
name,
|
||||
filename,
|
||||
|
@ -1741,7 +1741,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn encode_proc_macros(&mut self) -> Option<ProcMacroData> {
|
||||
let is_proc_macro = self.tcx.sess.crate_types().contains(&CrateType::ProcMacro);
|
||||
let is_proc_macro = self.tcx.crate_types().contains(&CrateType::ProcMacro);
|
||||
if is_proc_macro {
|
||||
let tcx = self.tcx;
|
||||
let hir = tcx.hir();
|
||||
@ -2204,7 +2204,7 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) {
|
||||
source_file_cache,
|
||||
interpret_allocs: Default::default(),
|
||||
required_source_files,
|
||||
is_proc_macro: tcx.sess.crate_types().contains(&CrateType::ProcMacro),
|
||||
is_proc_macro: tcx.crate_types().contains(&CrateType::ProcMacro),
|
||||
hygiene_ctxt: &hygiene_ctxt,
|
||||
symbol_table: Default::default(),
|
||||
};
|
||||
|
@ -60,7 +60,7 @@ use crate::mir::mono::MonoItem;
|
||||
use crate::ty::TyCtxt;
|
||||
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
|
||||
use rustc_hir::definitions::DefPathHash;
|
||||
use rustc_hir::{HirId, ItemLocalId, OwnerId};
|
||||
use rustc_query_system::dep_graph::FingerprintStyle;
|
||||
@ -371,7 +371,7 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId {
|
||||
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
|
||||
if tcx.fingerprint_style(dep_node.kind) == FingerprintStyle::HirId {
|
||||
let (local_hash, local_id) = Fingerprint::from(dep_node.hash).split();
|
||||
let def_path_hash = DefPathHash::new(tcx.sess.local_stable_crate_id(), local_hash);
|
||||
let def_path_hash = DefPathHash::new(tcx.stable_crate_id(LOCAL_CRATE), local_hash);
|
||||
let def_id = tcx
|
||||
.def_path_hash_to_def_id(def_path_hash, &mut || {
|
||||
panic!("Failed to extract HirId: {:?} {}", dep_node.kind, dep_node.hash)
|
||||
|
@ -1210,7 +1210,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh {
|
||||
owner_spans.hash_stable(&mut hcx, &mut stable_hasher);
|
||||
}
|
||||
tcx.sess.opts.dep_tracking_hash(true).hash_stable(&mut hcx, &mut stable_hasher);
|
||||
tcx.sess.local_stable_crate_id().hash_stable(&mut hcx, &mut stable_hasher);
|
||||
tcx.stable_crate_id(LOCAL_CRATE).hash_stable(&mut hcx, &mut stable_hasher);
|
||||
// Hash visibility information since it does not appear in HIR.
|
||||
resolutions.visibilities.hash_stable(&mut hcx, &mut stable_hasher);
|
||||
resolutions.has_pub_restricted.hash_stable(&mut hcx, &mut stable_hasher);
|
||||
|
@ -72,6 +72,6 @@ pub fn metadata_symbol_name(tcx: TyCtxt<'_>) -> String {
|
||||
format!(
|
||||
"rust_metadata_{}_{:08x}",
|
||||
tcx.crate_name(LOCAL_CRATE),
|
||||
tcx.sess.local_stable_crate_id(),
|
||||
tcx.stable_crate_id(LOCAL_CRATE),
|
||||
)
|
||||
}
|
||||
|
@ -524,13 +524,13 @@ impl<'tcx> CodegenUnitNameBuilder<'tcx> {
|
||||
// local crate's ID. Otherwise there can be collisions between CGUs
|
||||
// instantiating stuff for upstream crates.
|
||||
let local_crate_id = if cnum != LOCAL_CRATE {
|
||||
let local_stable_crate_id = tcx.sess.local_stable_crate_id();
|
||||
let local_stable_crate_id = tcx.stable_crate_id(LOCAL_CRATE);
|
||||
format!("-in-{}.{:08x}", tcx.crate_name(LOCAL_CRATE), local_stable_crate_id)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
let stable_crate_id = tcx.sess.local_stable_crate_id();
|
||||
let stable_crate_id = tcx.stable_crate_id(LOCAL_CRATE);
|
||||
format!("{}.{:08x}{}", tcx.crate_name(cnum), stable_crate_id, local_crate_id)
|
||||
});
|
||||
|
||||
|
@ -59,8 +59,7 @@ use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
|
||||
use rustc_session::config::CrateType;
|
||||
use rustc_session::cstore::{CrateStoreDyn, Untracked};
|
||||
use rustc_session::lint::Lint;
|
||||
use rustc_session::Limit;
|
||||
use rustc_session::Session;
|
||||
use rustc_session::{Limit, MetadataKind, Session};
|
||||
use rustc_span::def_id::{DefPathHash, StableCrateId};
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
@ -527,6 +526,13 @@ pub struct GlobalCtxt<'tcx> {
|
||||
interners: CtxtInterners<'tcx>,
|
||||
|
||||
pub sess: &'tcx Session,
|
||||
crate_types: Vec<CrateType>,
|
||||
/// The `stable_crate_id` is constructed out of the crate name and all the
|
||||
/// `-C metadata` arguments passed to the compiler. Its value forms a unique
|
||||
/// global identifier for the crate. It is used to allow multiple crates
|
||||
/// with the same name to coexist. See the
|
||||
/// `rustc_symbol_mangling` crate for more information.
|
||||
stable_crate_id: StableCrateId,
|
||||
|
||||
/// This only ever stores a `LintStore` but we don't want a dependency on that type here.
|
||||
///
|
||||
@ -687,6 +693,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
/// has a valid reference to the context, to allow formatting values that need it.
|
||||
pub fn create_global_ctxt(
|
||||
s: &'tcx Session,
|
||||
crate_types: Vec<CrateType>,
|
||||
stable_crate_id: StableCrateId,
|
||||
lint_store: Lrc<dyn Any + sync::DynSend + sync::DynSync>,
|
||||
arena: &'tcx WorkerLocal<Arena<'tcx>>,
|
||||
hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
|
||||
@ -705,6 +713,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
|
||||
GlobalCtxt {
|
||||
sess: s,
|
||||
crate_types,
|
||||
stable_crate_id,
|
||||
lint_store,
|
||||
arena,
|
||||
hir_arena,
|
||||
@ -800,10 +810,47 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn crate_types(self) -> &'tcx [CrateType] {
|
||||
&self.crate_types
|
||||
}
|
||||
|
||||
pub fn metadata_kind(self) -> MetadataKind {
|
||||
self.crate_types()
|
||||
.iter()
|
||||
.map(|ty| match *ty {
|
||||
CrateType::Executable | CrateType::Staticlib | CrateType::Cdylib => {
|
||||
MetadataKind::None
|
||||
}
|
||||
CrateType::Rlib => MetadataKind::Uncompressed,
|
||||
CrateType::Dylib | CrateType::ProcMacro => MetadataKind::Compressed,
|
||||
})
|
||||
.max()
|
||||
.unwrap_or(MetadataKind::None)
|
||||
}
|
||||
|
||||
pub fn needs_metadata(self) -> bool {
|
||||
self.metadata_kind() != MetadataKind::None
|
||||
}
|
||||
|
||||
pub fn needs_crate_hash(self) -> bool {
|
||||
// Why is the crate hash needed for these configurations?
|
||||
// - debug_assertions: for the "fingerprint the result" check in
|
||||
// `rustc_query_system::query::plumbing::execute_job`.
|
||||
// - incremental: for query lookups.
|
||||
// - needs_metadata: for putting into crate metadata.
|
||||
// - instrument_coverage: for putting into coverage data (see
|
||||
// `hash_mir_source`).
|
||||
cfg!(debug_assertions)
|
||||
|| self.sess.opts.incremental.is_some()
|
||||
|| self.needs_metadata()
|
||||
|| self.sess.instrument_coverage()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
|
||||
if crate_num == LOCAL_CRATE {
|
||||
self.sess.local_stable_crate_id()
|
||||
self.stable_crate_id
|
||||
} else {
|
||||
self.cstore_untracked().stable_crate_id(crate_num)
|
||||
}
|
||||
@ -813,7 +860,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
/// that the crate in question has already been loaded by the CrateStore.
|
||||
#[inline]
|
||||
pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
|
||||
if stable_crate_id == self.sess.local_stable_crate_id() {
|
||||
if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
|
||||
LOCAL_CRATE
|
||||
} else {
|
||||
self.cstore_untracked().stable_crate_id_to_crate_num(stable_crate_id)
|
||||
@ -830,7 +877,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
|
||||
// If this is a DefPathHash from the local crate, we can look up the
|
||||
// DefId in the tcx's `Definitions`.
|
||||
if stable_crate_id == self.sess.local_stable_crate_id() {
|
||||
if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
|
||||
self.untracked.definitions.read().local_def_path_hash_to_def_id(hash, err).to_def_id()
|
||||
} else {
|
||||
// If this is a DefPathHash from an upstream crate, let the CrateStore map
|
||||
@ -847,7 +894,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
// statements within the query system and we'd run into endless
|
||||
// recursion otherwise.
|
||||
let (crate_name, stable_crate_id) = if def_id.is_local() {
|
||||
(self.crate_name(LOCAL_CRATE), self.sess.local_stable_crate_id())
|
||||
(self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
|
||||
} else {
|
||||
let cstore = &*self.cstore_untracked();
|
||||
(cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
|
||||
@ -986,7 +1033,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
pub fn local_crate_exports_generics(self) -> bool {
|
||||
debug_assert!(self.sess.opts.share_generics());
|
||||
|
||||
self.sess.crate_types().iter().any(|crate_type| {
|
||||
self.crate_types().iter().any(|crate_type| {
|
||||
match crate_type {
|
||||
CrateType::Executable
|
||||
| CrateType::Staticlib
|
||||
|
@ -31,7 +31,7 @@ struct EntryContext<'tcx> {
|
||||
}
|
||||
|
||||
fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> {
|
||||
let any_exe = tcx.sess.crate_types().iter().any(|ty| *ty == CrateType::Executable);
|
||||
let any_exe = tcx.crate_types().iter().any(|ty| *ty == CrateType::Executable);
|
||||
if !any_exe {
|
||||
// No need to find a main function.
|
||||
return None;
|
||||
|
@ -364,10 +364,10 @@ fn has_custom_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
|
||||
fn reachable_set(tcx: TyCtxt<'_>, (): ()) -> LocalDefIdSet {
|
||||
let effective_visibilities = &tcx.effective_visibilities(());
|
||||
|
||||
let any_library =
|
||||
tcx.sess.crate_types().iter().any(|ty| {
|
||||
*ty == CrateType::Rlib || *ty == CrateType::Dylib || *ty == CrateType::ProcMacro
|
||||
});
|
||||
let any_library = tcx
|
||||
.crate_types()
|
||||
.iter()
|
||||
.any(|ty| *ty == CrateType::Rlib || *ty == CrateType::Dylib || *ty == CrateType::ProcMacro);
|
||||
let mut reachable_context = ReachableContext {
|
||||
tcx,
|
||||
maybe_typeck_results: None,
|
||||
|
@ -43,7 +43,7 @@ pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems) {
|
||||
fn verify(tcx: TyCtxt<'_>, items: &lang_items::LanguageItems) {
|
||||
// We only need to check for the presence of weak lang items if we're
|
||||
// emitting something that's not an rlib.
|
||||
let needs_check = tcx.sess.crate_types().iter().any(|kind| match *kind {
|
||||
let needs_check = tcx.crate_types().iter().any(|kind| match *kind {
|
||||
CrateType::Dylib
|
||||
| CrateType::ProcMacro
|
||||
| CrateType::Cdylib
|
||||
|
@ -4374,7 +4374,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
if let Some(res) = res
|
||||
&& let Some(def_id) = res.opt_def_id()
|
||||
&& !def_id.is_local()
|
||||
&& self.r.tcx.sess.crate_types().contains(&CrateType::ProcMacro)
|
||||
&& self.r.tcx.crate_types().contains(&CrateType::ProcMacro)
|
||||
&& matches!(self.r.tcx.sess.opts.resolve_doc_links, ResolveDocLinks::ExportedMetadata) {
|
||||
// Encoding foreign def ids in proc macro crate metadata will ICE.
|
||||
return None;
|
||||
@ -4389,7 +4389,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
match self.r.tcx.sess.opts.resolve_doc_links {
|
||||
ResolveDocLinks::None => return,
|
||||
ResolveDocLinks::ExportedMetadata
|
||||
if !self.r.tcx.sess.crate_types().iter().copied().any(CrateType::has_metadata)
|
||||
if !self.r.tcx.crate_types().iter().copied().any(CrateType::has_metadata)
|
||||
|| !maybe_exported.eval(self.r) =>
|
||||
{
|
||||
return;
|
||||
@ -4448,7 +4448,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
.into_iter()
|
||||
.filter_map(|tr| {
|
||||
if !tr.def_id.is_local()
|
||||
&& self.r.tcx.sess.crate_types().contains(&CrateType::ProcMacro)
|
||||
&& self.r.tcx.crate_types().contains(&CrateType::ProcMacro)
|
||||
&& matches!(
|
||||
self.r.tcx.sess.opts.resolve_doc_links,
|
||||
ResolveDocLinks::ExportedMetadata
|
||||
|
@ -152,14 +152,6 @@ pub struct Session {
|
||||
/// Input, input file path and output file path to this compilation process.
|
||||
pub io: CompilerIO,
|
||||
|
||||
crate_types: OnceCell<Vec<CrateType>>,
|
||||
/// The `stable_crate_id` is constructed out of the crate name and all the
|
||||
/// `-C metadata` arguments passed to the compiler. Its value forms a unique
|
||||
/// global identifier for the crate. It is used to allow multiple crates
|
||||
/// with the same name to coexist. See the
|
||||
/// `rustc_symbol_mangling` crate for more information.
|
||||
pub stable_crate_id: OnceCell<StableCrateId>,
|
||||
|
||||
features: OnceCell<rustc_feature::Features>,
|
||||
|
||||
incr_comp_session: OneThread<RefCell<IncrCompSession>>,
|
||||
@ -310,55 +302,11 @@ impl Session {
|
||||
self.parse_sess.span_diagnostic.emit_future_breakage_report(diags);
|
||||
}
|
||||
|
||||
pub fn local_stable_crate_id(&self) -> StableCrateId {
|
||||
self.stable_crate_id.get().copied().unwrap()
|
||||
}
|
||||
|
||||
pub fn crate_types(&self) -> &[CrateType] {
|
||||
self.crate_types.get().unwrap().as_slice()
|
||||
}
|
||||
|
||||
/// Returns true if the crate is a testing one.
|
||||
pub fn is_test_crate(&self) -> bool {
|
||||
self.opts.test
|
||||
}
|
||||
|
||||
pub fn needs_crate_hash(&self) -> bool {
|
||||
// Why is the crate hash needed for these configurations?
|
||||
// - debug_assertions: for the "fingerprint the result" check in
|
||||
// `rustc_query_system::query::plumbing::execute_job`.
|
||||
// - incremental: for query lookups.
|
||||
// - needs_metadata: for putting into crate metadata.
|
||||
// - instrument_coverage: for putting into coverage data (see
|
||||
// `hash_mir_source`).
|
||||
cfg!(debug_assertions)
|
||||
|| self.opts.incremental.is_some()
|
||||
|| self.needs_metadata()
|
||||
|| self.instrument_coverage()
|
||||
}
|
||||
|
||||
pub fn metadata_kind(&self) -> MetadataKind {
|
||||
self.crate_types()
|
||||
.iter()
|
||||
.map(|ty| match *ty {
|
||||
CrateType::Executable | CrateType::Staticlib | CrateType::Cdylib => {
|
||||
MetadataKind::None
|
||||
}
|
||||
CrateType::Rlib => MetadataKind::Uncompressed,
|
||||
CrateType::Dylib | CrateType::ProcMacro => MetadataKind::Compressed,
|
||||
})
|
||||
.max()
|
||||
.unwrap_or(MetadataKind::None)
|
||||
}
|
||||
|
||||
pub fn needs_metadata(&self) -> bool {
|
||||
self.metadata_kind() != MetadataKind::None
|
||||
}
|
||||
|
||||
pub fn init_crate_types(&self, crate_types: Vec<CrateType>) {
|
||||
self.crate_types.set(crate_types).expect("`crate_types` was initialized twice")
|
||||
}
|
||||
|
||||
#[rustc_lint_diagnostics]
|
||||
#[track_caller]
|
||||
pub fn struct_span_warn<S: Into<MultiSpan>>(
|
||||
@ -1516,8 +1464,6 @@ pub fn build_session(
|
||||
parse_sess,
|
||||
sysroot,
|
||||
io,
|
||||
crate_types: OnceCell::new(),
|
||||
stable_crate_id: OnceCell::new(),
|
||||
features: OnceCell::new(),
|
||||
incr_comp_session: OneThread::new(RefCell::new(IncrCompSession::NotInitialized)),
|
||||
cgu_reuse_tracker,
|
||||
|
@ -63,6 +63,10 @@ pub fn trait_def(did: DefId) -> stable_mir::ty::TraitDef {
|
||||
with_tables(|t| t.trait_def(did))
|
||||
}
|
||||
|
||||
pub fn impl_def(did: DefId) -> stable_mir::ty::ImplDef {
|
||||
with_tables(|t| t.impl_def(did))
|
||||
}
|
||||
|
||||
impl<'tcx> Tables<'tcx> {
|
||||
pub fn item_def_id(&self, item: &stable_mir::CrateItem) -> DefId {
|
||||
self.def_ids[item.0]
|
||||
@ -72,6 +76,10 @@ impl<'tcx> Tables<'tcx> {
|
||||
self.def_ids[trait_def.0]
|
||||
}
|
||||
|
||||
pub fn impl_trait_def_id(&self, impl_def: &stable_mir::ty::ImplDef) -> DefId {
|
||||
self.def_ids[impl_def.0]
|
||||
}
|
||||
|
||||
pub fn crate_item(&mut self, did: DefId) -> stable_mir::CrateItem {
|
||||
stable_mir::CrateItem(self.create_def_id(did))
|
||||
}
|
||||
@ -116,6 +124,10 @@ impl<'tcx> Tables<'tcx> {
|
||||
stable_mir::ty::ConstDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn impl_def(&mut self, did: DefId) -> stable_mir::ty::ImplDef {
|
||||
stable_mir::ty::ImplDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
fn create_def_id(&mut self, did: DefId) -> stable_mir::DefId {
|
||||
// FIXME: this becomes inefficient when we have too many ids
|
||||
for (i, &d) in self.def_ids.iter().enumerate() {
|
||||
|
@ -59,6 +59,20 @@ impl<'tcx> Context for Tables<'tcx> {
|
||||
trait_def.stable(self)
|
||||
}
|
||||
|
||||
fn all_trait_impls(&mut self) -> stable_mir::ImplTraitDecls {
|
||||
self.tcx
|
||||
.trait_impls_in_crate(LOCAL_CRATE)
|
||||
.iter()
|
||||
.map(|impl_def_id| self.impl_def(*impl_def_id))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn trait_impl(&mut self, impl_def: &stable_mir::ty::ImplDef) -> stable_mir::ty::ImplTrait {
|
||||
let def_id = self.impl_trait_def_id(impl_def);
|
||||
let impl_trait = self.tcx.impl_trait_ref(def_id).unwrap();
|
||||
impl_trait.stable(self)
|
||||
}
|
||||
|
||||
fn mir_body(&mut self, item: &stable_mir::CrateItem) -> stable_mir::mir::Body {
|
||||
let def_id = self.item_def_id(item);
|
||||
let mir = self.tcx.optimized_mir(def_id);
|
||||
@ -840,6 +854,19 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, S, V> Stable<'tcx> for ty::EarlyBinder<S>
|
||||
where
|
||||
S: Stable<'tcx, T = V>,
|
||||
{
|
||||
type T = stable_mir::ty::EarlyBinder<V>;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
|
||||
use stable_mir::ty::EarlyBinder;
|
||||
|
||||
EarlyBinder { value: self.as_ref().skip_binder().stable(tables) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> {
|
||||
type T = stable_mir::ty::FnSig;
|
||||
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
|
||||
@ -1154,3 +1181,12 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::ConstantKind<'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> {
|
||||
type T = stable_mir::ty::TraitRef;
|
||||
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
|
||||
use stable_mir::ty::TraitRef;
|
||||
|
||||
TraitRef { def_id: rustc_internal::trait_def(self.def_id), args: self.args.stable(tables) }
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ use std::cell::Cell;
|
||||
|
||||
use crate::rustc_smir::Tables;
|
||||
|
||||
use self::ty::{TraitDecl, TraitDef, Ty, TyKind};
|
||||
use self::ty::{ImplDef, ImplTrait, TraitDecl, TraitDef, Ty, TyKind};
|
||||
|
||||
pub mod mir;
|
||||
pub mod ty;
|
||||
@ -32,9 +32,12 @@ pub type DefId = usize;
|
||||
/// A list of crate items.
|
||||
pub type CrateItems = Vec<CrateItem>;
|
||||
|
||||
/// A list of crate items.
|
||||
/// A list of trait decls.
|
||||
pub type TraitDecls = Vec<TraitDef>;
|
||||
|
||||
/// A list of impl trait decls.
|
||||
pub type ImplTraitDecls = Vec<ImplDef>;
|
||||
|
||||
/// Holds information about a crate.
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct Crate {
|
||||
@ -89,6 +92,8 @@ pub trait Context {
|
||||
fn mir_body(&mut self, item: &CrateItem) -> mir::Body;
|
||||
fn all_trait_decls(&mut self) -> TraitDecls;
|
||||
fn trait_decl(&mut self, trait_def: &TraitDef) -> TraitDecl;
|
||||
fn all_trait_impls(&mut self) -> ImplTraitDecls;
|
||||
fn trait_impl(&mut self, trait_impl: &ImplDef) -> ImplTrait;
|
||||
/// Get information about the local crate.
|
||||
fn local_crate(&self) -> Crate;
|
||||
/// Retrieve a list of all external crates.
|
||||
|
@ -119,6 +119,15 @@ impl TraitDef {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct ImplDef(pub(crate) DefId);
|
||||
|
||||
impl ImplDef {
|
||||
pub fn trait_impl(&self) -> ImplTrait {
|
||||
with(|cx| cx.trait_impl(self))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GenericArgs(pub Vec<GenericArgKind>);
|
||||
|
||||
@ -196,6 +205,11 @@ pub struct Binder<T> {
|
||||
pub bound_vars: Vec<BoundVariableKind>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct EarlyBinder<T> {
|
||||
pub value: T,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum BoundVariableKind {
|
||||
Ty(BoundTyKind),
|
||||
@ -432,3 +446,10 @@ pub struct TraitDecl {
|
||||
pub implement_via_object: bool,
|
||||
pub deny_explicit_impl: bool,
|
||||
}
|
||||
|
||||
pub type ImplTrait = EarlyBinder<TraitRef>;
|
||||
|
||||
pub struct TraitRef {
|
||||
pub def_id: TraitDef,
|
||||
pub args: GenericArgs,
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ fn compute_symbol_name<'tcx>(
|
||||
|
||||
if let Some(def_id) = def_id.as_local() {
|
||||
if tcx.proc_macro_decls_static(()) == Some(def_id) {
|
||||
let stable_crate_id = tcx.sess.local_stable_crate_id();
|
||||
let stable_crate_id = tcx.stable_crate_id(LOCAL_CRATE);
|
||||
return tcx.sess.generate_proc_macro_decls_symbol(stable_crate_id);
|
||||
}
|
||||
}
|
||||
|
@ -19,21 +19,25 @@ rustc_index::newtype_index! {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(super) struct ProvisionalEntry<'tcx> {
|
||||
// In case we have a coinductive cycle, this is the
|
||||
// the currently least restrictive result of this goal.
|
||||
pub(super) response: QueryResult<'tcx>,
|
||||
// In case of a cycle, the position of deepest stack entry involved
|
||||
// in that cycle. This is monotonically decreasing in the stack as all
|
||||
// elements between the current stack element in the deepest stack entry
|
||||
// involved have to also be involved in that cycle.
|
||||
//
|
||||
// We can only move entries to the global cache once we're complete done
|
||||
// with the cycle. If this entry has not been involved in a cycle,
|
||||
// this is just its own depth.
|
||||
/// In case we have a coinductive cycle, this is the
|
||||
/// the current provisional result of this goal.
|
||||
///
|
||||
/// This starts out as `None` for all goals and gets to some
|
||||
/// when the goal gets popped from the stack or we rerun evaluation
|
||||
/// for this goal to reach a fixpoint.
|
||||
pub(super) response: Option<QueryResult<'tcx>>,
|
||||
/// In case of a cycle, the position of deepest stack entry involved
|
||||
/// in that cycle. This is monotonically decreasing in the stack as all
|
||||
/// elements between the current stack element in the deepest stack entry
|
||||
/// involved have to also be involved in that cycle.
|
||||
///
|
||||
/// We can only move entries to the global cache once we're complete done
|
||||
/// with the cycle. If this entry has not been involved in a cycle,
|
||||
/// this is just its own depth.
|
||||
pub(super) depth: StackDepth,
|
||||
|
||||
// The goal for this entry. Should always be equal to the corresponding goal
|
||||
// in the lookup table.
|
||||
/// The goal for this entry. Should always be equal to the corresponding goal
|
||||
/// in the lookup table.
|
||||
pub(super) input: CanonicalInput<'tcx>,
|
||||
}
|
||||
|
||||
@ -92,7 +96,7 @@ impl<'tcx> ProvisionalCache<'tcx> {
|
||||
self.entries[entry_index].depth
|
||||
}
|
||||
|
||||
pub(super) fn provisional_result(&self, entry_index: EntryIndex) -> QueryResult<'tcx> {
|
||||
pub(super) fn provisional_result(&self, entry_index: EntryIndex) -> Option<QueryResult<'tcx>> {
|
||||
self.entries[entry_index].response
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ use rustc_middle::traits::solve::CacheData;
|
||||
use rustc_middle::traits::solve::{CanonicalInput, Certainty, EvaluationCache, QueryResult};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::Limit;
|
||||
use std::{collections::hash_map::Entry, mem};
|
||||
use std::collections::hash_map::Entry;
|
||||
|
||||
rustc_index::newtype_index! {
|
||||
pub struct StackDepth {}
|
||||
@ -216,8 +216,8 @@ impl<'tcx> SearchGraph<'tcx> {
|
||||
cycle_participants: Default::default(),
|
||||
};
|
||||
assert_eq!(self.stack.push(entry), depth);
|
||||
let response = Self::response_no_constraints(tcx, input, Certainty::Yes);
|
||||
let entry_index = cache.entries.push(ProvisionalEntry { response, depth, input });
|
||||
let entry_index =
|
||||
cache.entries.push(ProvisionalEntry { response: None, depth, input });
|
||||
v.insert(entry_index);
|
||||
}
|
||||
// We have a nested goal which relies on a goal `root` deeper in the stack.
|
||||
@ -243,23 +243,31 @@ impl<'tcx> SearchGraph<'tcx> {
|
||||
root.cycle_participants.insert(e.input);
|
||||
}
|
||||
|
||||
// NOTE: The goals on the stack aren't the only goals involved in this cycle.
|
||||
// We can also depend on goals which aren't part of the stack but coinductively
|
||||
// depend on the stack themselves. We already checked whether all the goals
|
||||
// between these goals and their root on the stack. This means that as long as
|
||||
// each goal in a cycle is checked for coinductivity by itself, simply checking
|
||||
// the stack is enough.
|
||||
if self.stack.raw[stack_depth.index()..]
|
||||
.iter()
|
||||
.all(|g| g.input.value.goal.predicate.is_coinductive(tcx))
|
||||
{
|
||||
// If we're in a coinductive cycle, we have to retry proving the current goal
|
||||
// until we reach a fixpoint.
|
||||
self.stack[stack_depth].has_been_used = true;
|
||||
return cache.provisional_result(entry_index);
|
||||
// If we're in a cycle, we have to retry proving the current goal
|
||||
// until we reach a fixpoint.
|
||||
self.stack[stack_depth].has_been_used = true;
|
||||
return if let Some(result) = cache.provisional_result(entry_index) {
|
||||
result
|
||||
} else {
|
||||
return Self::response_no_constraints(tcx, input, Certainty::OVERFLOW);
|
||||
}
|
||||
// If we don't have a provisional result yet, the goal has to
|
||||
// still be on the stack.
|
||||
let mut goal_on_stack = false;
|
||||
let mut is_coinductive = true;
|
||||
for entry in self.stack.raw[stack_depth.index()..]
|
||||
.iter()
|
||||
.skip_while(|entry| entry.input != input)
|
||||
{
|
||||
goal_on_stack = true;
|
||||
is_coinductive &= entry.input.value.goal.predicate.is_coinductive(tcx);
|
||||
}
|
||||
debug_assert!(goal_on_stack);
|
||||
|
||||
if is_coinductive {
|
||||
Self::response_no_constraints(tcx, input, Certainty::Yes)
|
||||
} else {
|
||||
Self::response_no_constraints(tcx, input, Certainty::OVERFLOW)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -288,15 +296,18 @@ impl<'tcx> SearchGraph<'tcx> {
|
||||
let provisional_entry_index =
|
||||
*cache.lookup_table.get(&stack_entry.input).unwrap();
|
||||
let provisional_entry = &mut cache.entries[provisional_entry_index];
|
||||
let prev_response = mem::replace(&mut provisional_entry.response, response);
|
||||
if stack_entry.has_been_used && prev_response != response {
|
||||
// If so, remove all entries whose result depends on this goal
|
||||
// from the provisional cache...
|
||||
if stack_entry.has_been_used
|
||||
&& provisional_entry.response.map_or(true, |r| r != response)
|
||||
{
|
||||
// If so, update the provisional result for this goal and remove
|
||||
// all entries whose result depends on this goal from the provisional
|
||||
// cache...
|
||||
//
|
||||
// That's not completely correct, as a nested goal can also
|
||||
// That's not completely correct, as a nested goal can also only
|
||||
// depend on a goal which is lower in the stack so it doesn't
|
||||
// actually depend on the current goal. This should be fairly
|
||||
// rare and is hopefully not relevant for performance.
|
||||
provisional_entry.response = Some(response);
|
||||
#[allow(rustc::potential_query_instability)]
|
||||
cache.lookup_table.retain(|_key, index| *index <= provisional_entry_index);
|
||||
cache.entries.truncate(provisional_entry_index.index() + 1);
|
||||
@ -315,8 +326,8 @@ impl<'tcx> SearchGraph<'tcx> {
|
||||
});
|
||||
|
||||
// We're now done with this goal. In case this goal is involved in a larger cycle
|
||||
// do not remove it from the provisional cache and do not add it to the global
|
||||
// cache.
|
||||
// do not remove it from the provisional cache and update its provisional result.
|
||||
// We only add the root of cycles to the global cache.
|
||||
//
|
||||
// It is not possible for any nested goal to depend on something deeper on the
|
||||
// stack, as this would have also updated the depth of the current goal.
|
||||
@ -348,6 +359,8 @@ impl<'tcx> SearchGraph<'tcx> {
|
||||
dep_node,
|
||||
result,
|
||||
)
|
||||
} else {
|
||||
provisional_entry.response = Some(result);
|
||||
}
|
||||
|
||||
result
|
||||
|
@ -2394,7 +2394,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||
Ok(args) => args,
|
||||
Err(()) => {
|
||||
// FIXME: A rematch may fail when a candidate cache hit occurs
|
||||
// on thefreshened form of the trait predicate, but the match
|
||||
// on the freshened form of the trait predicate, but the match
|
||||
// fails for some reason that is not captured in the freshened
|
||||
// cache key. For example, equating an impl trait ref against
|
||||
// the placeholder trait ref may fail due the Generalizer relation
|
||||
|
@ -200,7 +200,9 @@ pub enum TyKind<I: Interner> {
|
||||
/// A tuple type. For example, `(i32, bool)`.
|
||||
Tuple(I::ListTy),
|
||||
|
||||
/// A projection or opaque type. Both of these types
|
||||
/// A projection, opaque type, weak type alias, or inherent associated type.
|
||||
/// All of these types are represented as pairs of def-id and args, and can
|
||||
/// be normalized, so they are grouped conceptually.
|
||||
Alias(AliasKind, I::AliasTy),
|
||||
|
||||
/// A type parameter; for example, `T` in `fn f<T>(x: T) {}`.
|
||||
|
@ -74,7 +74,6 @@ fn is_executable_or_proc_macro(cx: &LateContext<'_>) -> bool {
|
||||
use rustc_session::config::CrateType;
|
||||
|
||||
cx.tcx
|
||||
.sess
|
||||
.crate_types()
|
||||
.iter()
|
||||
.any(|t: &CrateType| matches!(t, CrateType::Executable | CrateType::ProcMacro))
|
||||
|
@ -69,7 +69,7 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
|
||||
}
|
||||
|
||||
init_late_loggers(handler, tcx);
|
||||
if !tcx.sess.crate_types().contains(&CrateType::Executable) {
|
||||
if !tcx.crate_types().contains(&CrateType::Executable) {
|
||||
tcx.sess.fatal("miri only makes sense on bin crates");
|
||||
}
|
||||
|
||||
|
15
tests/ui/lazy-type-alias/leading-where-clause.fixed
Normal file
15
tests/ui/lazy-type-alias/leading-where-clause.fixed
Normal file
@ -0,0 +1,15 @@
|
||||
// run-rustfix
|
||||
|
||||
#![feature(lazy_type_alias)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
// Check that we *reject* leading where-clauses on lazy type aliases.
|
||||
|
||||
type Alias<T>
|
||||
|
||||
= T where String: From<T>;
|
||||
//~^^^ ERROR where clauses are not allowed before the type for type aliases
|
||||
|
||||
fn main() {
|
||||
let _: Alias<&str>;
|
||||
}
|
16
tests/ui/lazy-type-alias/leading-where-clause.rs
Normal file
16
tests/ui/lazy-type-alias/leading-where-clause.rs
Normal file
@ -0,0 +1,16 @@
|
||||
// run-rustfix
|
||||
|
||||
#![feature(lazy_type_alias)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
// Check that we *reject* leading where-clauses on lazy type aliases.
|
||||
|
||||
type Alias<T>
|
||||
where
|
||||
String: From<T>,
|
||||
= T;
|
||||
//~^^^ ERROR where clauses are not allowed before the type for type aliases
|
||||
|
||||
fn main() {
|
||||
let _: Alias<&str>;
|
||||
}
|
16
tests/ui/lazy-type-alias/leading-where-clause.stderr
Normal file
16
tests/ui/lazy-type-alias/leading-where-clause.stderr
Normal file
@ -0,0 +1,16 @@
|
||||
error: where clauses are not allowed before the type for type aliases
|
||||
--> $DIR/leading-where-clause.rs:9:1
|
||||
|
|
||||
LL | / where
|
||||
LL | | String: From<T>,
|
||||
| |____________________^
|
||||
|
|
||||
= note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
|
||||
help: move it to the end of the type declaration
|
||||
|
|
||||
LL +
|
||||
LL ~ = T where String: From<T>;
|
||||
|
|
||||
|
||||
error: aborting due to previous error
|
||||
|
13
tests/ui/lazy-type-alias/trailing-where-clause.rs
Normal file
13
tests/ui/lazy-type-alias/trailing-where-clause.rs
Normal file
@ -0,0 +1,13 @@
|
||||
#![feature(lazy_type_alias)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
// Check that we allow & respect trailing where-clauses on lazy type aliases.
|
||||
|
||||
type Alias<T> = T
|
||||
where
|
||||
String: From<T>;
|
||||
|
||||
fn main() {
|
||||
let _: Alias<&str>;
|
||||
let _: Alias<()>; //~ ERROR the trait bound `String: From<()>` is not satisfied
|
||||
}
|
22
tests/ui/lazy-type-alias/trailing-where-clause.stderr
Normal file
22
tests/ui/lazy-type-alias/trailing-where-clause.stderr
Normal file
@ -0,0 +1,22 @@
|
||||
error[E0277]: the trait bound `String: From<()>` is not satisfied
|
||||
--> $DIR/trailing-where-clause.rs:12:12
|
||||
|
|
||||
LL | let _: Alias<()>;
|
||||
| ^^^^^^^^^ the trait `From<()>` is not implemented for `String`
|
||||
|
|
||||
= help: the following other types implement trait `From<T>`:
|
||||
<String as From<char>>
|
||||
<String as From<Box<str>>>
|
||||
<String as From<Cow<'a, str>>>
|
||||
<String as From<&str>>
|
||||
<String as From<&mut str>>
|
||||
<String as From<&String>>
|
||||
note: required by a bound on the type alias `Alias`
|
||||
--> $DIR/trailing-where-clause.rs:8:13
|
||||
|
|
||||
LL | String: From<T>;
|
||||
| ^^^^^^^ required by this bound
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
@ -0,0 +1,37 @@
|
||||
// compile-flags: -Ztrait-solver=next
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
// Test that having both an inductive and a coinductive cycle
|
||||
// is handled correctly.
|
||||
|
||||
#[rustc_coinductive]
|
||||
trait Trait {}
|
||||
impl<T: Inductive + Coinductive> Trait for T {}
|
||||
|
||||
trait Inductive {}
|
||||
impl<T: Trait> Inductive for T {}
|
||||
#[rustc_coinductive]
|
||||
trait Coinductive {}
|
||||
impl<T: Trait> Coinductive for T {}
|
||||
|
||||
fn impls_trait<T: Trait>() {}
|
||||
|
||||
#[rustc_coinductive]
|
||||
trait TraitRev {}
|
||||
impl<T: CoinductiveRev + InductiveRev> TraitRev for T {}
|
||||
|
||||
trait InductiveRev {}
|
||||
impl<T: TraitRev> InductiveRev for T {}
|
||||
#[rustc_coinductive]
|
||||
trait CoinductiveRev {}
|
||||
impl<T: TraitRev> CoinductiveRev for T {}
|
||||
|
||||
fn impls_trait_rev<T: TraitRev>() {}
|
||||
|
||||
fn main() {
|
||||
impls_trait::<()>();
|
||||
//~^ ERROR overflow evaluating the requirement
|
||||
|
||||
impls_trait_rev::<()>();
|
||||
//~^ ERROR overflow evaluating the requirement
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
error[E0275]: overflow evaluating the requirement `(): Trait`
|
||||
--> $DIR/double-cycle-inductive-coinductive.rs:32:5
|
||||
|
|
||||
LL | impls_trait::<()>();
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`double_cycle_inductive_coinductive`)
|
||||
note: required by a bound in `impls_trait`
|
||||
--> $DIR/double-cycle-inductive-coinductive.rs:17:19
|
||||
|
|
||||
LL | fn impls_trait<T: Trait>() {}
|
||||
| ^^^^^ required by this bound in `impls_trait`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `(): TraitRev`
|
||||
--> $DIR/double-cycle-inductive-coinductive.rs:35:5
|
||||
|
|
||||
LL | impls_trait_rev::<()>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`double_cycle_inductive_coinductive`)
|
||||
note: required by a bound in `impls_trait_rev`
|
||||
--> $DIR/double-cycle-inductive-coinductive.rs:29:23
|
||||
|
|
||||
LL | fn impls_trait_rev<T: TraitRev>() {}
|
||||
| ^^^^^^^^ required by this bound in `impls_trait_rev`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0275`.
|
48
tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.rs
Normal file
48
tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.rs
Normal file
@ -0,0 +1,48 @@
|
||||
// compile-flags: -Ztrait-solver=next
|
||||
#![feature(trivial_bounds, marker_trait_attr)]
|
||||
#![allow(trivial_bounds)]
|
||||
// This previously triggered a bug in the provisional cache.
|
||||
//
|
||||
// This has the proof tree
|
||||
// - `MultipleCandidates: Trait` proven via impl-one
|
||||
// - `MultipleNested: Trait` via impl
|
||||
// - `MultipleCandidates: Trait` (inductive cycle ~> OVERFLOW)
|
||||
// - `DoesNotImpl: Trait` (ERR)
|
||||
// - `MultipleCandidates: Trait` proven via impl-two
|
||||
// - `MultipleNested: Trait` (in provisional cache ~> OVERFLOW)
|
||||
//
|
||||
// We previously incorrectly treated the `MultipleCandidates: Trait` as
|
||||
// overflow because it was in the cache and reached via an inductive cycle.
|
||||
// It should be `NoSolution`.
|
||||
|
||||
struct MultipleCandidates;
|
||||
struct MultipleNested;
|
||||
struct DoesNotImpl;
|
||||
|
||||
#[marker]
|
||||
trait Trait {}
|
||||
|
||||
// impl-one
|
||||
impl Trait for MultipleCandidates
|
||||
where
|
||||
MultipleNested: Trait
|
||||
{}
|
||||
|
||||
// impl-two
|
||||
impl Trait for MultipleCandidates
|
||||
where
|
||||
MultipleNested: Trait,
|
||||
{}
|
||||
|
||||
impl Trait for MultipleNested
|
||||
where
|
||||
MultipleCandidates: Trait,
|
||||
DoesNotImpl: Trait,
|
||||
{}
|
||||
|
||||
fn impls_trait<T: Trait>() {}
|
||||
|
||||
fn main() {
|
||||
impls_trait::<MultipleCandidates>();
|
||||
//~^ ERROR the trait bound `MultipleCandidates: Trait` is not satisfied
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
error[E0277]: the trait bound `MultipleCandidates: Trait` is not satisfied
|
||||
--> $DIR/inductive-cycle-but-err.rs:46:19
|
||||
|
|
||||
LL | impls_trait::<MultipleCandidates>();
|
||||
| ^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `MultipleCandidates`
|
||||
|
|
||||
= help: the trait `Trait` is implemented for `MultipleCandidates`
|
||||
note: required by a bound in `impls_trait`
|
||||
--> $DIR/inductive-cycle-but-err.rs:43:19
|
||||
|
|
||||
LL | fn impls_trait<T: Trait>() {}
|
||||
| ^^^^^ required by this bound in `impls_trait`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
44
tests/ui/traits/new-solver/cycles/inductive-cycle-but-ok.rs
Normal file
44
tests/ui/traits/new-solver/cycles/inductive-cycle-but-ok.rs
Normal file
@ -0,0 +1,44 @@
|
||||
// compile-flags: -Ztrait-solver=next
|
||||
// check-pass
|
||||
#![feature(trivial_bounds, marker_trait_attr)]
|
||||
#![allow(trivial_bounds)]
|
||||
|
||||
// This previously triggered a bug in the provisional cache.
|
||||
//
|
||||
// This has the proof tree
|
||||
// - `Root: Trait` proven via impl
|
||||
// - `MultipleCandidates: Trait`
|
||||
// - candidate: overflow-impl
|
||||
// - `Root: Trait` (inductive cycle ~> OVERFLOW)
|
||||
// - candidate: trivial-impl ~> YES
|
||||
// - merge respones ~> YES
|
||||
// - `MultipleCandidates: Trait` (in provisional cache ~> OVERFLOW)
|
||||
//
|
||||
// We previously incorrectly treated the `MultipleCandidates: Trait` as
|
||||
// overflow because it was in the cache and reached via an inductive cycle.
|
||||
// It should be `YES`.
|
||||
|
||||
struct Root;
|
||||
struct MultipleCandidates;
|
||||
|
||||
#[marker]
|
||||
trait Trait {}
|
||||
impl Trait for Root
|
||||
where
|
||||
MultipleCandidates: Trait,
|
||||
MultipleCandidates: Trait,
|
||||
{}
|
||||
|
||||
// overflow-impl
|
||||
impl Trait for MultipleCandidates
|
||||
where
|
||||
Root: Trait,
|
||||
{}
|
||||
// trivial-impl
|
||||
impl Trait for MultipleCandidates {}
|
||||
|
||||
fn impls_trait<T: Trait>() {}
|
||||
|
||||
fn main() {
|
||||
impls_trait::<Root>();
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
// check-pass
|
||||
// compile-flags: -Ztrait-solver=next
|
||||
#![feature(rustc_attrs, marker_trait_attr)]
|
||||
#[rustc_coinductive]
|
||||
trait Trait {}
|
||||
|
||||
impl<T, U> Trait for (T, U)
|
||||
where
|
||||
(U, T): Trait,
|
||||
(T, U): Inductive,
|
||||
(): ConstrainToU32<T>,
|
||||
{}
|
||||
|
||||
trait ConstrainToU32<T> {}
|
||||
impl ConstrainToU32<u32> for () {}
|
||||
|
||||
// We only prefer the candidate without an inductive cycle
|
||||
// once the inductive cycle has the same constraints as the
|
||||
// other goal.
|
||||
#[marker]
|
||||
trait Inductive {}
|
||||
impl<T, U> Inductive for (T, U)
|
||||
where
|
||||
(T, U): Trait,
|
||||
{}
|
||||
|
||||
impl Inductive for (u32, u32) {}
|
||||
|
||||
fn impls_trait<T, U>()
|
||||
where
|
||||
(T, U): Trait,
|
||||
{}
|
||||
|
||||
fn main() {
|
||||
impls_trait::<_, _>();
|
||||
}
|
@ -39,7 +39,7 @@ fn impls_ar<T: AR>() {}
|
||||
|
||||
fn main() {
|
||||
impls_a::<()>();
|
||||
//~^ ERROR overflow evaluating the requirement `(): A`
|
||||
// FIXME(-Ztrait-solver=next): This is broken and should error.
|
||||
|
||||
impls_ar::<()>();
|
||||
//~^ ERROR overflow evaluating the requirement `(): AR`
|
||||
|
@ -1,16 +1,3 @@
|
||||
error[E0275]: overflow evaluating the requirement `(): A`
|
||||
--> $DIR/inductive-not-on-stack.rs:41:5
|
||||
|
|
||||
LL | impls_a::<()>();
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_not_on_stack`)
|
||||
note: required by a bound in `impls_a`
|
||||
--> $DIR/inductive-not-on-stack.rs:25:15
|
||||
|
|
||||
LL | fn impls_a<T: A>() {}
|
||||
| ^ required by this bound in `impls_a`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `(): AR`
|
||||
--> $DIR/inductive-not-on-stack.rs:44:5
|
||||
|
|
||||
@ -24,6 +11,6 @@ note: required by a bound in `impls_ar`
|
||||
LL | fn impls_ar<T: AR>() {}
|
||||
| ^^ required by this bound in `impls_ar`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0275`.
|
||||
|
@ -1,5 +1,5 @@
|
||||
// check-pass
|
||||
// compile-flags: -Ztrait-solver=next
|
||||
// check-pass
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
#[rustc_coinductive]
|
@ -1,6 +1,10 @@
|
||||
// compile-flags: -Ztrait-solver=next
|
||||
// check-pass
|
||||
|
||||
// Test that selection prefers the builtin trait object impl for `Any`
|
||||
// instead of the user defined impl. Both impls apply to the trait
|
||||
// object.
|
||||
|
||||
use std::any::Any;
|
||||
|
||||
fn needs_usize(_: &usize) {}
|
||||
|
@ -4,7 +4,8 @@ error: where clauses are not allowed after the type for type aliases
|
||||
LL | type Bar = () where u32: Copy;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
|
||||
= note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
|
||||
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable
|
||||
|
||||
error: where clauses are not allowed after the type for type aliases
|
||||
--> $DIR/where-clause-placement-type-alias.rs:8:15
|
||||
@ -12,7 +13,8 @@ error: where clauses are not allowed after the type for type aliases
|
||||
LL | type Baz = () where;
|
||||
| ^^^^^
|
||||
|
|
||||
= note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
|
||||
= note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
|
||||
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -527,7 +527,6 @@ bootstrap = [
|
||||
]
|
||||
infra-ci = [
|
||||
"@Mark-Simulacrum",
|
||||
"@pietroalbini",
|
||||
]
|
||||
rustdoc = [
|
||||
"@jsha",
|
||||
|
Loading…
x
Reference in New Issue
Block a user