Skip to content

Rollup of 8 pull requests #101282

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 31 commits into from
Closed
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
38de102
Support eager and lazy methods for providing references and values
shepmaster Jul 21, 2022
260ec93
Add `Provider::{would_be_satisfied_by_value_of,would_be_satisfied_by_…
shepmaster Jul 22, 2022
81a583c
Try normalizing types without RevealAll in ParamEnv in mir validation
Noratrieb Aug 3, 2022
96d4137
Only normalize once in mir validator typechecker
Noratrieb Aug 6, 2022
c846a2a
Make `std::os::fd` public.
sunfishcode Jun 14, 2022
09bbc42
Update asrawfd.js.
sunfishcode Jun 22, 2022
bda1262
Clarify that the `fd` module is supported on Unix and WASI.
sunfishcode Jun 30, 2022
7d80510
Re-introduce `unstable` attributes.
sunfishcode Aug 23, 2022
b9d3f65
[drop tracking] Use parent expression for scope
eholk Aug 30, 2022
803e35a
Remove unneeded extra whitespace before where clause
GuillaumeGomez Aug 31, 2022
4304d1d
Update rustdoc tests
GuillaumeGomez Aug 31, 2022
b112bfe
Add rustdoc GUI test
GuillaumeGomez Aug 31, 2022
54645e8
set up rustc_metadata for SessionDiagnostics, port dependency_format.rs
CleanCut Aug 23, 2022
3ed9310
port native_libs.rs to SessionDiagnostics
CleanCut Aug 23, 2022
f7e462a
port encoder.rs to SessionDiagnostics
CleanCut Aug 23, 2022
32e1823
port creader.rs to SessionDiagnostics
CleanCut Aug 23, 2022
bd8e312
port fs.rs to SessionDiagnostics
CleanCut Aug 23, 2022
d0ba1fb
port of locator.rs to SessionDiagnostics, fix some of the errors
CleanCut Aug 24, 2022
0d65819
respond to review feedback: mainly eliminate as many conversions as p…
CleanCut Aug 26, 2022
30adfd6
port 5 new diagnostics that appeared in master
CleanCut Aug 27, 2022
f921f56
Use parent_iter instead of a find_parent_node loop
eholk Aug 31, 2022
a928255
Fix bad target name in Walkthrough
diminishedprime Aug 31, 2022
d8b572b
Tweaks to fuchsia doc walkthrough
andrewpollack Aug 31, 2022
eb14b5d
Rollup merge of #98368 - sunfishcode:sunfishcode/std-os-fd, r=joshtri…
Dylan-DPC Sep 1, 2022
fbe63c2
Rollup merge of #99583 - shepmaster:provider-plus-plus, r=yaahc
Dylan-DPC Sep 1, 2022
6a3a886
Rollup merge of #100121 - Nilstrieb:mir-validator-param-env, r=oli-obk
Dylan-DPC Sep 1, 2022
1116b4d
Rollup merge of #100928 - CleanCut:rustc_metadata_diagnostics, r=davi…
Dylan-DPC Sep 1, 2022
7298451
Rollup merge of #101217 - eholk:drop-tracking-73137, r=jyn514
Dylan-DPC Sep 1, 2022
4e07938
Rollup merge of #101245 - GuillaumeGomez:remove-unneeded-where-whites…
Dylan-DPC Sep 1, 2022
4c92e64
Rollup merge of #101251 - diminishedprime:patch-1, r=JohnTitor
Dylan-DPC Sep 1, 2022
8c9564e
Rollup merge of #101256 - andrewpollack:fuchsia-docs-adding, r=tmandry
Dylan-DPC Sep 1, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -3519,6 +3519,7 @@ dependencies = [
"rustc_macros",
"rustc_serialize",
"rustc_span",
"rustc_target",
"serde",
"serde_json",
"termcolor",
17 changes: 12 additions & 5 deletions compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
@@ -181,16 +181,23 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
if (src, dest).has_opaque_types() {
return true;
}
// Normalize projections and things like that.
let param_env = self.param_env.with_reveal_all_normalized(self.tcx);
let src = self.tcx.normalize_erasing_regions(param_env, src);
let dest = self.tcx.normalize_erasing_regions(param_env, dest);

// Normalize projections and things like that.
// Type-changing assignments can happen when subtyping is used. While
// all normal lifetimes are erased, higher-ranked types with their
// late-bound lifetimes are still around and can lead to type
// differences. So we compare ignoring lifetimes.
equal_up_to_regions(self.tcx, param_env, src, dest)

// First, try with reveal_all. This might not work in some cases, as the predicates
// can be cleared in reveal_all mode. We try the reveal first anyways as it is used
// by some other passes like inlining as well.
let param_env = self.param_env.with_reveal_all_normalized(self.tcx);
if equal_up_to_regions(self.tcx, param_env, src, dest) {
return true;
}

// If this fails, we can try it without the reveal.
equal_up_to_regions(self.tcx, self.param_env, src, dest)
}
}

272 changes: 272 additions & 0 deletions compiler/rustc_error_messages/locales/en-US/metadata.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
metadata_rlib_required =
crate `{$crate_name}` required to be available in rlib format, but was not found in this form
metadata_lib_required =
crate `{$crate_name}` required to be available in {$kind} format, but was not found in this form
metadata_crate_dep_multiple =
cannot satisfy dependencies so `{$crate_name}` only shows up once
.help = having upstream crates all available in one format will likely make this go away
metadata_two_panic_runtimes =
cannot link together two panic runtimes: {$prev_name} and {$cur_name}
metadata_bad_panic_strategy =
the linked panic runtime `{$runtime}` is not compiled with this crate's panic strategy `{$strategy}`
metadata_required_panic_strategy =
the crate `{$crate_name}` requires panic strategy `{$found_strategy}` which is incompatible with this crate's strategy of `{$desired_strategy}`
metadata_incompatible_panic_in_drop_strategy =
the crate `{$crate_name}` is compiled with the panic-in-drop strategy `{$found_strategy}` which is incompatible with this crate's strategy of `{$desired_strategy}`
metadata_multiple_names_in_link =
multiple `name` arguments in a single `#[link]` attribute
metadata_multiple_kinds_in_link =
multiple `kind` arguments in a single `#[link]` attribute
metadata_link_name_form =
link name must be of the form `name = "string"`
metadata_link_kind_form =
link kind must be of the form `kind = "string"`
metadata_link_modifiers_form =
link modifiers must be of the form `modifiers = "string"`
metadata_link_cfg_form =
link cfg must be of the form `cfg(/* predicate */)`
metadata_wasm_import_form =
wasm import module must be of the form `wasm_import_module = "string"`
metadata_empty_link_name =
link name must not be empty
.label = empty link name
metadata_link_framework_apple =
link kind `framework` is only supported on Apple targets
metadata_framework_only_windows =
link kind `raw-dylib` is only supported on Windows targets
metadata_unknown_link_kind =
unknown link kind `{$kind}`, expected one of: static, dylib, framework, raw-dylib
.label = unknown link kind
metadata_multiple_link_modifiers =
multiple `modifiers` arguments in a single `#[link]` attribute
metadata_multiple_cfgs =
multiple `cfg` arguments in a single `#[link]` attribute
metadata_link_cfg_single_predicate =
link cfg must have a single predicate argument
metadata_multiple_wasm_import =
multiple `wasm_import_module` arguments in a single `#[link]` attribute
metadata_unexpected_link_arg =
unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module, import_name_type
metadata_invalid_link_modifier =
invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed
metadata_multiple_modifiers =
multiple `{$modifier}` modifiers in a single `modifiers` argument
metadata_bundle_needs_static =
linking modifier `bundle` is only compatible with `static` linking kind
metadata_whole_archive_needs_static =
linking modifier `whole-archive` is only compatible with `static` linking kind
metadata_as_needed_compatibility =
linking modifier `as-needed` is only compatible with `dylib` and `framework` linking kinds
metadata_unknown_link_modifier =
unknown linking modifier `{$modifier}`, expected one of: bundle, verbatim, whole-archive, as-needed
metadata_incompatible_wasm_link =
`wasm_import_module` is incompatible with other arguments in `#[link]` attributes
metadata_link_requires_name =
`#[link]` attribute requires a `name = "string"` argument
.label = missing `name` argument
metadata_raw_dylib_no_nul =
link name must not contain NUL characters if link kind is `raw-dylib`
metadata_link_ordinal_raw_dylib =
`#[link_ordinal]` is only supported if link kind is `raw-dylib`
metadata_lib_framework_apple =
library kind `framework` is only supported on Apple targets
metadata_empty_renaming_target =
an empty renaming target was specified for library `{$lib_name}`
metadata_renaming_no_link =
renaming of the library `{$lib_name}` was specified, however this crate contains no `#[link(...)]` attributes referencing this library
metadata_multiple_renamings =
multiple renamings were specified for library `{$lib_name}`
metadata_no_link_mod_override =
overriding linking modifiers from command line is not supported
metadata_unsupported_abi_i686 =
ABI not supported by `#[link(kind = "raw-dylib")]` on i686
metadata_unsupported_abi =
ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture
metadata_fail_create_file_encoder =
failed to create file encoder: {$err}
metadata_fail_seek_file =
failed to seek the file: {$err}
metadata_fail_write_file =
failed to write to the file: {$err}
metadata_crate_not_panic_runtime =
the crate `{$crate_name}` is not a panic runtime
metadata_no_panic_strategy =
the crate `{$crate_name}` does not have the panic strategy `{$strategy}`
metadata_profiler_builtins_needs_core =
`profiler_builtins` crate (required by compiler options) is not compatible with crate attribute `#![no_core]`
metadata_not_profiler_runtime =
the crate `{$crate_name}` is not a profiler runtime
metadata_no_multiple_global_alloc =
cannot define multiple global allocators
.label = cannot define a new global allocator
metadata_prev_global_alloc =
previous global allocator defined here
metadata_conflicting_global_alloc =
the `#[global_allocator]` in {$other_crate_name} conflicts with global allocator in: {$crate_name}
metadata_global_alloc_required =
no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait
metadata_no_transitive_needs_dep =
the crate `{$crate_name}` cannot depend on a crate that needs {$needs_crate_name}, but it depends on `{$deps_crate_name}`
metadata_failed_write_error =
failed to write {$filename}: {$err}
metadata_failed_create_tempdir =
couldn't create a temp dir: {$err}
metadata_failed_create_file =
failed to create the file {$filename}: {$err}
metadata_failed_create_encoded_metadata =
failed to create encoded metadata from file: {$err}
metadata_non_ascii_name =
cannot load a crate with a non-ascii name `{$crate_name}`
metadata_extern_location_not_exist =
extern location for {$crate_name} does not exist: {$location}
metadata_extern_location_not_file =
extern location for {$crate_name} is not a file: {$location}
metadata_multiple_candidates =
multiple {$flavor} candidates for `{$crate_name}` found
metadata_multiple_matching_crates =
multiple matching crates for `{$crate_name}`
.note = candidates:{$candidates}
metadata_symbol_conflicts_current =
the current crate is indistinguishable from one of its dependencies: it has the same crate-name `{$crate_name}` and was compiled with the same `-C metadata` arguments. This will result in symbol conflicts between the two.
metadata_symbol_conflicts_others =
found two different crates with name `{$crate_name}` that are not distinguished by differing `-C metadata`. This will result in symbol conflicts between the two.
metadata_stable_crate_id_collision =
found crates (`{$crate_name0}` and `{$crate_name1}`) with colliding StableCrateId values.
metadata_dl_error =
{$err}
metadata_newer_crate_version =
found possibly newer version of crate `{$crate_name}`{$add_info}
.note = perhaps that crate needs to be recompiled?
metadata_found_crate_versions =
the following crate versions were found:{$found_crates}
metadata_no_crate_with_triple =
couldn't find crate `{$crate_name}` with expected target triple {$locator_triple}{$add_info}
metadata_found_staticlib =
found staticlib `{$crate_name}` instead of rlib or dylib{$add_info}
.help = please recompile that crate using --crate-type lib
metadata_incompatible_rustc =
found crate `{$crate_name}` compiled by an incompatible version of rustc{$add_info}
.help = please recompile that crate using this compiler ({$rustc_version}) (consider running `cargo clean` first)
metadata_invalid_meta_files =
found invalid metadata files for crate `{$crate_name}`{$add_info}
metadata_cannot_find_crate =
can't find crate for `{$crate_name}`{$add_info}
metadata_no_dylib_plugin =
plugin `{$crate_name}` only found in rlib format, but must be available in dylib format
metadata_target_not_installed =
the `{$locator_triple}` target may not be installed
metadata_target_no_std_support =
the `{$locator_triple}` target may not support the standard library
metadata_consider_downloading_target =
consider downloading the target with `rustup target add {$locator_triple}`
metadata_std_required =
`std` is required by `{$current_crate}` because it does not declare `#![no_std]`
metadata_consider_building_std =
consider building the standard library from source with `cargo build -Zbuild-std`
metadata_compiler_missing_profiler =
the compiler may have been built without the profiler runtime
metadata_install_missing_components =
maybe you need to install the missing components with: `rustup component add rust-src rustc-dev llvm-tools-preview`
metadata_cant_find_crate =
can't find crate
metadata_crate_location_unknown_type =
extern location for {$crate_name} is of an unknown type: {$path}
metadata_lib_filename_form =
file name should be lib*.rlib or {dll_prefix}*.{dll_suffix}
metadata_multiple_import_name_type =
multiple `import_name_type` arguments in a single `#[link]` attribute
metadata_import_name_type_form =
import name type must be of the form `import_name_type = "string"`
metadata_import_name_type_x86 =
import name type is only supported on x86
metadata_unknown_import_name_type =
unknown import name type `{$import_name_type}`, expected one of: decorated, noprefix, undecorated
metadata_import_name_type_raw =
import name type can only be used with link kind `raw-dylib`
1 change: 1 addition & 0 deletions compiler/rustc_error_messages/src/lib.rs
Original file line number Diff line number Diff line change
@@ -46,6 +46,7 @@ fluent_messages! {
infer => "../locales/en-US/infer.ftl",
lint => "../locales/en-US/lint.ftl",
monomorphize => "../locales/en-US/monomorphize.ftl",
metadata => "../locales/en-US/metadata.ftl",
parser => "../locales/en-US/parser.ftl",
passes => "../locales/en-US/passes.ftl",
plugin_impl => "../locales/en-US/plugin_impl.ftl",
5 changes: 3 additions & 2 deletions compiler/rustc_errors/Cargo.toml
Original file line number Diff line number Diff line change
@@ -15,13 +15,14 @@ rustc_macros = { path = "../rustc_macros" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_hir = { path = "../rustc_hir" }
rustc_lint_defs = { path = "../rustc_lint_defs" }
rustc_target = { path = "../rustc_target" }
unicode-width = "0.1.4"
atty = "0.2"
termcolor = "1.0"
annotate-snippets = "0.9"
termize = "0.1.1"
serde = { version = "1.0.125", features = ["derive"] }
serde = { version = "1.0.125", features = [ "derive" ] }
serde_json = "1.0.59"

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["handleapi", "synchapi", "winbase"] }
winapi = { version = "0.3", features = [ "handleapi", "synchapi", "winbase" ] }
7 changes: 7 additions & 0 deletions compiler/rustc_errors/src/diagnostic.rs
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@ use rustc_lint_defs::{Applicability, LintExpectationId};
use rustc_span::edition::LATEST_STABLE_EDITION;
use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol};
use rustc_span::{edition::Edition, Span, DUMMY_SP};
use rustc_target::spec::PanicStrategy;
use std::borrow::Cow;
use std::fmt;
use std::hash::{Hash, Hasher};
@@ -144,6 +145,12 @@ impl IntoDiagnosticArg for usize {
}
}

