mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Remove the translation compiler options
This commit is contained in:
@@ -5,9 +5,8 @@
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::error::Error;
|
||||
use std::path::Path;
|
||||
use std::sync::{Arc, LazyLock};
|
||||
use std::{fmt, fs, io};
|
||||
use std::{fmt, io};
|
||||
|
||||
use fluent_bundle::FluentResource;
|
||||
pub use fluent_bundle::types::FluentType;
|
||||
@@ -17,7 +16,7 @@
|
||||
use rustc_data_structures::sync::{DynSend, IntoDynSyncSend};
|
||||
use rustc_macros::{Decodable, Encodable};
|
||||
use rustc_span::Span;
|
||||
use tracing::{instrument, trace};
|
||||
use tracing::instrument;
|
||||
pub use unic_langid::{LanguageIdentifier, langid};
|
||||
|
||||
mod diagnostic_impls;
|
||||
@@ -98,100 +97,6 @@ fn from(mut errs: Vec<FluentError>) -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns Fluent bundle with the user's locale resources from
|
||||
/// `$sysroot/share/locale/$requested_locale/*.ftl`.
|
||||
///
|
||||
/// If `-Z additional-ftl-path` was provided, load that resource and add it to the bundle
|
||||
/// (overriding any conflicting messages).
|
||||
#[instrument(level = "trace")]
|
||||
pub fn fluent_bundle(
|
||||
sysroot_candidates: &[&Path],
|
||||
requested_locale: Option<LanguageIdentifier>,
|
||||
additional_ftl_path: Option<&Path>,
|
||||
with_directionality_markers: bool,
|
||||
) -> Result<Option<Arc<FluentBundle>>, TranslationBundleError> {
|
||||
if requested_locale.is_none() && additional_ftl_path.is_none() {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let fallback_locale = langid!("en-US");
|
||||
let requested_fallback_locale = requested_locale.as_ref() == Some(&fallback_locale);
|
||||
trace!(?requested_fallback_locale);
|
||||
if requested_fallback_locale && additional_ftl_path.is_none() {
|
||||
return Ok(None);
|
||||
}
|
||||
// If there is only `-Z additional-ftl-path`, assume locale is "en-US", otherwise use user
|
||||
// provided locale.
|
||||
let locale = requested_locale.clone().unwrap_or(fallback_locale);
|
||||
trace!(?locale);
|
||||
let mut bundle = new_bundle(vec![locale]);
|
||||
|
||||
// Add convenience functions available to ftl authors.
|
||||
register_functions(&mut bundle);
|
||||
|
||||
// Fluent diagnostics can insert directionality isolation markers around interpolated variables
|
||||
// indicating that there may be a shift from right-to-left to left-to-right text (or
|
||||
// vice-versa). These are disabled because they are sometimes visible in the error output, but
|
||||
// may be worth investigating in future (for example: if type names are left-to-right and the
|
||||
// surrounding diagnostic messages are right-to-left, then these might be helpful).
|
||||
bundle.set_use_isolating(with_directionality_markers);
|
||||
|
||||
// If the user requests the default locale then don't try to load anything.
|
||||
if let Some(requested_locale) = requested_locale {
|
||||
let mut found_resources = false;
|
||||
for sysroot in sysroot_candidates {
|
||||
let mut sysroot = sysroot.to_path_buf();
|
||||
sysroot.push("share");
|
||||
sysroot.push("locale");
|
||||
sysroot.push(requested_locale.to_string());
|
||||
trace!(?sysroot);
|
||||
|
||||
if !sysroot.exists() {
|
||||
trace!("skipping");
|
||||
continue;
|
||||
}
|
||||
|
||||
if !sysroot.is_dir() {
|
||||
return Err(TranslationBundleError::LocaleIsNotDir);
|
||||
}
|
||||
|
||||
for entry in sysroot.read_dir().map_err(TranslationBundleError::ReadLocalesDir)? {
|
||||
let entry = entry.map_err(TranslationBundleError::ReadLocalesDirEntry)?;
|
||||
let path = entry.path();
|
||||
trace!(?path);
|
||||
if path.extension().and_then(|s| s.to_str()) != Some("ftl") {
|
||||
trace!("skipping");
|
||||
continue;
|
||||
}
|
||||
|
||||
let resource_str =
|
||||
fs::read_to_string(path).map_err(TranslationBundleError::ReadFtl)?;
|
||||
let resource =
|
||||
FluentResource::try_new(resource_str).map_err(TranslationBundleError::from)?;
|
||||
trace!(?resource);
|
||||
bundle.add_resource(resource).map_err(TranslationBundleError::from)?;
|
||||
found_resources = true;
|
||||
}
|
||||
}
|
||||
|
||||
if !found_resources {
|
||||
return Err(TranslationBundleError::MissingLocale);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(additional_ftl_path) = additional_ftl_path {
|
||||
let resource_str =
|
||||
fs::read_to_string(additional_ftl_path).map_err(TranslationBundleError::ReadFtl)?;
|
||||
let resource =
|
||||
FluentResource::try_new(resource_str).map_err(TranslationBundleError::from)?;
|
||||
trace!(?resource);
|
||||
bundle.add_resource_overriding(resource);
|
||||
}
|
||||
|
||||
let bundle = Arc::new(bundle);
|
||||
Ok(Some(bundle))
|
||||
}
|
||||
|
||||
pub fn register_functions<R, M>(bundle: &mut fluent_bundle::bundle::FluentBundle<R, M>) {
|
||||
bundle
|
||||
.add_function("STREQ", |positional, _named| match positional {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use std::borrow::Cow;
|
||||
use std::error::Report;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub use rustc_error_messages::{FluentArgs, LazyFallbackBundle};
|
||||
use rustc_error_messages::{langid, register_functions};
|
||||
@@ -8,7 +7,7 @@
|
||||
|
||||
use crate::error::TranslateError;
|
||||
use crate::fluent_bundle::FluentResource;
|
||||
use crate::{DiagArg, DiagMessage, FluentBundle, Style, fluent_bundle};
|
||||
use crate::{DiagArg, DiagMessage, Style, fluent_bundle};
|
||||
|
||||
/// Convert diagnostic arguments (a rustc internal type that exists to implement
|
||||
/// `Encodable`/`Decodable`) into `FluentArgs` which is necessary to perform translation.
|
||||
@@ -30,15 +29,11 @@ pub fn to_fluent_args<'iter>(iter: impl Iterator<Item = DiagArg<'iter>>) -> Flue
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Translator {
|
||||
/// Localized diagnostics for the locale requested by the user. If no language was requested by
|
||||
/// the user then this will be `None` and `fallback_fluent_bundle` should be used.
|
||||
pub fluent_bundle: Option<Arc<FluentBundle>>,
|
||||
}
|
||||
pub struct Translator;
|
||||
|
||||
impl Translator {
|
||||
pub fn new() -> Translator {
|
||||
Translator { fluent_bundle: None }
|
||||
Self
|
||||
}
|
||||
|
||||
/// Convert `DiagMessage`s to a string, performing translation if necessary.
|
||||
|
||||
@@ -436,16 +436,6 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
|
||||
|
||||
let temps_dir = config.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
|
||||
|
||||
let bundle = match rustc_errors::fluent_bundle(
|
||||
&config.opts.sysroot.all_paths().collect::<Vec<_>>(),
|
||||
config.opts.unstable_opts.translate_lang.clone(),
|
||||
config.opts.unstable_opts.translate_additional_ftl.as_deref(),
|
||||
config.opts.unstable_opts.translate_directionality_markers,
|
||||
) {
|
||||
Ok(bundle) => bundle,
|
||||
Err(e) => early_dcx.early_fatal(format!("failed to load fluent bundle: {e}")),
|
||||
};
|
||||
|
||||
let mut sess = rustc_session::build_session(
|
||||
config.opts,
|
||||
CompilerIO {
|
||||
@@ -454,7 +444,6 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
|
||||
output_file: config.output_file,
|
||||
temps_dir,
|
||||
},
|
||||
bundle,
|
||||
config.lint_caps,
|
||||
target,
|
||||
util::rustc_version_str().unwrap_or("unknown"),
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_data_structures::profiling::TimePassesFormat;
|
||||
use rustc_data_structures::stable_hasher::StableHasher;
|
||||
use rustc_errors::{ColorConfig, LanguageIdentifier, TerminalUrl};
|
||||
use rustc_errors::{ColorConfig, TerminalUrl};
|
||||
use rustc_feature::UnstableFeatures;
|
||||
use rustc_hashes::Hash64;
|
||||
use rustc_hir::attrs::CollapseMacroDebuginfo;
|
||||
@@ -790,7 +790,6 @@ mod desc {
|
||||
pub(crate) const parse_string: &str = "a string";
|
||||
pub(crate) const parse_opt_string: &str = parse_string;
|
||||
pub(crate) const parse_string_push: &str = parse_string;
|
||||
pub(crate) const parse_opt_langid: &str = "a language identifier";
|
||||
pub(crate) const parse_opt_pathbuf: &str = "a path";
|
||||
pub(crate) const parse_list: &str = "a space-separated list of strings";
|
||||
pub(crate) const parse_list_with_polarity: &str =
|
||||
@@ -998,17 +997,6 @@ pub(crate) fn parse_opt_string(slot: &mut Option<String>, v: Option<&str>) -> bo
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse an optional language identifier, e.g. `en-US` or `zh-CN`.
|
||||
pub(crate) fn parse_opt_langid(slot: &mut Option<LanguageIdentifier>, v: Option<&str>) -> bool {
|
||||
match v {
|
||||
Some(s) => {
|
||||
*slot = rustc_errors::LanguageIdentifier::from_str(s).ok();
|
||||
true
|
||||
}
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn parse_opt_pathbuf(slot: &mut Option<PathBuf>, v: Option<&str>) -> bool {
|
||||
match v {
|
||||
Some(s) => {
|
||||
@@ -2710,15 +2698,6 @@ pub(crate) fn parse_align(slot: &mut Option<Align>, v: Option<&str>) -> bool {
|
||||
"for every macro invocation, print its name and arguments (default: no)"),
|
||||
track_diagnostics: bool = (false, parse_bool, [UNTRACKED],
|
||||
"tracks where in rustc a diagnostic was emitted"),
|
||||
// Diagnostics are considered side-effects of a query (see `QuerySideEffect`) and are saved
|
||||
// alongside query results and changes to translation options can affect diagnostics - so
|
||||
// translation options should be tracked.
|
||||
translate_additional_ftl: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
|
||||
"additional fluent translation to preferentially use (for testing translation)"),
|
||||
translate_directionality_markers: bool = (false, parse_bool, [TRACKED],
|
||||
"emit directionality isolation markers in translated diagnostics"),
|
||||
translate_lang: Option<LanguageIdentifier> = (None, parse_opt_langid, [TRACKED],
|
||||
"language identifier for diagnostic output"),
|
||||
translate_remapped_path_to_local_path: bool = (true, parse_bool, [TRACKED],
|
||||
"translate remapped paths into local paths when possible (default: yes)"),
|
||||
trap_unreachable: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
||||
|
||||
@@ -966,7 +966,6 @@ fn default_emitter(
|
||||
pub fn build_session(
|
||||
sopts: config::Options,
|
||||
io: CompilerIO,
|
||||
fluent_bundle: Option<Arc<rustc_errors::FluentBundle>>,
|
||||
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
|
||||
target: Target,
|
||||
cfg_version: &'static str,
|
||||
@@ -984,7 +983,7 @@ pub fn build_session(
|
||||
let cap_lints_allow = sopts.lint_cap.is_some_and(|cap| cap == lint::Allow);
|
||||
let can_emit_warnings = !(warnings_allow || cap_lints_allow);
|
||||
|
||||
let translator = Translator { fluent_bundle };
|
||||
let translator = Translator;
|
||||
let source_map = rustc_span::source_map::get_source_map().unwrap();
|
||||
let emitter = default_emitter(&sopts, Arc::clone(&source_map), translator);
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
# `foo` isn't provided by this diagnostic so it is expected that the fallback message is used.
|
||||
parse_struct_literal_body_without_path = this is a {$foo} message
|
||||
.suggestion = this is a test suggestion
|
||||
@@ -1,3 +0,0 @@
|
||||
# `parse_struct_literal_body_without_path` isn't provided by this resource at all, so the
|
||||
# fallback should be used.
|
||||
foo = bar
|
||||
@@ -1,197 +0,0 @@
|
||||
//! Smoke test for the rustc diagnostics translation infrastructure.
|
||||
//!
|
||||
//! # References
|
||||
//!
|
||||
//! - Current tracking issue: <https://github.com/rust-lang/rust/issues/132181>.
|
||||
//! - Old tracking issue: <https://github.com/rust-lang/rust/issues/100717>
|
||||
//! - Initial translation infra implementation: <https://github.com/rust-lang/rust/pull/95512>.
|
||||
|
||||
// This test uses symbolic links to stub out a fake sysroot to save testing time.
|
||||
//@ needs-symlink
|
||||
//@ needs-subprocess
|
||||
|
||||
// FIXME(151366) Currently `-Ztranslate-additional-ftl` is currently broken
|
||||
//@ ignore-test
|
||||
|
||||
#![deny(warnings)]
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use run_make_support::rustc::sysroot;
|
||||
use run_make_support::{cwd, rfs, run_in_tmpdir, rustc};
|
||||
|
||||
fn main() {
|
||||
builtin_fallback_bundle();
|
||||
additional_primary_bundle();
|
||||
missing_slug_prefers_fallback_bundle();
|
||||
broken_primary_bundle_prefers_fallback_bundle();
|
||||
locale_sysroot();
|
||||
missing_sysroot();
|
||||
file_sysroot();
|
||||
}
|
||||
|
||||
/// Check that the test works normally, using the built-in fallback bundle.
|
||||
fn builtin_fallback_bundle() {
|
||||
rustc().input("test.rs").run_fail().assert_stderr_contains("struct literal body without path");
|
||||
}
|
||||
|
||||
/// Check that a primary bundle can be loaded and will be preferentially used where possible.
|
||||
fn additional_primary_bundle() {
|
||||
rustc()
|
||||
.input("test.rs")
|
||||
.arg("-Ztranslate-additional-ftl=working.ftl")
|
||||
.run_fail()
|
||||
.assert_stderr_contains("this is a test message");
|
||||
}
|
||||
|
||||
/// Check that a primary bundle without the desired message will use the fallback bundle.
|
||||
fn missing_slug_prefers_fallback_bundle() {
|
||||
rustc()
|
||||
.input("test.rs")
|
||||
.arg("-Ztranslate-additional-ftl=missing.ftl")
|
||||
.run_fail()
|
||||
.assert_stderr_contains("struct literal body without path");
|
||||
}
|
||||
|
||||
/// Check that a primary bundle with a broken message (e.g. an interpolated variable is not
|
||||
/// provided) will use the fallback bundle.
|
||||
fn broken_primary_bundle_prefers_fallback_bundle() {
|
||||
// FIXME(#135817): as of the rmake.rs port, the compiler actually ICEs on the additional
|
||||
// `broken.ftl`, even though the original intention seems to be that it should gracefully
|
||||
// failover to the fallback bundle. On `aarch64-apple-darwin`, somehow it *doesn't* ICE.
|
||||
|
||||
rustc()
|
||||
.env("RUSTC_ICE", "0") // disable ICE dump file, not needed
|
||||
.input("test.rs")
|
||||
.arg("-Ztranslate-additional-ftl=broken.ftl")
|
||||
.run_fail();
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn shallow_symlink_dir_entries(src_dir: &Path, dst_dir: &Path) {
|
||||
for entry in rfs::read_dir(src_dir) {
|
||||
let entry = entry.unwrap();
|
||||
let src_entry_path = entry.path();
|
||||
let src_filename = src_entry_path.file_name().unwrap();
|
||||
let meta = rfs::symlink_metadata(&src_entry_path);
|
||||
if meta.is_symlink() || meta.is_file() {
|
||||
rfs::symlink_file(&src_entry_path, dst_dir.join(src_filename));
|
||||
} else if meta.is_dir() {
|
||||
rfs::symlink_dir(&src_entry_path, dst_dir.join(src_filename));
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn shallow_symlink_dir_entries_materialize_single_dir(
|
||||
src_dir: &Path,
|
||||
dst_dir: &Path,
|
||||
dir_filename: &str,
|
||||
) {
|
||||
shallow_symlink_dir_entries(src_dir, dst_dir);
|
||||
|
||||
let dst_symlink_meta = rfs::symlink_metadata(dst_dir.join(dir_filename));
|
||||
|
||||
if dst_symlink_meta.is_file() || dst_symlink_meta.is_dir() {
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use std::os::windows::fs::FileTypeExt as _;
|
||||
if dst_symlink_meta.file_type().is_symlink_file() {
|
||||
rfs::remove_file(dst_dir.join(dir_filename));
|
||||
} else if dst_symlink_meta.file_type().is_symlink_dir() {
|
||||
rfs::remove_dir(dst_dir.join(dir_filename));
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
rfs::remove_file(dst_dir.join(dir_filename));
|
||||
}
|
||||
|
||||
rfs::create_dir_all(dst_dir.join(dir_filename));
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn setup_fakeroot_parents() -> PathBuf {
|
||||
let sysroot = sysroot();
|
||||
let fakeroot = cwd().join("fakeroot");
|
||||
rfs::create_dir_all(&fakeroot);
|
||||
shallow_symlink_dir_entries_materialize_single_dir(&sysroot, &fakeroot, "lib");
|
||||
shallow_symlink_dir_entries_materialize_single_dir(
|
||||
&sysroot.join("lib"),
|
||||
&fakeroot.join("lib"),
|
||||
"rustlib",
|
||||
);
|
||||
shallow_symlink_dir_entries_materialize_single_dir(
|
||||
&sysroot.join("lib").join("rustlib"),
|
||||
&fakeroot.join("lib").join("rustlib"),
|
||||
"src",
|
||||
);
|
||||
shallow_symlink_dir_entries(
|
||||
&sysroot.join("lib").join("rustlib").join("src"),
|
||||
&fakeroot.join("lib").join("rustlib").join("src"),
|
||||
);
|
||||
fakeroot
|
||||
}
|
||||
|
||||
/// Check that a locale can be loaded from the sysroot given a language identifier by making a local
|
||||
/// copy of the sysroot and adding the custom locale to it.
|
||||
fn locale_sysroot() {
|
||||
run_in_tmpdir(|| {
|
||||
let fakeroot = setup_fakeroot_parents();
|
||||
|
||||
// When download-rustc is enabled, real sysroot will have a share directory. Delete the link
|
||||
// to it.
|
||||
let _ = std::fs::remove_file(fakeroot.join("share"));
|
||||
|
||||
let fake_locale_path = fakeroot.join("share").join("locale").join("zh-CN");
|
||||
rfs::create_dir_all(&fake_locale_path);
|
||||
rfs::symlink_file(
|
||||
cwd().join("working.ftl"),
|
||||
fake_locale_path.join("basic-translation.ftl"),
|
||||
);
|
||||
|
||||
rustc()
|
||||
.env("RUSTC_ICE", "0")
|
||||
.input("test.rs")
|
||||
.sysroot(&fakeroot)
|
||||
.arg("-Ztranslate-lang=zh-CN")
|
||||
.run_fail()
|
||||
.assert_stderr_contains("this is a test message");
|
||||
});
|
||||
}
|
||||
|
||||
/// Check that the compiler errors out when the sysroot requested cannot be found. This test might
|
||||
/// start failing if there actually exists a Klingon translation of rustc's error messages.
|
||||
fn missing_sysroot() {
|
||||
run_in_tmpdir(|| {
|
||||
rustc()
|
||||
.input("test.rs")
|
||||
.arg("-Ztranslate-lang=tlh")
|
||||
.run_fail()
|
||||
.assert_stderr_contains("missing locale directory");
|
||||
});
|
||||
}
|
||||
|
||||
/// Check that the compiler errors out when the directory for the locale in the sysroot is actually
|
||||
/// a file.
|
||||
fn file_sysroot() {
|
||||
run_in_tmpdir(|| {
|
||||
let fakeroot = setup_fakeroot_parents();
|
||||
rfs::create_dir_all(fakeroot.join("share").join("locale"));
|
||||
rfs::write(fakeroot.join("share").join("locale").join("zh-CN"), b"not a dir");
|
||||
|
||||
rustc()
|
||||
.input("test.rs")
|
||||
.sysroot(&fakeroot)
|
||||
.arg("-Ztranslate-lang=zh-CN")
|
||||
.run_fail()
|
||||
.assert_stderr_contains("is not a directory");
|
||||
});
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
// Exact error being tested isn't relevant, it just needs to be known that it uses Fluent-backed
|
||||
// diagnostics.
|
||||
|
||||
struct Foo {
|
||||
val: (),
|
||||
}
|
||||
|
||||
fn foo() -> Foo {
|
||||
val: (),
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = foo();
|
||||
x.val == 42;
|
||||
let x = {
|
||||
val: (),
|
||||
};
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
parse_struct_literal_body_without_path = this is a test message
|
||||
.suggestion = this is a test suggestion
|
||||
@@ -446,10 +446,6 @@ Everything to do with `--diagnostic-width`.
|
||||
|
||||
Exercises `#[diagnostic::*]` namespaced attributes. See [RFC 3368 Diagnostic attribute namespace](https://github.com/rust-lang/rfcs/blob/master/text/3368-diagnostic-attribute-namespace.md).
|
||||
|
||||
## `tests/ui/diagnostics-infra`
|
||||
|
||||
This directory contains tests and infrastructure related to the diagnostics system, including support for translatable diagnostics
|
||||
|
||||
## `tests/ui/did_you_mean/`
|
||||
|
||||
Tests for miscellaneous suggestions.
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
//! Regression test for https://github.com/rust-lang/rust/issues/106755
|
||||
|
||||
//@ compile-flags:-Ztranslate-lang=en_US
|
||||
|
||||
#![feature(negative_impls)]
|
||||
#![feature(marker_trait_attr)]
|
||||
|
||||
#[marker]
|
||||
trait MyTrait {}
|
||||
|
||||
struct TestType<T>(::std::marker::PhantomData<T>);
|
||||
|
||||
unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
|
||||
|
||||
impl<T: MyTrait> !Send for TestType<T> {}
|
||||
//~^ ERROR found both positive and negative implementation
|
||||
//~| ERROR `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not
|
||||
|
||||
unsafe impl<T: 'static> Send for TestType<T> {} //~ ERROR conflicting implementations
|
||||
|
||||
impl !Send for TestType<i32> {}
|
||||
//~^ ERROR `!Send` impls cannot be specialized
|
||||
|
||||
fn main() {}
|
||||
@@ -1,47 +0,0 @@
|
||||
error[E0751]: found both positive and negative implementation of trait `Send` for type `TestType<_>`:
|
||||
--> $DIR/primary-fluent-bundle-missing.rs:15:1
|
||||
|
|
||||
LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
|
||||
| ------------------------------------------------------ positive implementation here
|
||||
LL |
|
||||
LL | impl<T: MyTrait> !Send for TestType<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Send` for type `TestType<_>`
|
||||
--> $DIR/primary-fluent-bundle-missing.rs:19:1
|
||||
|
|
||||
LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
|
||||
| ------------------------------------------------------ first implementation here
|
||||
...
|
||||
LL | unsafe impl<T: 'static> Send for TestType<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
|
||||
|
||||
error[E0367]: `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not
|
||||
--> $DIR/primary-fluent-bundle-missing.rs:15:9
|
||||
|
|
||||
LL | impl<T: MyTrait> !Send for TestType<T> {}
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: the implementor must specify the same requirement
|
||||
--> $DIR/primary-fluent-bundle-missing.rs:11:1
|
||||
|
|
||||
LL | struct TestType<T>(::std::marker::PhantomData<T>);
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0366]: `!Send` impls cannot be specialized
|
||||
--> $DIR/primary-fluent-bundle-missing.rs:21:1
|
||||
|
|
||||
LL | impl !Send for TestType<i32> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `i32` is not a generic parameter
|
||||
note: use the same sequence of generic lifetime, type and const parameters as the struct definition
|
||||
--> $DIR/primary-fluent-bundle-missing.rs:11:1
|
||||
|
|
||||
LL | struct TestType<T>(::std::marker::PhantomData<T>);
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0119, E0366, E0367, E0751.
|
||||
For more information about an error, try `rustc --explain E0119`.
|
||||
@@ -1,5 +1,3 @@
|
||||
//@ compile-flags:-Ztranslate-lang=en_US
|
||||
|
||||
#![feature(negative_impls)]
|
||||
#![feature(marker_trait_attr)]
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
error[E0751]: found both positive and negative implementation of trait `Send` for type `TestType<_>`:
|
||||
--> $DIR/conflicting-send-impls-for-marker-trait-106755.rs:13:1
|
||||
--> $DIR/conflicting-send-impls-for-marker-trait-106755.rs:11:1
|
||||
|
|
||||
LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
|
||||
| ------------------------------------------------------ positive implementation here
|
||||
@@ -8,7 +8,7 @@ LL | impl<T: MyTrait> !Send for TestType<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Send` for type `TestType<_>`
|
||||
--> $DIR/conflicting-send-impls-for-marker-trait-106755.rs:17:1
|
||||
--> $DIR/conflicting-send-impls-for-marker-trait-106755.rs:15:1
|
||||
|
|
||||
LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
|
||||
| ------------------------------------------------------ first implementation here
|
||||
@@ -17,26 +17,26 @@ LL | unsafe impl<T: 'static> Send for TestType<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
|
||||
|
||||
error[E0367]: `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not
|
||||
--> $DIR/conflicting-send-impls-for-marker-trait-106755.rs:13:9
|
||||
--> $DIR/conflicting-send-impls-for-marker-trait-106755.rs:11:9
|
||||
|
|
||||
LL | impl<T: MyTrait> !Send for TestType<T> {}
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: the implementor must specify the same requirement
|
||||
--> $DIR/conflicting-send-impls-for-marker-trait-106755.rs:9:1
|
||||
--> $DIR/conflicting-send-impls-for-marker-trait-106755.rs:7:1
|
||||
|
|
||||
LL | struct TestType<T>(::std::marker::PhantomData<T>);
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0366]: `!Send` impls cannot be specialized
|
||||
--> $DIR/conflicting-send-impls-for-marker-trait-106755.rs:19:1
|
||||
--> $DIR/conflicting-send-impls-for-marker-trait-106755.rs:17:1
|
||||
|
|
||||
LL | impl !Send for TestType<i32> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `i32` is not a generic parameter
|
||||
note: use the same sequence of generic lifetime, type and const parameters as the struct definition
|
||||
--> $DIR/conflicting-send-impls-for-marker-trait-106755.rs:9:1
|
||||
--> $DIR/conflicting-send-impls-for-marker-trait-106755.rs:7:1
|
||||
|
|
||||
LL | struct TestType<T>(::std::marker::PhantomData<T>);
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Reference in New Issue
Block a user