mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Auto merge of #101333 - matthiaskrgr:rollup-qpf1otj, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #100121 (Try normalizing types without RevealAll in ParamEnv in MIR validation) - #100200 (Change implementation of `-Z gcc-ld` and `lld-wrapper` again) - #100814 ( Porting 'compiler/rustc_trait_selection' to translatable diagnostics - Part 1) - #101215 (Also replace the version placeholder in rustc_attr) - #101260 (Use `FILE_ATTRIBUTE_TAG_INFO` to get reparse tag) - #101323 (Remove unused .toggle-label CSS rule) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
9ba169a73a
@ -15,6 +15,12 @@ use std::num::NonZeroU32;
|
||||
|
||||
use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause};
|
||||
|
||||
/// The version placeholder that recently stabilized features contain inside the
|
||||
/// `since` field of the `#[stable]` attribute.
|
||||
///
|
||||
/// For more, see [this pull request](https://github.com/rust-lang/rust/pull/100591).
|
||||
pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION";
|
||||
|
||||
pub fn is_builtin_attr(attr: &Attribute) -> bool {
|
||||
attr.is_doc_comment() || attr.ident().filter(|ident| is_builtin_attr_name(ident.name)).is_some()
|
||||
}
|
||||
@ -483,6 +489,12 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(s) = since && s.as_str() == VERSION_PLACEHOLDER {
|
||||
let version = option_env!("CFG_VERSION").unwrap_or("<current>");
|
||||
let version = version.split(' ').next().unwrap();
|
||||
since = Some(Symbol::intern(&version));
|
||||
}
|
||||
|
||||
match (feature, since) {
|
||||
(Some(feature), Some(since)) => {
|
||||
let level = Stable { since, allowed_through_unstable_modules: false };
|
||||
|
@ -2797,20 +2797,24 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
|
||||
if let LinkerFlavor::Gcc = flavor {
|
||||
match ld_impl {
|
||||
LdImpl::Lld => {
|
||||
let tools_path = sess.get_tools_search_paths(false);
|
||||
let gcc_ld_dir = tools_path
|
||||
.into_iter()
|
||||
.map(|p| p.join("gcc-ld"))
|
||||
.find(|p| {
|
||||
p.join(if sess.host.is_like_windows { "ld.exe" } else { "ld" }).exists()
|
||||
})
|
||||
.unwrap_or_else(|| sess.fatal("rust-lld (as ld) not found"));
|
||||
cmd.arg({
|
||||
let mut arg = OsString::from("-B");
|
||||
arg.push(gcc_ld_dir);
|
||||
arg
|
||||
});
|
||||
cmd.arg(format!("-Wl,-rustc-lld-flavor={}", sess.target.lld_flavor.as_str()));
|
||||
// Implement the "self-contained" part of -Zgcc-ld
|
||||
// by adding rustc distribution directories to the tool search path.
|
||||
for path in sess.get_tools_search_paths(false) {
|
||||
cmd.arg({
|
||||
let mut arg = OsString::from("-B");
|
||||
arg.push(path.join("gcc-ld"));
|
||||
arg
|
||||
});
|
||||
}
|
||||
// Implement the "linker flavor" part of -Zgcc-ld
|
||||
// by asking cc to use some kind of lld.
|
||||
cmd.arg("-fuse-ld=lld");
|
||||
if sess.target.lld_flavor != LldFlavor::Ld {
|
||||
// Tell clang to use a non-default LLD flavor.
|
||||
// Gcc doesn't understand the target option, but we currently assume
|
||||
// that gcc is not used for Apple and Wasm targets (#97402).
|
||||
cmd.arg(format!("--target={}", sess.target.llvm_target));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,26 @@
|
||||
trait_selection_dump_vtable_entries = vtable entries for `{$trait_ref}`: {$entries}
|
||||
|
||||
trait_selection_unable_to_construct_constant_value = unable to construct a constant value for the unevaluated constant {$unevaluated}
|
||||
|
||||
trait_selection_auto_deref_reached_recursion_limit = reached the recursion limit while auto-dereferencing `{$ty}`
|
||||
.label = deref recursion limit reached
|
||||
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)
|
||||
|
||||
trait_selection_empty_on_clause_in_rustc_on_unimplemented = empty `on`-clause in `#[rustc_on_unimplemented]`
|
||||
.label = empty on-clause here
|
||||
|
||||
trait_selection_invalid_on_clause_in_rustc_on_unimplemented = invalid `on`-clause in `#[rustc_on_unimplemented]`
|
||||
.label = invalid on-clause here
|
||||
|
||||
trait_selection_no_value_in_rustc_on_unimplemented = this attribute must have a valid value
|
||||
.label = expected value here
|
||||
.note = eg `#[rustc_on_unimplemented(message="foo")]`
|
||||
|
||||
trait_selection_negative_positive_conflict = found both positive and negative implementation of trait `{$trait_desc}`{$self_desc ->
|
||||
[none] {""}
|
||||
*[default] {" "}for type `{$self_desc}`
|
||||
}:
|
||||
.negative_implementation_here = negative implementation here
|
||||
.negative_implementation_in_crate = negative implementation in crate `{$negative_impl_cname}`
|
||||
.positive_implementation_here = positive implementation here
|
||||
.positive_implementation_in_crate = positive implementation in crate `{$positive_impl_cname}`
|
@ -53,6 +53,7 @@ fluent_messages! {
|
||||
plugin_impl => "../locales/en-US/plugin_impl.ftl",
|
||||
privacy => "../locales/en-US/privacy.ftl",
|
||||
query_system => "../locales/en-US/query_system.ftl",
|
||||
trait_selection => "../locales/en-US/trait_selection.ftl",
|
||||
save_analysis => "../locales/en-US/save_analysis.ftl",
|
||||
ty_utils => "../locales/en-US/ty_utils.ftl",
|
||||
typeck => "../locales/en-US/typeck.ftl",
|
||||
|
@ -20,6 +20,12 @@ pub struct Unevaluated<'tcx, P = Option<Promoted>> {
|
||||
pub promoted: P,
|
||||
}
|
||||
|
||||
impl rustc_errors::IntoDiagnosticArg for Unevaluated<'_> {
|
||||
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
|
||||
format!("{:?}", self).into_diagnostic_arg()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Unevaluated<'tcx> {
|
||||
#[inline]
|
||||
pub fn shrink(self) -> Unevaluated<'tcx, ()> {
|
||||
|
@ -849,6 +849,12 @@ impl<'tcx> PolyTraitRef<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl rustc_errors::IntoDiagnosticArg for PolyTraitRef<'_> {
|
||||
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
|
||||
self.to_string().into_diagnostic_arg()
|
||||
}
|
||||
}
|
||||
|
||||
/// An existential reference to a trait, where `Self` is erased.
|
||||
/// For example, the trait object `Trait<'a, 'b, X, Y>` is:
|
||||
/// ```ignore (illustrative)
|
||||
|
@ -5,6 +5,7 @@
|
||||
//! collect them instead.
|
||||
|
||||
use rustc_ast::{Attribute, MetaItemKind};
|
||||
use rustc_attr::VERSION_PLACEHOLDER;
|
||||
use rustc_errors::struct_span_err;
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_middle::hir::nested_filter;
|
||||
@ -54,7 +55,6 @@ impl<'tcx> LibFeatureCollector<'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION";
|
||||
|
||||
if let Some(s) = since && s.as_str() == VERSION_PLACEHOLDER {
|
||||
let version = option_env!("CFG_VERSION").unwrap_or("<current>");
|
||||
|
@ -110,6 +110,12 @@ impl Mul<usize> for Limit {
|
||||
}
|
||||
}
|
||||
|
||||
impl rustc_errors::IntoDiagnosticArg for Limit {
|
||||
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
|
||||
self.to_string().into_diagnostic_arg()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, HashStable_Generic)]
|
||||
pub struct Limits {
|
||||
/// The maximum recursion limit for potentially infinitely recursive
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::errors::AutoDerefReachedRecursionLimit;
|
||||
use crate::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
use crate::traits::{self, TraitEngine};
|
||||
use rustc_errors::struct_span_err;
|
||||
use rustc_hir as hir;
|
||||
use rustc_infer::infer::InferCtxt;
|
||||
use rustc_middle::ty::{self, TraitRef, Ty, TyCtxt};
|
||||
@ -222,19 +222,10 @@ pub fn report_autoderef_recursion_limit_error<'tcx>(tcx: TyCtxt<'tcx>, span: Spa
|
||||
Limit(0) => Limit(2),
|
||||
limit => limit * 2,
|
||||
};
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
tcx.sess.emit_err(AutoDerefReachedRecursionLimit {
|
||||
span,
|
||||
E0055,
|
||||
"reached the recursion limit while auto-dereferencing `{:?}`",
|
||||
ty
|
||||
)
|
||||
.span_label(span, "deref recursion limit reached")
|
||||
.help(&format!(
|
||||
"consider increasing the recursion limit by adding a \
|
||||
`#![recursion_limit = \"{}\"]` attribute to your crate (`{}`)",
|
||||
ty,
|
||||
suggested_limit,
|
||||
tcx.crate_name(LOCAL_CRATE),
|
||||
))
|
||||
.emit();
|
||||
crate_name: tcx.crate_name(LOCAL_CRATE),
|
||||
});
|
||||
}
|
||||
|
102
compiler/rustc_trait_selection/src/errors.rs
Normal file
102
compiler/rustc_trait_selection/src/errors.rs
Normal file
@ -0,0 +1,102 @@
|
||||
use rustc_errors::{fluent, ErrorGuaranteed};
|
||||
use rustc_macros::SessionDiagnostic;
|
||||
use rustc_middle::ty::{PolyTraitRef, Ty, Unevaluated};
|
||||
use rustc_session::{parse::ParseSess, Limit, SessionDiagnostic};
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(trait_selection::dump_vtable_entries)]
|
||||
pub struct DumpVTableEntries<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub trait_ref: PolyTraitRef<'a>,
|
||||
pub entries: String,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(trait_selection::unable_to_construct_constant_value)]
|
||||
pub struct UnableToConstructConstantValue<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub unevaluated: Unevaluated<'a>,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[help]
|
||||
#[diag(trait_selection::auto_deref_reached_recursion_limit, code = "E0055")]
|
||||
pub struct AutoDerefReachedRecursionLimit<'a> {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
pub ty: Ty<'a>,
|
||||
pub suggested_limit: Limit,
|
||||
pub crate_name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(trait_selection::empty_on_clause_in_rustc_on_unimplemented, code = "E0232")]
|
||||
pub struct EmptyOnClauseInOnUnimplemented {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(trait_selection::invalid_on_clause_in_rustc_on_unimplemented, code = "E0232")]
|
||||
pub struct InvalidOnClauseInOnUnimplemented {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(trait_selection::no_value_in_rustc_on_unimplemented, code = "E0232")]
|
||||
#[note]
|
||||
pub struct NoValueInOnUnimplemented {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
pub struct NegativePositiveConflict<'a> {
|
||||
pub impl_span: Span,
|
||||
pub trait_desc: &'a str,
|
||||
pub self_desc: &'a Option<String>,
|
||||
pub negative_impl_span: Result<Span, Symbol>,
|
||||
pub positive_impl_span: Result<Span, Symbol>,
|
||||
}
|
||||
|
||||
impl SessionDiagnostic<'_> for NegativePositiveConflict<'_> {
|
||||
fn into_diagnostic(
|
||||
self,
|
||||
sess: &ParseSess,
|
||||
) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
|
||||
let mut diag = sess.struct_err(fluent::trait_selection::negative_positive_conflict);
|
||||
diag.set_arg("trait_desc", self.trait_desc);
|
||||
diag.set_arg(
|
||||
"self_desc",
|
||||
self.self_desc.clone().map_or_else(|| String::from("none"), |ty| ty),
|
||||
);
|
||||
diag.set_span(self.impl_span);
|
||||
diag.code(rustc_errors::error_code!(E0751));
|
||||
match self.negative_impl_span {
|
||||
Ok(span) => {
|
||||
diag.span_label(span, fluent::trait_selection::negative_implementation_here);
|
||||
}
|
||||
Err(cname) => {
|
||||
diag.note(fluent::trait_selection::negative_implementation_in_crate);
|
||||
diag.set_arg("negative_impl_cname", cname.to_string());
|
||||
}
|
||||
}
|
||||
match self.positive_impl_span {
|
||||
Ok(span) => {
|
||||
diag.span_label(span, fluent::trait_selection::positive_implementation_here);
|
||||
}
|
||||
Err(cname) => {
|
||||
diag.note(fluent::trait_selection::positive_implementation_in_crate);
|
||||
diag.set_arg("positive_impl_cname", cname.to_string());
|
||||
}
|
||||
}
|
||||
diag
|
||||
}
|
||||
}
|
@ -37,5 +37,6 @@ extern crate rustc_middle;
|
||||
extern crate smallvec;
|
||||
|
||||
pub mod autoderef;
|
||||
pub mod errors;
|
||||
pub mod infer;
|
||||
pub mod traits;
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
use super::*;
|
||||
|
||||
use crate::errors::UnableToConstructConstantValue;
|
||||
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
|
||||
use crate::infer::InferCtxt;
|
||||
use crate::traits::project::ProjectAndUnifyResult;
|
||||
@ -830,8 +831,11 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||
Ok(None) => {
|
||||
let tcx = self.tcx;
|
||||
let def_id = unevaluated.def.did;
|
||||
let reported = tcx.sess.struct_span_err(tcx.def_span(def_id), &format!("unable to construct a constant value for the unevaluated constant {:?}", unevaluated)).emit();
|
||||
|
||||
let reported =
|
||||
tcx.sess.emit_err(UnableToConstructConstantValue {
|
||||
span: tcx.def_span(def_id),
|
||||
unevaluated,
|
||||
});
|
||||
Err(ErrorHandled::Reported(reported))
|
||||
}
|
||||
Err(err) => Err(err),
|
||||
|
@ -23,6 +23,7 @@ mod structural_match;
|
||||
mod util;
|
||||
pub mod wf;
|
||||
|
||||
use crate::errors::DumpVTableEntries;
|
||||
use crate::infer::outlives::env::OutlivesEnvironment;
|
||||
use crate::infer::{InferCtxt, TyCtxtInferExt};
|
||||
use crate::traits::error_reporting::InferCtxtExt as _;
|
||||
@ -763,8 +764,11 @@ fn dump_vtable_entries<'tcx>(
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
entries: &[VtblEntry<'tcx>],
|
||||
) {
|
||||
let msg = format!("vtable entries for `{}`: {:#?}", trait_ref, entries);
|
||||
tcx.sess.struct_span_err(sp, &msg).emit();
|
||||
tcx.sess.emit_err(DumpVTableEntries {
|
||||
span: sp,
|
||||
trait_ref,
|
||||
entries: format!("{:#?}", entries),
|
||||
});
|
||||
}
|
||||
|
||||
fn own_existential_vtable_entries<'tcx>(
|
||||
|
@ -8,6 +8,10 @@ use rustc_parse_format::{ParseMode, Parser, Piece, Position};
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
use crate::errors::{
|
||||
EmptyOnClauseInOnUnimplemented, InvalidOnClauseInOnUnimplemented, NoValueInOnUnimplemented,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct OnUnimplementedFormatString(Symbol);
|
||||
|
||||
@ -35,21 +39,6 @@ pub struct OnUnimplementedNote {
|
||||
pub append_const_msg: Option<Option<Symbol>>,
|
||||
}
|
||||
|
||||
fn parse_error(
|
||||
tcx: TyCtxt<'_>,
|
||||
span: Span,
|
||||
message: &str,
|
||||
label: &str,
|
||||
note: Option<&str>,
|
||||
) -> ErrorGuaranteed {
|
||||
let mut diag = struct_span_err!(tcx.sess, span, E0232, "{}", message);
|
||||
diag.span_label(span, label);
|
||||
if let Some(note) = note {
|
||||
diag.note(note);
|
||||
}
|
||||
diag.emit()
|
||||
}
|
||||
|
||||
impl<'tcx> OnUnimplementedDirective {
|
||||
fn parse(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
@ -70,25 +59,9 @@ impl<'tcx> OnUnimplementedDirective {
|
||||
} else {
|
||||
let cond = item_iter
|
||||
.next()
|
||||
.ok_or_else(|| {
|
||||
parse_error(
|
||||
tcx,
|
||||
span,
|
||||
"empty `on`-clause in `#[rustc_on_unimplemented]`",
|
||||
"empty on-clause here",
|
||||
None,
|
||||
)
|
||||
})?
|
||||
.ok_or_else(|| tcx.sess.emit_err(EmptyOnClauseInOnUnimplemented { span }))?
|
||||
.meta_item()
|
||||
.ok_or_else(|| {
|
||||
parse_error(
|
||||
tcx,
|
||||
span,
|
||||
"invalid `on`-clause in `#[rustc_on_unimplemented]`",
|
||||
"invalid on-clause here",
|
||||
None,
|
||||
)
|
||||
})?;
|
||||
.ok_or_else(|| tcx.sess.emit_err(InvalidOnClauseInOnUnimplemented { span }))?;
|
||||
attr::eval_condition(cond, &tcx.sess.parse_sess, Some(tcx.features()), &mut |cfg| {
|
||||
if let Some(value) = cfg.value && let Err(guar) = parse_value(value) {
|
||||
errored = Some(guar);
|
||||
@ -150,13 +123,7 @@ impl<'tcx> OnUnimplementedDirective {
|
||||
}
|
||||
|
||||
// nothing found
|
||||
parse_error(
|
||||
tcx,
|
||||
item.span(),
|
||||
"this attribute must have a valid value",
|
||||
"expected value here",
|
||||
Some(r#"eg `#[rustc_on_unimplemented(message="foo")]`"#),
|
||||
);
|
||||
tcx.sess.emit_err(NoValueInOnUnimplemented { span: item.span() });
|
||||
}
|
||||
|
||||
if let Some(reported) = errored {
|
||||
|
@ -12,6 +12,7 @@
|
||||
pub mod specialization_graph;
|
||||
use specialization_graph::GraphExt;
|
||||
|
||||
use crate::errors::NegativePositiveConflict;
|
||||
use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt};
|
||||
use crate::traits::select::IntercrateAmbiguityCause;
|
||||
use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause};
|
||||
@ -327,35 +328,13 @@ fn report_negative_positive_conflict(
|
||||
positive_impl_def_id: DefId,
|
||||
sg: &mut specialization_graph::Graph,
|
||||
) {
|
||||
let impl_span = tcx.def_span(local_impl_def_id);
|
||||
|
||||
let mut err = struct_span_err!(
|
||||
tcx.sess,
|
||||
impl_span,
|
||||
E0751,
|
||||
"found both positive and negative implementation of trait `{}`{}:",
|
||||
overlap.trait_desc,
|
||||
overlap.self_desc.clone().map_or_else(String::new, |ty| format!(" for type `{}`", ty))
|
||||
);
|
||||
|
||||
match tcx.span_of_impl(negative_impl_def_id) {
|
||||
Ok(span) => {
|
||||
err.span_label(span, "negative implementation here");
|
||||
}
|
||||
Err(cname) => {
|
||||
err.note(&format!("negative implementation in crate `{}`", cname));
|
||||
}
|
||||
}
|
||||
|
||||
match tcx.span_of_impl(positive_impl_def_id) {
|
||||
Ok(span) => {
|
||||
err.span_label(span, "positive implementation here");
|
||||
}
|
||||
Err(cname) => {
|
||||
err.note(&format!("positive implementation in crate `{}`", cname));
|
||||
}
|
||||
}
|
||||
|
||||
let mut err = tcx.sess.create_err(NegativePositiveConflict {
|
||||
impl_span: tcx.def_span(local_impl_def_id),
|
||||
trait_desc: &overlap.trait_desc,
|
||||
self_desc: &overlap.self_desc,
|
||||
negative_impl_span: tcx.span_of_impl(negative_impl_def_id),
|
||||
positive_impl_span: tcx.span_of_impl(positive_impl_def_id),
|
||||
});
|
||||
sg.has_errored = Some(err.emit());
|
||||
}
|
||||
|
||||
|
@ -454,6 +454,12 @@ pub enum FILE_INFO_BY_HANDLE_CLASS {
|
||||
MaximumFileInfoByHandlesClass,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FILE_ATTRIBUTE_TAG_INFO {
|
||||
pub FileAttributes: DWORD,
|
||||
pub ReparseTag: DWORD,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FILE_DISPOSITION_INFO {
|
||||
pub DeleteFile: BOOLEAN,
|
||||
|
@ -326,10 +326,15 @@ impl File {
|
||||
cvt(c::GetFileInformationByHandle(self.handle.as_raw_handle(), &mut info))?;
|
||||
let mut reparse_tag = 0;
|
||||
if info.dwFileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
|
||||
let mut b =
|
||||
Align8([MaybeUninit::<u8>::uninit(); c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]);
|
||||
if let Ok((_, buf)) = self.reparse_point(&mut b) {
|
||||
reparse_tag = (*buf).ReparseTag;
|
||||
let mut attr_tag: c::FILE_ATTRIBUTE_TAG_INFO = mem::zeroed();
|
||||
cvt(c::GetFileInformationByHandleEx(
|
||||
self.handle.as_raw_handle(),
|
||||
c::FileAttributeTagInfo,
|
||||
ptr::addr_of_mut!(attr_tag).cast(),
|
||||
mem::size_of::<c::FILE_ATTRIBUTE_TAG_INFO>().try_into().unwrap(),
|
||||
))?;
|
||||
if attr_tag.FileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
|
||||
reparse_tag = attr_tag.ReparseTag;
|
||||
}
|
||||
}
|
||||
Ok(FileAttr {
|
||||
@ -390,10 +395,15 @@ impl File {
|
||||
attr.file_size = info.AllocationSize as u64;
|
||||
attr.number_of_links = Some(info.NumberOfLinks);
|
||||
if attr.file_type().is_reparse_point() {
|
||||
let mut b =
|
||||
Align8([MaybeUninit::<u8>::uninit(); c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]);
|
||||
if let Ok((_, buf)) = self.reparse_point(&mut b) {
|
||||
attr.reparse_tag = (*buf).ReparseTag;
|
||||
let mut attr_tag: c::FILE_ATTRIBUTE_TAG_INFO = mem::zeroed();
|
||||
cvt(c::GetFileInformationByHandleEx(
|
||||
self.handle.as_raw_handle(),
|
||||
c::FileAttributeTagInfo,
|
||||
ptr::addr_of_mut!(attr_tag).cast(),
|
||||
mem::size_of::<c::FILE_ATTRIBUTE_TAG_INFO>().try_into().unwrap(),
|
||||
))?;
|
||||
if attr_tag.FileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
|
||||
reparse_tag = attr_tag.ReparseTag;
|
||||
}
|
||||
}
|
||||
Ok(attr)
|
||||
|
@ -1281,7 +1281,9 @@ impl Step for Assemble {
|
||||
compiler: build_compiler,
|
||||
target: target_compiler.host,
|
||||
});
|
||||
builder.copy(&lld_wrapper_exe, &gcc_ld_dir.join(exe("ld", target_compiler.host)));
|
||||
for name in crate::LLD_FILE_NAMES {
|
||||
builder.copy(&lld_wrapper_exe, &gcc_ld_dir.join(exe(name, target_compiler.host)));
|
||||
}
|
||||
}
|
||||
|
||||
if builder.config.rust_codegen_backends.contains(&INTERNER.intern_str("llvm")) {
|
||||
|
@ -423,8 +423,11 @@ impl Step for Rustc {
|
||||
let gcc_lld_src_dir = src_dir.join("gcc-ld");
|
||||
let gcc_lld_dst_dir = dst_dir.join("gcc-ld");
|
||||
t!(fs::create_dir(&gcc_lld_dst_dir));
|
||||
let exe_name = exe("ld", compiler.host);
|
||||
builder.copy(&gcc_lld_src_dir.join(&exe_name), &gcc_lld_dst_dir.join(&exe_name));
|
||||
for name in crate::LLD_FILE_NAMES {
|
||||
let exe_name = exe(name, compiler.host);
|
||||
builder
|
||||
.copy(&gcc_lld_src_dir.join(&exe_name), &gcc_lld_dst_dir.join(&exe_name));
|
||||
}
|
||||
}
|
||||
|
||||
// Man pages
|
||||
|
@ -187,6 +187,9 @@ const LLVM_TOOLS: &[&str] = &[
|
||||
"opt", // used to optimize LLVM bytecode
|
||||
];
|
||||
|
||||
/// LLD file names for all flavors.
|
||||
const LLD_FILE_NAMES: &[&str] = &["ld.lld", "ld64.lld", "lld-link", "wasm-ld"];
|
||||
|
||||
pub const VERSION: usize = 2;
|
||||
|
||||
/// Extra --check-cfg to add when building
|
||||
|
@ -1241,12 +1241,6 @@ h3.variant {
|
||||
margin-left: 24px;
|
||||
}
|
||||
|
||||
.toggle-label {
|
||||
display: inline-block;
|
||||
margin-left: 4px;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
:target > code, :target > .code-header {
|
||||
opacity: 1;
|
||||
}
|
||||
|
@ -242,7 +242,6 @@ a.test-arrow:hover {
|
||||
color: #c5c5c5;
|
||||
}
|
||||
|
||||
.toggle-label,
|
||||
.code-attribute {
|
||||
color: #999;
|
||||
}
|
||||
|
@ -197,7 +197,6 @@ a.test-arrow:hover{
|
||||
background-color: #4e8bca;
|
||||
}
|
||||
|
||||
.toggle-label,
|
||||
.code-attribute {
|
||||
color: #999;
|
||||
}
|
||||
|
@ -182,7 +182,6 @@ a.test-arrow:hover{
|
||||
background-color: #4e8bca;
|
||||
}
|
||||
|
||||
.toggle-label,
|
||||
.code-attribute {
|
||||
color: #999;
|
||||
}
|
||||
|
25
src/test/ui/mir/issue-99866.rs
Normal file
25
src/test/ui/mir/issue-99866.rs
Normal file
@ -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() {}
|
@ -8,8 +8,8 @@
|
||||
//! make gcc/clang pass `-flavor <flavor>` as the first two arguments in the linker invocation
|
||||
//! and since Windows does not support symbolic links for files this wrapper is used in place of a
|
||||
//! symbolic link. It execs `../rust-lld -flavor <flavor>` by propagating the flavor argument
|
||||
//! passed to the wrapper as the first two arguments. On Windows it spawns a `..\rust-lld.exe`
|
||||
//! child process.
|
||||
//! obtained from the wrapper's name as the first two arguments.
|
||||
//! On Windows it spawns a `..\rust-lld.exe` child process.
|
||||
|
||||
use std::fmt::Display;
|
||||
use std::path::{Path, PathBuf};
|
||||
@ -53,29 +53,32 @@ fn get_rust_lld_path(current_exe_path: &Path) -> PathBuf {
|
||||
rust_lld_path
|
||||
}
|
||||
|
||||
/// Extract LLD flavor name from the lld-wrapper executable name.
|
||||
fn get_lld_flavor(current_exe_path: &Path) -> Result<&'static str, String> {
|
||||
let stem = current_exe_path.file_stem();
|
||||
Ok(match stem.and_then(|s| s.to_str()) {
|
||||
Some("ld.lld") => "gnu",
|
||||
Some("ld64.lld") => "darwin",
|
||||
Some("lld-link") => "link",
|
||||
Some("wasm-ld") => "wasm",
|
||||
_ => return Err(format!("{:?}", stem)),
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the command for invoking rust-lld with the correct flavor.
|
||||
/// LLD only accepts the flavor argument at the first two arguments, so move it there.
|
||||
/// LLD only accepts the flavor argument at the first two arguments, so pass it there.
|
||||
///
|
||||
/// Exits on error.
|
||||
fn get_rust_lld_command(current_exe_path: &Path) -> process::Command {
|
||||
let rust_lld_path = get_rust_lld_path(current_exe_path);
|
||||
let mut command = process::Command::new(rust_lld_path);
|
||||
|
||||
let mut flavor = None;
|
||||
let args = env::args_os()
|
||||
.skip(1)
|
||||
.filter(|arg| match arg.to_str().and_then(|s| s.strip_prefix("-rustc-lld-flavor=")) {
|
||||
Some(suffix) => {
|
||||
flavor = Some(suffix.to_string());
|
||||
false
|
||||
}
|
||||
None => true,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let flavor =
|
||||
get_lld_flavor(current_exe_path).unwrap_or_exit_with("executable has unexpected name");
|
||||
|
||||
command.arg("-flavor");
|
||||
command.arg(flavor.unwrap_or_exit_with("-rustc-lld-flavor=<flavor> is not passed"));
|
||||
command.args(args);
|
||||
command.arg(flavor);
|
||||
command.args(env::args_os().skip(1));
|
||||
command
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ fn main() {
|
||||
walk::filter_dirs(path)
|
||||
// We exempt these as they require the placeholder
|
||||
// for their operation
|
||||
|| path.ends_with("compiler/rustc_passes/src/lib_features.rs")
|
||||
|| path.ends_with("compiler/rustc_attr/src/builtin.rs")
|
||||
|| path.ends_with("src/tools/tidy/src/features/version.rs")
|
||||
|| path.ends_with("src/tools/replace-version-placeholder")
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user