impl IntoDiagnosticArg for PanicStrategy {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
DiagnosticArgValue::Str(Cow::Owned(self.desc().to_string()))
}
}

impl<'source> Into<FluentValue<'source>> for DiagnosticArgValue<'source> {
fn into(self) -> FluentValue<'source> {
match self {
53 changes: 19 additions & 34 deletions compiler/rustc_metadata/src/creader.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
//! Validates all used crates and extern libraries and loads their metadata
use crate::errors::{
ConflictingGlobalAlloc, CrateNotPanicRuntime, GlobalAllocRequired, NoMultipleGlobalAlloc,
NoPanicStrategy, NoTransitiveNeedsDep, NotProfilerRuntime, ProfilerBuiltinsNeedsCore,
};
use crate::locator::{CrateError, CrateLocator, CratePaths};
use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob};

@@ -746,15 +750,10 @@ impl<'a> CrateLoader<'a> {
// Sanity check the loaded crate to ensure it is indeed a panic runtime
// and the panic strategy is indeed what we thought it was.
if !data.is_panic_runtime() {
self.sess.err(&format!("the crate `{}` is not a panic runtime", name));
self.sess.emit_err(CrateNotPanicRuntime { crate_name: name });
}
if data.required_panic_strategy() != Some(desired_strategy) {
self.sess.err(&format!(
"the crate `{}` does not have the panic \
strategy `{}`",
name,
desired_strategy.desc()
));
self.sess.emit_err(NoPanicStrategy { crate_name: name, strategy: desired_strategy });
}

self.cstore.injected_panic_runtime = Some(cnum);
@@ -774,29 +773,22 @@ impl<'a> CrateLoader<'a> {

let name = Symbol::intern(&self.sess.opts.unstable_opts.profiler_runtime);
if name == sym::profiler_builtins && self.sess.contains_name(&krate.attrs, sym::no_core) {
self.sess.err(
"`profiler_builtins` crate (required by compiler options) \
is not compatible with crate attribute `#![no_core]`",
);
self.sess.emit_err(ProfilerBuiltinsNeedsCore);
}

let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else { return; };
let data = self.cstore.get_crate_data(cnum);

// Sanity check the loaded crate to ensure it is indeed a profiler runtime
if !data.is_profiler_runtime() {
self.sess.err(&format!("the crate `{}` is not a profiler runtime", name));
self.sess.emit_err(NotProfilerRuntime { crate_name: name });
}
}

fn inject_allocator_crate(&mut self, krate: &ast::Crate) {
self.cstore.has_global_allocator = match &*global_allocator_spans(&self.sess, krate) {
[span1, span2, ..] => {
self.sess
.struct_span_err(*span2, "cannot define multiple global allocators")
.span_label(*span2, "cannot define a new global allocator")
.span_label(*span1, "previous global allocator defined here")
.emit();
self.sess.emit_err(NoMultipleGlobalAlloc { span2: *span2, span1: *span1 });
true
}
spans => !spans.is_empty(),
@@ -832,11 +824,10 @@ impl<'a> CrateLoader<'a> {
if data.has_global_allocator() {
match global_allocator {
Some(other_crate) => {
self.sess.err(&format!(
"the `#[global_allocator]` in {} conflicts with global allocator in: {}",
other_crate,
data.name()
));
self.sess.emit_err(ConflictingGlobalAlloc {
crate_name: data.name(),
other_crate_name: other_crate,
});
}
None => global_allocator = Some(data.name()),
}
@@ -855,10 +846,7 @@ impl<'a> CrateLoader<'a> {
if !self.sess.contains_name(&krate.attrs, sym::default_lib_allocator)
&& !self.cstore.iter_crate_data().any(|(_, data)| data.has_default_lib_allocator())
{
self.sess.err(
"no global memory allocator found but one is required; link to std or add \
`#[global_allocator]` to a static item that implements the GlobalAlloc trait",
);
self.sess.emit_err(GlobalAllocRequired);
}
self.cstore.allocator_kind = Some(AllocatorKind::Default);
}
@@ -882,14 +870,11 @@ impl<'a> CrateLoader<'a> {
for dep in self.cstore.crate_dependencies_in_reverse_postorder(krate) {
let data = self.cstore.get_crate_data(dep);
if needs_dep(&data) {
self.sess.err(&format!(
"the crate `{}` cannot depend \
on a crate that needs {}, but \
it depends on `{}`",
self.cstore.get_crate_data(krate).name(),
what,
data.name()
));
self.sess.emit_err(NoTransitiveNeedsDep {
crate_name: self.cstore.get_crate_data(krate).name(),
needs_crate_name: what,
deps_crate_name: data.name(),
});
}
}

73 changes: 21 additions & 52 deletions compiler/rustc_metadata/src/dependency_format.rs
Original file line number Diff line number Diff line change
@@ -52,6 +52,10 @@
//! than finding a number of solutions (there are normally quite a few).
use crate::creader::CStore;
use crate::errors::{
BadPanicStrategy, CrateDepMultiple, IncompatiblePanicInDropStrategy, LibRequired,
RequiredPanicStrategy, RlibRequired, TwoPanicRuntimes,
};

use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def_id::CrateNum;
@@ -136,11 +140,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
if src.rlib.is_some() {
continue;
}
sess.err(&format!(
"crate `{}` required to be available in rlib format, \
but was not found in this form",
tcx.crate_name(cnum)
));
sess.emit_err(RlibRequired { crate_name: tcx.crate_name(cnum) });
}
return Vec::new();
}
@@ -224,12 +224,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
Linkage::Static => "rlib",
_ => "dylib",
};
sess.err(&format!(
"crate `{}` required to be available in {} format, \
but was not found in this form",
tcx.crate_name(cnum),
kind
));
sess.emit_err(LibRequired { crate_name: tcx.crate_name(cnum), kind: kind });
}
}
}
@@ -253,17 +248,7 @@ fn add_library(
// This error is probably a little obscure, but I imagine that it
// can be refined over time.
if link2 != link || link == RequireStatic {
tcx.sess
.struct_err(&format!(
"cannot satisfy dependencies so `{}` only \
shows up once",
tcx.crate_name(cnum)
))
.help(
"having upstream crates all available in one format \
will likely make this go away",
)
.emit();
tcx.sess.emit_err(CrateDepMultiple { crate_name: tcx.crate_name(cnum) });
}
}
None => {
@@ -360,11 +345,7 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) {
if let Some((prev, _)) = panic_runtime {
let prev_name = tcx.crate_name(prev);
let cur_name = tcx.crate_name(cnum);
sess.err(&format!(
"cannot link together two \
panic runtimes: {} and {}",
prev_name, cur_name
));
sess.emit_err(TwoPanicRuntimes { prev_name, cur_name });
}
panic_runtime = Some((
cnum,
@@ -384,13 +365,10 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) {
// First up, validate that our selected panic runtime is indeed exactly
// our same strategy.
if found_strategy != desired_strategy {
sess.err(&format!(
"the linked panic runtime `{}` is \
not compiled with this crate's \
panic strategy `{}`",
tcx.crate_name(runtime_cnum),
desired_strategy.desc()
));
sess.emit_err(BadPanicStrategy {
runtime: tcx.crate_name(runtime_cnum),
strategy: desired_strategy,
});
}

// Next up, verify that all other crates are compatible with this panic
@@ -407,28 +385,19 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) {
}

if let Some(found_strategy) = tcx.required_panic_strategy(cnum) && desired_strategy != found_strategy {
sess.err(&format!(
"the crate `{}` requires \
panic strategy `{}` which is \
incompatible with this crate's \
strategy of `{}`",
tcx.crate_name(cnum),
found_strategy.desc(),
desired_strategy.desc()
));
sess.emit_err(RequiredPanicStrategy {
crate_name: tcx.crate_name(cnum),
found_strategy,
desired_strategy});
}

let found_drop_strategy = tcx.panic_in_drop_strategy(cnum);
if tcx.sess.opts.unstable_opts.panic_in_drop != found_drop_strategy {
sess.err(&format!(
"the crate `{}` is compiled with the \
panic-in-drop strategy `{}` which is \
incompatible with this crate's \
strategy of `{}`",
tcx.crate_name(cnum),
found_drop_strategy.desc(),
tcx.sess.opts.unstable_opts.panic_in_drop.desc()
));
sess.emit_err(IncompatiblePanicInDropStrategy {
crate_name: tcx.crate_name(cnum),
found_strategy: found_drop_strategy,
desired_strategy: tcx.sess.opts.unstable_opts.panic_in_drop,
});
}
}
}
672 changes: 672 additions & 0 deletions compiler/rustc_metadata/src/errors.rs

Large diffs are not rendered by default.

25 changes: 12 additions & 13 deletions compiler/rustc_metadata/src/fs.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use crate::errors::{
FailedCreateEncodedMetadata, FailedCreateFile, FailedCreateTempdir, FailedWriteError,
};
use crate::{encode_metadata, EncodedMetadata};

use rustc_data_structures::temp_dir::MaybeTempDir;
@@ -23,8 +26,8 @@ pub fn emit_metadata(sess: &Session, metadata: &[u8], tmpdir: &MaybeTempDir) ->
let out_filename = tmpdir.as_ref().join(METADATA_FILENAME);
let result = fs::write(&out_filename, metadata);

if let Err(e) = result {
sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));
if let Err(err) = result {
sess.emit_fatal(FailedWriteError { filename: out_filename, err });
}

out_filename
@@ -65,20 +68,16 @@ pub fn encode_and_write_metadata(
let metadata_tmpdir = TempFileBuilder::new()
.prefix("rmeta")
.tempdir_in(out_filename.parent().unwrap_or_else(|| Path::new("")))
.unwrap_or_else(|err| tcx.sess.fatal(&format!("couldn't create a temp dir: {}", err)));
.unwrap_or_else(|err| tcx.sess.emit_fatal(FailedCreateTempdir { err }));
let metadata_tmpdir = MaybeTempDir::new(metadata_tmpdir, tcx.sess.opts.cg.save_temps);
let metadata_filename = metadata_tmpdir.as_ref().join(METADATA_FILENAME);

// 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.
match metadata_kind {
MetadataKind::None => {
std::fs::File::create(&metadata_filename).unwrap_or_else(|e| {
tcx.sess.fatal(&format!(
"failed to create the file {}: {}",
metadata_filename.display(),
e
))
std::fs::File::create(&metadata_filename).unwrap_or_else(|err| {
tcx.sess.emit_fatal(FailedCreateFile { filename: &metadata_filename, err });
});
}
MetadataKind::Uncompressed | MetadataKind::Compressed => {
@@ -93,8 +92,8 @@ pub fn encode_and_write_metadata(
// this file always exists.
let need_metadata_file = tcx.sess.opts.output_types.contains_key(&OutputType::Metadata);
let (metadata_filename, metadata_tmpdir) = if need_metadata_file {
if let Err(e) = non_durable_rename(&metadata_filename, &out_filename) {
tcx.sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));
if let Err(err) = non_durable_rename(&metadata_filename, &out_filename) {
tcx.sess.emit_fatal(FailedWriteError { filename: out_filename, err });
}
if tcx.sess.opts.json_artifact_notifications {
tcx.sess
@@ -109,8 +108,8 @@ pub fn encode_and_write_metadata(

// Load metadata back to memory: codegen may need to include it in object files.
let metadata =
EncodedMetadata::from_path(metadata_filename, metadata_tmpdir).unwrap_or_else(|e| {
tcx.sess.fatal(&format!("failed to create encoded metadata from file: {}", e))
EncodedMetadata::from_path(metadata_filename, metadata_tmpdir).unwrap_or_else(|err| {
tcx.sess.emit_fatal(FailedCreateEncodedMetadata { err });
});

let need_metadata_module = metadata_kind == MetadataKind::Compressed;
3 changes: 3 additions & 0 deletions compiler/rustc_metadata/src/lib.rs
Original file line number Diff line number Diff line change
@@ -16,6 +16,8 @@
#![feature(never_type)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]

extern crate proc_macro;

@@ -34,6 +36,7 @@ mod native_libs;
mod rmeta;

pub mod creader;
pub mod errors;
pub mod fs;
pub mod locator;

328 changes: 122 additions & 206 deletions compiler/rustc_metadata/src/locator.rs

Large diffs are not rendered by default.

201 changes: 58 additions & 143 deletions compiler/rustc_metadata/src/native_libs.rs

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::errors::{FailCreateFileEncoder, FailSeekFile, FailWriteFile};
use crate::rmeta::def_path_hash_map::DefPathHashMapRef;
use crate::rmeta::table::TableBuilder;
use crate::rmeta::*;
@@ -2269,7 +2270,7 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path) {

fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) {
let mut encoder = opaque::FileEncoder::new(path)
.unwrap_or_else(|err| tcx.sess.fatal(&format!("failed to create file encoder: {}", err)));
.unwrap_or_else(|err| tcx.sess.emit_fatal(FailCreateFileEncoder { err }));
encoder.emit_raw_bytes(METADATA_HEADER);

// Will be filled with the root position after encoding everything.
@@ -2314,10 +2315,10 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) {
// Encode the root position.
let header = METADATA_HEADER.len();
file.seek(std::io::SeekFrom::Start(header as u64))
.unwrap_or_else(|err| tcx.sess.fatal(&format!("failed to seek the file: {}", err)));
.unwrap_or_else(|err| tcx.sess.emit_fatal(FailSeekFile { err }));
let pos = root.position.get();
file.write_all(&[(pos >> 24) as u8, (pos >> 16) as u8, (pos >> 8) as u8, (pos >> 0) as u8])
.unwrap_or_else(|err| tcx.sess.fatal(&format!("failed to write to the file: {}", err)));
.unwrap_or_else(|err| tcx.sess.emit_fatal(FailWriteFile { err }));

// Return to the position where we are before writing the root position.
file.seek(std::io::SeekFrom::Start(pos_before_seek)).unwrap();
3 changes: 3 additions & 0 deletions compiler/rustc_middle/src/hir/map/mod.rs
Original file line number Diff line number Diff line change
@@ -291,6 +291,9 @@ impl<'hir> Map<'hir> {
Some(def_kind)
}

/// Finds the id of the parent node to this one.
///
/// If calling repeatedly and iterating over parents, prefer [`Map::parent_iter`].
pub fn find_parent_node(self, id: HirId) -> Option<HirId> {
if id.local_id == ItemLocalId::from_u32(0) {
Some(self.tcx.hir_owner_parent(id.owner))
11 changes: 9 additions & 2 deletions compiler/rustc_typeck/src/check/generator_interior.rs
Original file line number Diff line number Diff line change
@@ -409,8 +409,15 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
}) {
self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id)
} else {
debug!("parent_node: {:?}", self.fcx.tcx.hir().find_parent_node(expr.hir_id));
match self.fcx.tcx.hir().find_parent_node(expr.hir_id) {
let parent_expr = self
.fcx
.tcx
.hir()
.parent_iter(expr.hir_id)
.find(|(_, node)| matches!(node, hir::Node::Expr(_)))
.map(|(id, _)| id);
debug!("parent_expr: {:?}", parent_expr);
match parent_expr {
Some(parent) => Some(Scope { id: parent.local_id, data: ScopeData::Node }),
None => {
self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id)
Original file line number Diff line number Diff line change
@@ -159,8 +159,8 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> {
bk: rustc_middle::ty::BorrowKind,
) {
debug!(
"borrow: place_with_id = {place_with_id:?}, diag_expr_id={diag_expr_id:?}, \
borrow_kind={bk:?}"
"borrow: place_with_id = {place_with_id:#?}, diag_expr_id={diag_expr_id:#?}, \
borrow_kind={bk:#?}"
);

self.borrow_place(place_with_id);
239 changes: 233 additions & 6 deletions library/core/src/any.rs
Original file line number Diff line number Diff line change
@@ -796,7 +796,7 @@ pub trait Provider {
/// impl Provider for SomeConcreteType {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
/// demand.provide_ref::<str>(&self.field)
/// .provide_value::<i32>(|| self.num_field);
/// .provide_value::<i32>(self.num_field);
/// }
/// }
/// ```
@@ -881,36 +881,64 @@ impl<'a> Demand<'a> {
///
/// # Examples
///
/// Provides an `u8`.
///
/// ```rust
/// #![feature(provide_any)]
///
/// use std::any::{Provider, Demand};
/// # struct SomeConcreteType { field: u8 }
///
/// impl Provider for SomeConcreteType {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
/// demand.provide_value::<u8>(self.field);
/// }
/// }
/// ```
#[unstable(feature = "provide_any", issue = "96024")]
pub fn provide_value<T>(&mut self, value: T) -> &mut Self
where
T: 'static,
{
self.provide::<tags::Value<T>>(value)
}

/// Provide a value or other type with only static lifetimes computed using a closure.
///
/// # Examples
///
/// Provides a `String` by cloning.
///
/// ```rust
/// # #![feature(provide_any)]
/// #![feature(provide_any)]
///
/// use std::any::{Provider, Demand};
/// # struct SomeConcreteType { field: String }
///
/// impl Provider for SomeConcreteType {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
/// demand.provide_value::<String>(|| self.field.clone());
/// demand.provide_value_with::<String>(|| self.field.clone());
/// }
/// }
/// ```
#[unstable(feature = "provide_any", issue = "96024")]
pub fn provide_value<T>(&mut self, fulfil: impl FnOnce() -> T) -> &mut Self
pub fn provide_value_with<T>(&mut self, fulfil: impl FnOnce() -> T) -> &mut Self
where
T: 'static,
{
self.provide_with::<tags::Value<T>>(fulfil)
}

/// Provide a reference, note that the referee type must be bounded by `'static`,
/// Provide a reference. The referee type must be bounded by `'static`,
/// but may be unsized.
///
/// # Examples
///
/// Provides a reference to a field as a `&str`.
///
/// ```rust
/// # #![feature(provide_any)]
/// #![feature(provide_any)]
///
/// use std::any::{Provider, Demand};
/// # struct SomeConcreteType { field: String }
///
@@ -925,6 +953,40 @@ impl<'a> Demand<'a> {
self.provide::<tags::Ref<tags::MaybeSizedValue<T>>>(value)
}

/// Provide a reference computed using a closure. The referee type
/// must be bounded by `'static`, but may be unsized.
///
/// # Examples
///
/// Provides a reference to a field as a `&str`.
///
/// ```rust
/// #![feature(provide_any)]
///
/// use std::any::{Provider, Demand};
/// # struct SomeConcreteType { business: String, party: String }
/// # fn today_is_a_weekday() -> bool { true }
///
/// impl Provider for SomeConcreteType {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
/// demand.provide_ref_with::<str>(|| {
/// if today_is_a_weekday() {
/// &self.business
/// } else {
/// &self.party
/// }
/// });
/// }
/// }
/// ```
#[unstable(feature = "provide_any", issue = "96024")]
pub fn provide_ref_with<T: ?Sized + 'static>(
&mut self,
fulfil: impl FnOnce() -> &'a T,
) -> &mut Self {
self.provide_with::<tags::Ref<tags::MaybeSizedValue<T>>>(fulfil)
}

/// Provide a value with the given `Type` tag.
fn provide<I>(&mut self, value: I::Reified) -> &mut Self
where
@@ -946,6 +1008,156 @@ impl<'a> Demand<'a> {
}
self
}

/// Check if the `Demand` would be satisfied if provided with a
/// value of the specified type. If the type does not match or has
/// already been provided, returns false.
///
/// # Examples
///
/// Check if an `u8` still needs to be provided and then provides
/// it.
///
/// ```rust
/// #![feature(provide_any)]
///
/// use std::any::{Provider, Demand};
///
/// struct Parent(Option<u8>);
///
/// impl Provider for Parent {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
/// if let Some(v) = self.0 {
/// demand.provide_value::<u8>(v);
/// }
/// }
/// }
///
/// struct Child {
/// parent: Parent,
/// }
///
/// impl Child {
/// // Pretend that this takes a lot of resources to evaluate.
/// fn an_expensive_computation(&self) -> Option<u8> {
/// Some(99)
/// }
/// }
///
/// impl Provider for Child {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
/// // In general, we don't know if this call will provide
/// // an `u8` value or not...
/// self.parent.provide(demand);
///
/// // ...so we check to see if the `u8` is needed before
/// // we run our expensive computation.
/// if demand.would_be_satisfied_by_value_of::<u8>() {
/// if let Some(v) = self.an_expensive_computation() {
/// demand.provide_value::<u8>(v);
/// }
/// }
///
/// // The demand will be satisfied now, regardless of if
/// // the parent provided the value or we did.
/// assert!(!demand.would_be_satisfied_by_value_of::<u8>());
/// }
/// }
///
/// let parent = Parent(Some(42));
/// let child = Child { parent };
/// assert_eq!(Some(42), std::any::request_value::<u8>(&child));
///
/// let parent = Parent(None);
/// let child = Child { parent };
/// assert_eq!(Some(99), std::any::request_value::<u8>(&child));
/// ```
#[unstable(feature = "provide_any", issue = "96024")]
pub fn would_be_satisfied_by_value_of<T>(&self) -> bool
where
T: 'static,
{
self.would_be_satisfied_by::<tags::Value<T>>()
}

/// Check if the `Demand` would be satisfied if provided with a
/// reference to a value of the specified type. If the type does
/// not match or has already been provided, returns false.
///
/// # Examples
///
/// Check if a `&str` still needs to be provided and then provides
/// it.
///
/// ```rust
/// #![feature(provide_any)]
///
/// use std::any::{Provider, Demand};
///
/// struct Parent(Option<String>);
///
/// impl Provider for Parent {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
/// if let Some(v) = &self.0 {
/// demand.provide_ref::<str>(v);
/// }
/// }
/// }
///
/// struct Child {
/// parent: Parent,
/// name: String,
/// }
///
/// impl Child {
/// // Pretend that this takes a lot of resources to evaluate.
/// fn an_expensive_computation(&self) -> Option<&str> {
/// Some(&self.name)
/// }
/// }
///
/// impl Provider for Child {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
/// // In general, we don't know if this call will provide
/// // a `str` reference or not...
/// self.parent.provide(demand);
///
/// // ...so we check to see if the `&str` is needed before
/// // we run our expensive computation.
/// if demand.would_be_satisfied_by_ref_of::<str>() {
/// if let Some(v) = self.an_expensive_computation() {
/// demand.provide_ref::<str>(v);
/// }
/// }
///
/// // The demand will be satisfied now, regardless of if
/// // the parent provided the reference or we did.
/// assert!(!demand.would_be_satisfied_by_ref_of::<str>());
/// }
/// }
///
/// let parent = Parent(Some("parent".into()));
/// let child = Child { parent, name: "child".into() };
/// assert_eq!(Some("parent"), std::any::request_ref::<str>(&child));
///
/// let parent = Parent(None);
/// let child = Child { parent, name: "child".into() };
/// assert_eq!(Some("child"), std::any::request_ref::<str>(&child));
/// ```
#[unstable(feature = "provide_any", issue = "96024")]
pub fn would_be_satisfied_by_ref_of<T>(&self) -> bool
where
T: ?Sized + 'static,
{
self.would_be_satisfied_by::<tags::Ref<tags::MaybeSizedValue<T>>>()
}

fn would_be_satisfied_by<I>(&self) -> bool
where
I: tags::Type<'a>,
{
matches!(self.0.downcast::<I>(), Some(TaggedOption(None)))
}
}

#[unstable(feature = "provide_any", issue = "96024")]
@@ -1050,6 +1262,21 @@ impl<'a> dyn Erased<'a> + 'a {
/// Returns some reference to the dynamic value if it is tagged with `I`,
/// or `None` otherwise.
#[inline]
fn downcast<I>(&self) -> Option<&TaggedOption<'a, I>>
where
I: tags::Type<'a>,
{
if self.tag_id() == TypeId::of::<I>() {
// SAFETY: Just checked whether we're pointing to an I.
Some(unsafe { &*(self as *const Self).cast::<TaggedOption<'a, I>>() })
} else {
None
}
}

/// Returns some mutable reference to the dynamic value if it is tagged with `I`,
/// or `None` otherwise.
#[inline]
fn downcast_mut<I>(&mut self) -> Option<&mut TaggedOption<'a, I>>
where
I: tags::Type<'a>,
2 changes: 1 addition & 1 deletion library/core/tests/any.rs
Original file line number Diff line number Diff line change
@@ -142,7 +142,7 @@ impl Provider for SomeConcreteType {
demand
.provide_ref::<String>(&self.some_string)
.provide_ref::<str>(&self.some_string)
.provide_value::<String>(|| "bye".to_owned());
.provide_value_with::<String>(|| "bye".to_owned());
}
}

13 changes: 11 additions & 2 deletions library/std/src/os/fd/mod.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
//! Owned and borrowed Unix-like file descriptors.
//!
//! This module is supported on Unix platforms and WASI, which both use a
//! similar file descriptor system for referencing OS resources.
#![stable(feature = "io_safety", since = "1.63.0")]
#![deny(unsafe_op_in_unsafe_fn)]

// `RawFd`, `AsRawFd`, etc.
pub mod raw;
mod raw;

// `OwnedFd`, `AsFd`, etc.
pub mod owned;
mod owned;

// Implementations for `AsRawFd` etc. for network types.
mod net;

#[cfg(test)]
mod tests;

// Export the types and traits for the public API.
#[unstable(feature = "os_fd", issue = "98699")]
pub use owned::*;
#[unstable(feature = "os_fd", issue = "98699")]
pub use raw::*;
5 changes: 1 addition & 4 deletions library/std/src/os/fd/owned.rs
Original file line number Diff line number Diff line change
@@ -205,10 +205,7 @@ pub trait AsFd {
/// ```rust,no_run
/// use std::fs::File;
/// # use std::io;
/// # #[cfg(target_os = "wasi")]
/// # use std::os::wasi::io::{AsFd, BorrowedFd};
/// # #[cfg(unix)]
/// # use std::os::unix::io::{AsFd, BorrowedFd};
/// # use std::os::fd::{AsFd, BorrowedFd};
///
/// let mut f = File::open("foo.txt")?;
/// # #[cfg(any(unix, target_os = "wasi"))]
15 changes: 3 additions & 12 deletions library/std/src/os/fd/raw.rs
Original file line number Diff line number Diff line change
@@ -42,10 +42,7 @@ pub trait AsRawFd {
/// ```no_run
/// use std::fs::File;
/// # use std::io;
/// #[cfg(unix)]
/// use std::os::unix::io::{AsRawFd, RawFd};
/// #[cfg(target_os = "wasi")]
/// use std::os::wasi::io::{AsRawFd, RawFd};
/// use std::os::fd::{AsRawFd, RawFd};
///
/// let mut f = File::open("foo.txt")?;
/// // Note that `raw_fd` is only valid as long as `f` exists.
@@ -83,10 +80,7 @@ pub trait FromRawFd {
/// ```no_run
/// use std::fs::File;
/// # use std::io;
/// #[cfg(unix)]
/// use std::os::unix::io::{FromRawFd, IntoRawFd, RawFd};
/// #[cfg(target_os = "wasi")]
/// use std::os::wasi::io::{FromRawFd, IntoRawFd, RawFd};
/// use std::os::fd::{FromRawFd, IntoRawFd, RawFd};
///
/// let f = File::open("foo.txt")?;
/// # #[cfg(any(unix, target_os = "wasi"))]
@@ -121,10 +115,7 @@ pub trait IntoRawFd {
/// ```no_run
/// use std::fs::File;
/// # use std::io;
/// #[cfg(unix)]
/// use std::os::unix::io::{IntoRawFd, RawFd};
/// #[cfg(target_os = "wasi")]
/// use std::os::wasi::io::{IntoRawFd, RawFd};
/// use std::os::fd::{IntoRawFd, RawFd};
///
/// let f = File::open("foo.txt")?;
/// #[cfg(any(unix, target_os = "wasi"))]
2 changes: 1 addition & 1 deletion library/std/src/os/mod.rs
Original file line number Diff line number Diff line change
@@ -147,7 +147,7 @@ pub mod solid;
pub mod vxworks;

#[cfg(any(unix, target_os = "wasi", doc))]
mod fd;
pub mod fd;

#[cfg(any(target_os = "linux", target_os = "android", doc))]
mod net;
8 changes: 0 additions & 8 deletions library/std/src/os/unix/io/fd.rs

This file was deleted.

11 changes: 5 additions & 6 deletions library/std/src/os/unix/io/mod.rs
Original file line number Diff line number Diff line change
@@ -77,10 +77,9 @@
#![stable(feature = "rust1", since = "1.0.0")]

mod fd;
mod raw;

#[stable(feature = "io_safety", since = "1.63.0")]
pub use fd::*;
#[stable(feature = "rust1", since = "1.0.0")]
pub use raw::*;
pub use crate::os::fd::*;

// Tests for this module
#[cfg(test)]
mod tests;
6 changes: 0 additions & 6 deletions library/std/src/os/unix/io/raw.rs

This file was deleted.

File renamed without changes.
8 changes: 1 addition & 7 deletions library/std/src/os/wasi/io/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
//! WASI-specific extensions to general I/O primitives.
#![deny(unsafe_op_in_unsafe_fn)]
#![unstable(feature = "wasi_ext", issue = "71213")]

mod fd;
mod raw;

#[unstable(feature = "wasi_ext", issue = "71213")]
pub use fd::*;
#[unstable(feature = "wasi_ext", issue = "71213")]
pub use raw::*;
pub use crate::os::fd::*;
30 changes: 19 additions & 11 deletions src/doc/rustc/src/platform-support/fuchsia.md
Original file line number Diff line number Diff line change
@@ -79,7 +79,7 @@ the following commands:

```sh
rustup target add x86_64-fuchsia
rustup target add aarch_64-fuchsia
rustup target add aarch64-fuchsia
```

After installing our Fuchsia targets, we can now compile a Rust binary that targets
@@ -125,13 +125,20 @@ during compilation:
[target.x86_64-fuchsia]
rustflags = [
"-Lnative", "<SDK_PATH>/arch/x64/sysroot/lib",
"-Lnative", "<SDK_PATH>/arch/x64/lib"
"-Lnative=<SDK_PATH>/arch/x64/lib",
"-Lnative=<SDK_PATH>/arch/x64/sysroot/lib"
]
```

*Note: Make sure to fill out `<SDK_PATH>` with the path to the downloaded [Fuchsia SDK].*

These options configure the following:

* `-Lnative=${SDK_PATH}/arch/${ARCH}/lib`: Link against Fuchsia libraries from
the SDK
* `-Lnative=${SDK_PATH}/arch/${ARCH}/sysroot/lib`: Link against Fuchsia kernel
libraries from the SDK

In total, our new project will look like:

**Current directory structure**
@@ -368,6 +375,7 @@ language called CML. The Fuchsia devsite contains an [overview of CML] and a
}
```

**Current directory structure**
```txt
hello_fuchsia/
┗━ pkg/
@@ -386,6 +394,9 @@ ${SDK_PATH}/tools/${ARCH}/cmc compile \
-o pkg/meta/hello_fuchsia.cm
```

*Note: `--includepath` tells the compiler where to look for `include`s from our CML.
In our case, we're only using `syslog/client.shard.cml`.*

**Current directory structure**
```txt
hello_fuchsia/
@@ -397,19 +408,16 @@ hello_fuchsia/
┗━ hello_fuchsia.cml
```

*Note: `--includepath` tells the compiler where to look for `include`s from our CML.
In our case, we're only using `syslog/client.shard.cml`.*

### Building a Fuchsia package

Next, we'll build a package manifest as defined by our manifest:

```sh
${SDK_PATH}/tools/${ARCH}/pm \
-o hello_fuchsia_manifest \
-o pkg/hello_fuchsia_manifest \
-m pkg/hello_fuchsia.manifest \
build \
-output-package-manifest hello_fuchsia_package_manifest
-output-package-manifest pkg/hello_fuchsia_package_manifest
```

This will produce `pkg/hello_fuchsia_manifest/` which is a package manifest we can
@@ -469,15 +477,15 @@ We can publish our new package to that repository with:

```sh
${SDK_PATH}/tools/${ARCH}/pm publish \
-repo repo \
-lp -f <(echo "hello_fuchsia_package_manifest")
-repo pkg/repo \
-lp -f <(echo "pkg/hello_fuchsia_package_manifest")
```

Then we can add the repository to `ffx`'s package server as `hello-fuchsia` using:

```sh
${SDK_PATH}/tools/${ARCH}/ffx repository add-from-pm \
repo \
pkg/repo \
-r hello-fuchsia
```

13 changes: 4 additions & 9 deletions src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
@@ -349,8 +349,7 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
let where_preds = comma_sep(where_predicates, false);
let clause = if f.alternate() {
if ending == Ending::Newline {
// add a space so stripping <br> tags and breaking spaces still renders properly
format!(" where{where_preds}, ")
format!(" where{where_preds},")
} else {
format!(" where{where_preds}")
}
@@ -364,20 +363,16 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(

if ending == Ending::Newline {
let mut clause = "&nbsp;".repeat(indent.saturating_sub(1));
// add a space so stripping <br> tags and breaking spaces still renders properly
write!(
clause,
" <span class=\"where fmt-newline\">where{where_preds},&nbsp;</span>"
)?;
write!(clause, "<span class=\"where fmt-newline\">where{where_preds},</span>")?;
clause
} else {
// insert a <br> tag after a single space but before multiple spaces at the start
if indent == 0 {
format!(" <br><span class=\"where\">where{where_preds}</span>")
format!("<br><span class=\"where\">where{where_preds}</span>")
} else {
let mut clause = br_with_padding;
clause.truncate(clause.len() - 5 * "&nbsp;".len());
write!(clause, " <span class=\"where\">where{where_preds}</span>")?;
write!(clause, "<span class=\"where\">where{where_preds}</span>")?;
clause
}
}
12 changes: 6 additions & 6 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
@@ -1737,8 +1737,8 @@ pub(crate) fn render_impl_summary(
// in documentation pages for trait with automatic implementations like "Send" and "Sync".
aliases: &[String],
) {
let id =
cx.derive_id(get_id_for_impl(&i.inner_impl().for_, i.inner_impl().trait_.as_ref(), cx));
let inner_impl = i.inner_impl();
let id = cx.derive_id(get_id_for_impl(&inner_impl.for_, inner_impl.trait_.as_ref(), cx));
let aliases = if aliases.is_empty() {
String::new()
} else {
@@ -1750,9 +1750,9 @@ pub(crate) fn render_impl_summary(
write!(w, "<h3 class=\"code-header in-band\">");

if let Some(use_absolute) = use_absolute {
write!(w, "{}", i.inner_impl().print(use_absolute, cx));
write!(w, "{}", inner_impl.print(use_absolute, cx));
if show_def_docs {
for it in &i.inner_impl().items {
for it in &inner_impl.items {
if let clean::AssocTypeItem(ref tydef, ref _bounds) = *it.kind {
w.write_str("<span class=\"where fmt-newline\"> ");
assoc_type(
@@ -1770,11 +1770,11 @@ pub(crate) fn render_impl_summary(
}
}
} else {
write!(w, "{}", i.inner_impl().print(false, cx));
write!(w, "{}", inner_impl.print(false, cx));
}
write!(w, "</h3>");

let is_trait = i.inner_impl().trait_.is_some();
let is_trait = inner_impl.trait_.is_some();
if is_trait {
if let Some(portability) = portability(&i.impl_item, Some(parent)) {
write!(w, "<span class=\"item-info\">{}</span>", portability);
27 changes: 27 additions & 0 deletions src/test/rustdoc-gui/src/lib2/lib.rs
Original file line number Diff line number Diff line change
@@ -143,3 +143,30 @@ pub struct LongItemInfo2;
/// Some docs.
#[doc(cfg(any(target_os = "android", target_os = "linux", target_os = "emscripten", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd")))]
impl SimpleTrait for LongItemInfo2 {}

pub struct WhereWhitespace<T>;

impl<T> WhereWhitespace<T> {
pub fn new<F>(f: F) -> Self
where
F: FnMut() -> i32,
{}
}

impl<K, T> Whitespace<&K> for WhereWhitespace<T>
where
K: std::fmt::Debug,
{
type Output = WhereWhitespace<T>;
fn index(&self, _key: &K) -> &Self::Output {
self
}
}

pub trait Whitespace<Idx>
where
Idx: ?Sized,
{
type Output;
fn index(&self, index: Idx) -> &Self::Output;
}
27 changes: 27 additions & 0 deletions src/test/rustdoc-gui/where-whitespace.goml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// This test ensures that the where conditions are correctly displayed.
goto: file://|DOC_PATH|/lib2/trait.Whitespace.html
show-text: true
// First, we check in the trait definition if the where clause is "on its own" (not on the same
// line than "pub trait Whitespace<Idx>").
compare-elements-position-false: (".item-decl code", ".where.fmt-newline", ("y"))
// And that the code following it isn't on the same line either.
compare-elements-position-false: (".item-decl .fnname", ".where.fmt-newline", ("y"))

goto: file://|DOC_PATH|/lib2/struct.WhereWhitespace.html
// We make the screen a bit wider to ensure that the trait impl is on one line.
size: (915, 915)

compare-elements-position-false: ("#method\.new .fnname", "#method\.new .where.fmt-newline", ("y"))
// We ensure that both the trait name and the struct name are on the same line in
// "impl<K, T> Whitespace<&K> for WhereWhitespace<T>".
compare-elements-position: (
"#trait-implementations-list .impl h3 .trait",
"#trait-implementations-list .impl h3 .struct",
("y"),
)
// And we now check that the where condition isn't on the same line.
compare-elements-position-false: (
"#trait-implementations-list .impl h3 .trait",
"#trait-implementations-list .impl h3 .where.fmt-newline",
("y"),
)
6 changes: 3 additions & 3 deletions src/test/rustdoc-js-std/asrawfd.js
Original file line number Diff line number Diff line change
@@ -6,9 +6,9 @@ const EXPECTED = {
'others': [
// Reproduction test for https://github.com/rust-lang/rust/issues/78724
// Validate that type alias methods get the correct path.
{ 'path': 'std::os::unix::io::AsRawFd', 'name': 'as_raw_fd' },
{ 'path': 'std::os::wasi::io::AsRawFd', 'name': 'as_raw_fd' },
{ 'path': 'std::os::fd::AsRawFd', 'name': 'as_raw_fd' },
{ 'path': 'std::os::fd::AsRawFd', 'name': 'as_raw_fd' },
{ 'path': 'std::os::linux::process::PidFd', 'name': 'as_raw_fd' },
{ 'path': 'std::os::unix::io::RawFd', 'name': 'as_raw_fd' },
{ 'path': 'std::os::fd::RawFd', 'name': 'as_raw_fd' },
],
};
8 changes: 4 additions & 4 deletions src/test/rustdoc/const-generics/const-generics-docs.rs
Original file line number Diff line number Diff line change
@@ -31,12 +31,12 @@ impl Trait<{1 + 2}> for u8 {}
impl<const N: usize> Trait<N> for [u8; N] {}

// @has foo/struct.Foo.html '//pre[@class="rust struct"]' \
// 'pub struct Foo<const N: usize> where u8: Trait<N>'
// 'pub struct Foo<const N: usize>where u8: Trait<N>'
pub struct Foo<const N: usize> where u8: Trait<N>;
// @has foo/struct.Bar.html '//pre[@class="rust struct"]' 'pub struct Bar<T, const N: usize>(_)'
pub struct Bar<T, const N: usize>([T; N]);

// @has foo/struct.Foo.html '//*[@id="impl-Foo%3CM%3E"]/h3[@class="code-header in-band"]' 'impl<const M: usize> Foo<M> where u8: Trait<M>'
// @has foo/struct.Foo.html '//*[@id="impl-Foo%3CM%3E"]/h3[@class="code-header in-band"]' 'impl<const M: usize> Foo<M>where u8: Trait<M>'
impl<const M: usize> Foo<M> where u8: Trait<M> {
// @has - '//*[@id="associatedconstant.FOO_ASSOC"]' 'pub const FOO_ASSOC: usize'
pub const FOO_ASSOC: usize = M + 13;
@@ -50,14 +50,14 @@ impl<const M: usize> Foo<M> where u8: Trait<M> {
// @has foo/struct.Bar.html '//*[@id="impl-Bar%3Cu8%2C%20M%3E"]/h3[@class="code-header in-band"]' 'impl<const M: usize> Bar<u8, M>'
impl<const M: usize> Bar<u8, M> {
// @has - '//*[@id="method.hey"]' \
// 'pub fn hey<const N: usize>(&self) -> Foo<N> where u8: Trait<N>'
// 'pub fn hey<const N: usize>(&self) -> Foo<N>where u8: Trait<N>'
pub fn hey<const N: usize>(&self) -> Foo<N> where u8: Trait<N> {
Foo
}
}

// @has foo/fn.test.html '//pre[@class="rust fn"]' \
// 'pub fn test<const N: usize>() -> impl Trait<N> where u8: Trait<N>'
// 'pub fn test<const N: usize>() -> impl Trait<N>where u8: Trait<N>'
pub fn test<const N: usize>() -> impl Trait<N> where u8: Trait<N> {
2u8
}
4 changes: 2 additions & 2 deletions src/test/rustdoc/generic-associated-types/gats.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@

// @has foo/trait.LendingIterator.html
pub trait LendingIterator {
// @has - '//*[@id="associatedtype.Item"]//h4[@class="code-header"]' "type Item<'a> where Self: 'a"
// @has - '//*[@id="associatedtype.Item"]//h4[@class="code-header"]' "type Item<'a>where Self: 'a"
type Item<'a> where Self: 'a;

// @has - '//*[@id="tymethod.next"]//h4[@class="code-header"]' \
@@ -24,7 +24,7 @@ impl LendingIterator for () {
pub struct Infinite<T>(T);

// @has foo/trait.LendingIterator.html
// @has - '//*[@id="associatedtype.Item-2"]//h4[@class="code-header"]' "type Item<'a> where Self: 'a = &'a T"
// @has - '//*[@id="associatedtype.Item-2"]//h4[@class="code-header"]' "type Item<'a>where Self: 'a = &'a T"
impl<T> LendingIterator for Infinite<T> {
type Item<'a> where Self: 'a = &'a T;

8 changes: 4 additions & 4 deletions src/test/rustdoc/higher-ranked-trait-bounds.rs
Original file line number Diff line number Diff line change
@@ -4,23 +4,23 @@
pub trait Trait<'x> {}

// @has foo/fn.test1.html
// @has - '//pre' "pub fn test1<T>() where for<'a> &'a T: Iterator,"
// @has - '//pre' "pub fn test1<T>()where for<'a> &'a T: Iterator,"
pub fn test1<T>()
where
for<'a> &'a T: Iterator,
{
}

// @has foo/fn.test2.html
// @has - '//pre' "pub fn test2<T>() where for<'a, 'b> &'a T: Trait<'b>,"
// @has - '//pre' "pub fn test2<T>()where for<'a, 'b> &'a T: Trait<'b>,"
pub fn test2<T>()
where
for<'a, 'b> &'a T: Trait<'b>,
{
}

// @has foo/fn.test3.html
// @has - '//pre' "pub fn test3<F>() where F: for<'a, 'b> Fn(&'a u8, &'b u8),"
// @has - '//pre' "pub fn test3<F>()where F: for<'a, 'b> Fn(&'a u8, &'b u8),"
pub fn test3<F>()
where
F: for<'a, 'b> Fn(&'a u8, &'b u8),
@@ -38,7 +38,7 @@ pub struct Foo<'a> {
// @has - '//span[@id="structfield.some_trait"]' "some_trait: &'a dyn for<'b> Trait<'b>"

impl<'a> Foo<'a> {
// @has - '//h4[@class="code-header"]' "pub fn bar<T>() where T: Trait<'a>,"
// @has - '//h4[@class="code-header"]' "pub fn bar<T>()where T: Trait<'a>,"
pub fn bar<T>()
where
T: Trait<'a>,
4 changes: 2 additions & 2 deletions src/test/rustdoc/impl-parts.rs
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ pub auto trait AnAutoTrait {}
pub struct Foo<T> { field: T }

// @has impl_parts/struct.Foo.html '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// "impl<T: Clone> !AnAutoTrait for Foo<T> where T: Sync,"
// "impl<T: Clone> !AnAutoTrait for Foo<T>where T: Sync,"
// @has impl_parts/trait.AnAutoTrait.html '//*[@class="item-list"]//h3[@class="code-header in-band"]' \
// "impl<T: Clone> !AnAutoTrait for Foo<T> where T: Sync,"
// "impl<T: Clone> !AnAutoTrait for Foo<T>where T: Sync,"
impl<T: Clone> !AnAutoTrait for Foo<T> where T: Sync {}
4 changes: 2 additions & 2 deletions src/test/rustdoc/issue-20727-4.rs
Original file line number Diff line number Diff line change
@@ -25,15 +25,15 @@ pub trait IndexMut<Idx: ?Sized>: Index<Idx> {

pub mod reexport {
// @has issue_20727_4/reexport/trait.Index.html
// @has - '//*[@class="rust trait"]' 'trait Index<Idx> where Idx: ?Sized, {'
// @has - '//*[@class="rust trait"]' 'trait Index<Idx>where Idx: ?Sized,{'
// @has - '//*[@class="rust trait"]' 'type Output: ?Sized'
// @has - '//*[@class="rust trait"]' \
// 'fn index(&self, index: Idx) -> &Self::Output'
pub use issue_20727::Index;

// @has issue_20727_4/reexport/trait.IndexMut.html
// @has - '//*[@class="rust trait"]' \
// 'trait IndexMut<Idx>: Index<Idx> where Idx: ?Sized, {'
// 'trait IndexMut<Idx>: Index<Idx>where Idx: ?Sized,{'
// @has - '//*[@class="rust trait"]' \
// 'fn index_mut(&mut self, index: Idx) -> &mut Self::Output;'
pub use issue_20727::IndexMut;
2 changes: 1 addition & 1 deletion src/test/rustdoc/issue-21801.rs
Original file line number Diff line number Diff line change
@@ -5,5 +5,5 @@ extern crate issue_21801;

// @has issue_21801/struct.Foo.html
// @has - '//*[@id="method.new"]' \
// 'fn new<F>(f: F) -> Foo where F: FnMut() -> i32'
// 'fn new<F>(f: F) -> Foowhere F: FnMut() -> i32'
pub use issue_21801::Foo;
2 changes: 1 addition & 1 deletion src/test/rustdoc/issue-29503.rs
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ pub trait MyTrait {
fn my_string(&self) -> String;
}

// @has - "//div[@id='implementors-list']//*[@id='impl-MyTrait-for-T']//h3[@class='code-header in-band']" "impl<T> MyTrait for T where T: Debug"
// @has - "//div[@id='implementors-list']//*[@id='impl-MyTrait-for-T']//h3[@class='code-header in-band']" "impl<T> MyTrait for Twhere T: Debug"
impl<T> MyTrait for T
where
T: fmt::Debug,
2 changes: 1 addition & 1 deletion src/test/rustdoc/issue-34928.rs
Original file line number Diff line number Diff line change
@@ -2,5 +2,5 @@

pub trait Bar {}

// @has foo/struct.Foo.html '//pre' 'pub struct Foo<T>(pub T) where T: Bar;'
// @has foo/struct.Foo.html '//pre' 'pub struct Foo<T>(pub T)where T: Bar;'
pub struct Foo<T>(pub T) where T: Bar;
4 changes: 2 additions & 2 deletions src/test/rustdoc/issue-50159.rs
Original file line number Diff line number Diff line change
@@ -11,8 +11,8 @@ impl<B, C> Signal2 for B where B: Signal<Item = C> {
}

// @has issue_50159/struct.Switch.html
// @has - '//h3[@class="code-header in-band"]' 'impl<B> Send for Switch<B> where <B as Signal>::Item: Send'
// @has - '//h3[@class="code-header in-band"]' 'impl<B> Sync for Switch<B> where <B as Signal>::Item: Sync'
// @has - '//h3[@class="code-header in-band"]' 'impl<B> Send for Switch<B>where <B as Signal>::Item: Send'
// @has - '//h3[@class="code-header in-band"]' 'impl<B> Sync for Switch<B>where <B as Signal>::Item: Sync'
// @count - '//*[@id="implementations-list"]//*[@class="impl"]' 0
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]' 5
pub struct Switch<B: Signal> {
2 changes: 1 addition & 1 deletion src/test/rustdoc/issue-51236.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ pub mod traits {

// @has issue_51236/struct.Owned.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// "impl<T> Send for Owned<T> where <T as Owned<'static>>::Reader: Send"
// "impl<T> Send for Owned<T>where <T as Owned<'static>>::Reader: Send"
pub struct Owned<T> where T: for<'a> ::traits::Owned<'a> {
marker: PhantomData<<T as ::traits::Owned<'static>>::Reader>,
}
6 changes: 2 additions & 4 deletions src/test/rustdoc/issue-54705.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
pub trait ScopeHandle<'scope> {}



// @has issue_54705/struct.ScopeFutureContents.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// "impl<'scope, S> Send for ScopeFutureContents<'scope, S> where S: Sync"
// "impl<'scope, S> Send for ScopeFutureContents<'scope, S>where S: Sync"
//
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// "impl<'scope, S> Sync for ScopeFutureContents<'scope, S> where S: Sync"
// "impl<'scope, S> Sync for ScopeFutureContents<'scope, S>where S: Sync"
pub struct ScopeFutureContents<'scope, S>
where S: ScopeHandle<'scope>,
{
2 changes: 1 addition & 1 deletion src/test/rustdoc/issue-98697.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@

extern crate issue_98697_reexport_with_anonymous_lifetime;

// @has issue_98697/fn.repro.html '//pre[@class="rust fn"]/code' 'fn repro<F>() where F: Fn(&str)'
// @has issue_98697/fn.repro.html '//pre[@class="rust fn"]/code' 'fn repro<F>()where F: Fn(&str)'
// @!has issue_98697/fn.repro.html '//pre[@class="rust fn"]/code' 'for<'
pub use issue_98697_reexport_with_anonymous_lifetime::repro;

4 changes: 2 additions & 2 deletions src/test/rustdoc/primitive-slice-auto-trait.rs
Original file line number Diff line number Diff line change
@@ -7,8 +7,8 @@
// @has - '//span[@class="in-band"]' 'Primitive Type slice'
// @has - '//section[@id="main-content"]//div[@class="docblock"]//p' 'this is a test!'
// @has - '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementations'
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl<T> Send for [T] where T: Send'
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl<T> Sync for [T] where T: Sync'
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl<T> Send for [T]where T: Send'
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl<T> Sync for [T]where T: Sync'
#[doc(primitive = "slice")]
/// this is a test!
mod slice_prim {}
4 changes: 2 additions & 2 deletions src/test/rustdoc/synthetic_auto/basic.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @has basic/struct.Foo.html
// @has - '//h3[@class="code-header in-band"]' 'impl<T> Send for Foo<T> where T: Send'
// @has - '//h3[@class="code-header in-band"]' 'impl<T> Sync for Foo<T> where T: Sync'
// @has - '//h3[@class="code-header in-band"]' 'impl<T> Send for Foo<T>where T: Send'
// @has - '//h3[@class="code-header in-band"]' 'impl<T> Sync for Foo<T>where T: Sync'
// @count - '//*[@id="implementations-list"]//*[@class="impl has-srclink"]' 0
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]' 5
pub struct Foo<T> {
2 changes: 1 addition & 1 deletion src/test/rustdoc/synthetic_auto/complex.rs
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ mod foo {

// @has complex/struct.NotOuter.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// "impl<'a, T, K: ?Sized> Send for Outer<'a, T, K> where K: for<'b> Fn((&'b bool, &'a u8)) \
// "impl<'a, T, K: ?Sized> Send for Outer<'a, T, K>where K: for<'b> Fn((&'b bool, &'a u8)) \
// -> &'b i8, T: MyTrait<'a>, <T as MyTrait<'a>>::MyItem: Copy, 'a: 'static"

pub use foo::{Foo, Inner as NotInner, MyTrait as NotMyTrait, Outer as NotOuter};
4 changes: 2 additions & 2 deletions src/test/rustdoc/synthetic_auto/lifetimes.rs
Original file line number Diff line number Diff line change
@@ -10,10 +10,10 @@ where

// @has lifetimes/struct.Foo.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// "impl<'c, K> Send for Foo<'c, K> where K: for<'b> Fn(&'b bool) -> &'c u8, 'c: 'static"
// "impl<'c, K> Send for Foo<'c, K>where K: for<'b> Fn(&'b bool) -> &'c u8, 'c: 'static"
//
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// "impl<'c, K> Sync for Foo<'c, K> where K: Sync"
// "impl<'c, K> Sync for Foo<'c, K>where K: Sync"
pub struct Foo<'c, K: 'c> {
inner_field: Inner<'c, K>,
}
2 changes: 1 addition & 1 deletion src/test/rustdoc/synthetic_auto/manual.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @has manual/struct.Foo.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// 'impl<T> Sync for Foo<T> where T: Sync'
// 'impl<T> Sync for Foo<T>where T: Sync'
//
// @has - '//*[@id="trait-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// 'impl<T> Send for Foo<T>'
4 changes: 2 additions & 2 deletions src/test/rustdoc/synthetic_auto/nested.rs
Original file line number Diff line number Diff line change
@@ -10,10 +10,10 @@ where

// @has nested/struct.Foo.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// 'impl<T> Send for Foo<T> where T: Copy'
// 'impl<T> Send for Foo<T>where T: Copy'
//
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// 'impl<T> Sync for Foo<T> where T: Sync'
// 'impl<T> Sync for Foo<T>where T: Sync'
pub struct Foo<T> {
inner_field: Inner<T>,
}
2 changes: 1 addition & 1 deletion src/test/rustdoc/synthetic_auto/no-redundancy.rs
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ where

// @has no_redundancy/struct.Outer.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// "impl<T> Send for Outer<T> where T: Send + Copy"
// "impl<T> Send for Outer<T>where T: Send + Copy"
pub struct Outer<T> {
inner_field: Inner<T>,
}
4 changes: 2 additions & 2 deletions src/test/rustdoc/synthetic_auto/project.rs
Original file line number Diff line number Diff line change
@@ -24,10 +24,10 @@ where

// @has project/struct.Foo.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// "impl<'c, K> Send for Foo<'c, K> where K: MyTrait<MyItem = bool>, 'c: 'static"
// "impl<'c, K> Send for Foo<'c, K>where K: MyTrait<MyItem = bool>, 'c: 'static"
//
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// "impl<'c, K> Sync for Foo<'c, K> where K: MyTrait, <K as MyTrait>::MyItem: OtherTrait, \
// "impl<'c, K> Sync for Foo<'c, K>where K: MyTrait, <K as MyTrait>::MyItem: OtherTrait, \
// 'c: 'static,"
pub struct Foo<'c, K: 'c> {
inner_field: Inner<'c, K>,
2 changes: 1 addition & 1 deletion src/test/rustdoc/synthetic_auto/self-referential.rs
Original file line number Diff line number Diff line change
@@ -24,6 +24,6 @@ impl<T> Pattern for Wrapper<T> {

// @has self_referential/struct.WriteAndThen.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// "impl<P1> Send for WriteAndThen<P1> where <P1 as Pattern>::Value: Send"
// "impl<P1> Send for WriteAndThen<P1>where <P1 as Pattern>::Value: Send"
pub struct WriteAndThen<P1>(pub P1::Value,pub <Constrain<P1, Wrapper<P1::Value>> as Pattern>::Value)
where P1: Pattern;
2 changes: 1 addition & 1 deletion src/test/rustdoc/synthetic_auto/static-region.rs
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ pub trait OwnedTrait<'a> {

// @has static_region/struct.Owned.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// "impl<T> Send for Owned<T> where <T as OwnedTrait<'static>>::Reader: Send"
// "impl<T> Send for Owned<T>where <T as OwnedTrait<'static>>::Reader: Send"
pub struct Owned<T> where T: OwnedTrait<'static> {
marker: <T as OwnedTrait<'static>>::Reader,
}
2 changes: 1 addition & 1 deletion src/test/rustdoc/where-clause-order.rs
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ where
}

// @has 'foo/trait.SomeTrait.html'
// @has - "//*[@id='impl-SomeTrait%3C(A%2C%20B%2C%20C%2C%20D%2C%20E)%3E-for-(A%2C%20B%2C%20C%2C%20D%2C%20E)']/h3" "impl<A, B, C, D, E> SomeTrait<(A, B, C, D, E)> for (A, B, C, D, E) where A: PartialOrd<A> + PartialEq<A>, B: PartialOrd<B> + PartialEq<B>, C: PartialOrd<C> + PartialEq<C>, D: PartialOrd<D> + PartialEq<D>, E: PartialOrd<E> + PartialEq<E> + ?Sized, "
// @has - "//*[@id='impl-SomeTrait%3C(A%2C%20B%2C%20C%2C%20D%2C%20E)%3E-for-(A%2C%20B%2C%20C%2C%20D%2C%20E)']/h3" "impl<A, B, C, D, E> SomeTrait<(A, B, C, D, E)> for (A, B, C, D, E)where A: PartialOrd<A> + PartialEq<A>, B: PartialOrd<B> + PartialEq<B>, C: PartialOrd<C> + PartialEq<C>, D: PartialOrd<D> + PartialEq<D>, E: PartialOrd<E> + PartialEq<E> + ?Sized, "
impl<A, B, C, D, E> SomeTrait<(A, B, C, D, E)> for (A, B, C, D, E)
where
A: PartialOrd<A> + PartialEq<A>,
22 changes: 11 additions & 11 deletions src/test/rustdoc/where.rs
Original file line number Diff line number Diff line change
@@ -3,17 +3,17 @@

pub trait MyTrait { fn dummy(&self) { } }

// @has foo/struct.Alpha.html '//pre' "pub struct Alpha<A>(_) where A: MyTrait"
// @has foo/struct.Alpha.html '//pre' "pub struct Alpha<A>(_)where A: MyTrait"
pub struct Alpha<A>(A) where A: MyTrait;
// @has foo/trait.Bravo.html '//pre' "pub trait Bravo<B> where B: MyTrait"
// @has foo/trait.Bravo.html '//pre' "pub trait Bravo<B>where B: MyTrait"
pub trait Bravo<B> where B: MyTrait { fn get(&self, B: B); }
// @has foo/fn.charlie.html '//pre' "pub fn charlie<C>() where C: MyTrait"
// @has foo/fn.charlie.html '//pre' "pub fn charlie<C>()where C: MyTrait"
pub fn charlie<C>() where C: MyTrait {}

pub struct Delta<D>(D);

// @has foo/struct.Delta.html '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// "impl<D> Delta<D> where D: MyTrait"
// "impl<D> Delta<D>where D: MyTrait"
impl<D> Delta<D> where D: MyTrait {
pub fn delta() {}
}
@@ -33,19 +33,19 @@ pub trait TraitWhere {
}

// @has foo/struct.Echo.html '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// "impl<E> MyTrait for Echo<E> where E: MyTrait"
// "impl<E> MyTrait for Echo<E>where E: MyTrait"
// @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//h3[@class="code-header in-band"]' \
// "impl<E> MyTrait for Echo<E> where E: MyTrait"
impl<E> MyTrait for Echo<E> where E: MyTrait {}
// "impl<E> MyTrait for Echo<E>where E: MyTrait"
impl<E> MyTrait for Echo<E>where E: MyTrait {}

pub enum Foxtrot<F> { Foxtrot1(F) }

// @has foo/enum.Foxtrot.html '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// "impl<F> MyTrait for Foxtrot<F> where F: MyTrait"
// "impl<F> MyTrait for Foxtrot<F>where F: MyTrait"
// @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//h3[@class="code-header in-band"]' \
// "impl<F> MyTrait for Foxtrot<F> where F: MyTrait"
impl<F> MyTrait for Foxtrot<F> where F: MyTrait {}
// "impl<F> MyTrait for Foxtrot<F>where F: MyTrait"
impl<F> MyTrait for Foxtrot<F>where F: MyTrait {}

// @has foo/type.Golf.html '//pre[@class="rust typedef"]' \
// "type Golf<T> where T: Clone, = (T, T)"
// "type Golf<T>where T: Clone, = (T, T)"
pub type Golf<T> where T: Clone = (T, T);
3 changes: 3 additions & 0 deletions src/test/ui/async-await/issue-73137.rs
Original file line number Diff line number Diff line change
@@ -2,6 +2,9 @@

// run-pass
// edition:2018
// revisions: normal drop-tracking
// [normal]compile-flags: -Zdrop-tracking=no
// [drop-tracking]compile-flags: -Zdrop-tracking

#![allow(dead_code)]
use std::future::Future;
25 changes: 25 additions & 0 deletions src/test/ui/mir/issue-99866.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// check-pass
pub trait Backend {
type DescriptorSetLayout;
}

pub struct Back;

impl Backend for Back {
type DescriptorSetLayout = u32;
}

pub struct HalSetLayouts {
vertex_layout: <Back as Backend>::DescriptorSetLayout,
}

impl HalSetLayouts {
pub fn iter<DSL>(self) -> DSL
where
Back: Backend<DescriptorSetLayout = DSL>,
{
self.vertex_layout
}
}

fn main() {}