Auto merge of #151409 - GuillaumeGomez:rollup-bDqwVwM, r=GuillaumeGomez
Rollup of 6 pull requests Successful merges: - rust-lang/rust#147611 (Stabilize `-Zremap-path-scope`) - rust-lang/rust#149058 (FCW Lint when using an ambiguously glob imported trait) - rust-lang/rust#149644 (Create x86_64-unknown-linux-gnuasan target which enables ASAN by default) - rust-lang/rust#150524 (Test that -Zbuild-std=core works on a variety of profiles) - rust-lang/rust#151394 (Fix typos: 'occured' -> 'occurred' and 'non_existant' -> 'non_existent') - rust-lang/rust#151396 (`rustc_queries!`: Don't push the `(cache)` modifier twice) r? @ghost
This commit is contained in:
commit
5c49c4f7c8
67 changed files with 880 additions and 140 deletions
|
|
@ -3337,6 +3337,7 @@ dependencies = [
|
||||||
"rustdoc-json-types",
|
"rustdoc-json-types",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"similar",
|
"similar",
|
||||||
|
"tempfile",
|
||||||
"wasmparser 0.236.1",
|
"wasmparser 0.236.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4615,6 +4615,11 @@ pub struct Upvar {
|
||||||
pub struct TraitCandidate {
|
pub struct TraitCandidate {
|
||||||
pub def_id: DefId,
|
pub def_id: DefId,
|
||||||
pub import_ids: SmallVec<[LocalDefId; 1]>,
|
pub import_ids: SmallVec<[LocalDefId; 1]>,
|
||||||
|
// Indicates whether this trait candidate is ambiguously glob imported
|
||||||
|
// in it's scope. Related to the AMBIGUOUS_GLOB_IMPORTED_TRAITS lint.
|
||||||
|
// If this is set to true and the trait is used as a result of method lookup, this
|
||||||
|
// lint is thrown.
|
||||||
|
pub lint_ambiguous: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, HashStable_Generic)]
|
#[derive(Copy, Clone, Debug, HashStable_Generic)]
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::fmt::Debug;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
|
@ -12,7 +13,9 @@ use rustc_hir_analysis::hir_ty_lowering::{
|
||||||
use rustc_infer::infer::{
|
use rustc_infer::infer::{
|
||||||
BoundRegionConversionTime, DefineOpaqueTypes, InferOk, RegionVariableOrigin,
|
BoundRegionConversionTime, DefineOpaqueTypes, InferOk, RegionVariableOrigin,
|
||||||
};
|
};
|
||||||
use rustc_lint::builtin::RESOLVING_TO_ITEMS_SHADOWING_SUPERTRAIT_ITEMS;
|
use rustc_lint::builtin::{
|
||||||
|
AMBIGUOUS_GLOB_IMPORTED_TRAITS, RESOLVING_TO_ITEMS_SHADOWING_SUPERTRAIT_ITEMS,
|
||||||
|
};
|
||||||
use rustc_middle::traits::ObligationCauseCode;
|
use rustc_middle::traits::ObligationCauseCode;
|
||||||
use rustc_middle::ty::adjustment::{
|
use rustc_middle::ty::adjustment::{
|
||||||
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCoercion,
|
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCoercion,
|
||||||
|
|
@ -149,6 +152,9 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||||
// Lint when an item is shadowing a supertrait item.
|
// Lint when an item is shadowing a supertrait item.
|
||||||
self.lint_shadowed_supertrait_items(pick, segment);
|
self.lint_shadowed_supertrait_items(pick, segment);
|
||||||
|
|
||||||
|
// Lint when a trait is ambiguously imported
|
||||||
|
self.lint_ambiguously_glob_imported_traits(pick, segment);
|
||||||
|
|
||||||
// Add any trait/regions obligations specified on the method's type parameters.
|
// Add any trait/regions obligations specified on the method's type parameters.
|
||||||
// We won't add these if we encountered an illegal sized bound, so that we can use
|
// We won't add these if we encountered an illegal sized bound, so that we can use
|
||||||
// a custom error in that case.
|
// a custom error in that case.
|
||||||
|
|
@ -322,7 +328,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
probe::TraitPick => {
|
probe::TraitPick(_) => {
|
||||||
let trait_def_id = pick.item.container_id(self.tcx);
|
let trait_def_id = pick.item.container_id(self.tcx);
|
||||||
|
|
||||||
// Make a trait reference `$0 : Trait<$1...$n>`
|
// Make a trait reference `$0 : Trait<$1...$n>`
|
||||||
|
|
@ -719,6 +725,25 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn lint_ambiguously_glob_imported_traits(
|
||||||
|
&self,
|
||||||
|
pick: &probe::Pick<'_>,
|
||||||
|
segment: &hir::PathSegment<'tcx>,
|
||||||
|
) {
|
||||||
|
if pick.kind != probe::PickKind::TraitPick(true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let trait_name = self.tcx.item_name(pick.item.container_id(self.tcx));
|
||||||
|
let import_span = self.tcx.hir_span_if_local(pick.import_ids[0].to_def_id()).unwrap();
|
||||||
|
|
||||||
|
self.tcx.node_lint(AMBIGUOUS_GLOB_IMPORTED_TRAITS, segment.hir_id, |diag| {
|
||||||
|
diag.primary_message(format!("Use of ambiguously glob imported trait `{trait_name}`"))
|
||||||
|
.span(segment.ident.span)
|
||||||
|
.span_label(import_span, format!("`{trait_name}` imported ambiguously here"))
|
||||||
|
.help(format!("Import `{trait_name}` explicitly"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn upcast(
|
fn upcast(
|
||||||
&mut self,
|
&mut self,
|
||||||
source_trait_ref: ty::PolyTraitRef<'tcx>,
|
source_trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ pub(crate) struct Candidate<'tcx> {
|
||||||
pub(crate) enum CandidateKind<'tcx> {
|
pub(crate) enum CandidateKind<'tcx> {
|
||||||
InherentImplCandidate { impl_def_id: DefId, receiver_steps: usize },
|
InherentImplCandidate { impl_def_id: DefId, receiver_steps: usize },
|
||||||
ObjectCandidate(ty::PolyTraitRef<'tcx>),
|
ObjectCandidate(ty::PolyTraitRef<'tcx>),
|
||||||
TraitCandidate(ty::PolyTraitRef<'tcx>),
|
TraitCandidate(ty::PolyTraitRef<'tcx>, bool /* lint_ambiguous */),
|
||||||
WhereClauseCandidate(ty::PolyTraitRef<'tcx>),
|
WhereClauseCandidate(ty::PolyTraitRef<'tcx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -235,7 +235,10 @@ pub(crate) struct Pick<'tcx> {
|
||||||
pub(crate) enum PickKind<'tcx> {
|
pub(crate) enum PickKind<'tcx> {
|
||||||
InherentImplPick,
|
InherentImplPick,
|
||||||
ObjectPick,
|
ObjectPick,
|
||||||
TraitPick,
|
TraitPick(
|
||||||
|
// Is Ambiguously Imported
|
||||||
|
bool,
|
||||||
|
),
|
||||||
WhereClausePick(
|
WhereClausePick(
|
||||||
// Trait
|
// Trait
|
||||||
ty::PolyTraitRef<'tcx>,
|
ty::PolyTraitRef<'tcx>,
|
||||||
|
|
@ -560,7 +563,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
probe_cx.push_candidate(
|
probe_cx.push_candidate(
|
||||||
Candidate {
|
Candidate {
|
||||||
item,
|
item,
|
||||||
kind: CandidateKind::TraitCandidate(ty::Binder::dummy(trait_ref)),
|
kind: CandidateKind::TraitCandidate(
|
||||||
|
ty::Binder::dummy(trait_ref),
|
||||||
|
false,
|
||||||
|
),
|
||||||
import_ids: smallvec![],
|
import_ids: smallvec![],
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
|
|
@ -1018,6 +1024,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
self.assemble_extension_candidates_for_trait(
|
self.assemble_extension_candidates_for_trait(
|
||||||
&trait_candidate.import_ids,
|
&trait_candidate.import_ids,
|
||||||
trait_did,
|
trait_did,
|
||||||
|
trait_candidate.lint_ambiguous,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1029,7 +1036,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
let mut duplicates = FxHashSet::default();
|
let mut duplicates = FxHashSet::default();
|
||||||
for trait_info in suggest::all_traits(self.tcx) {
|
for trait_info in suggest::all_traits(self.tcx) {
|
||||||
if duplicates.insert(trait_info.def_id) {
|
if duplicates.insert(trait_info.def_id) {
|
||||||
self.assemble_extension_candidates_for_trait(&smallvec![], trait_info.def_id);
|
self.assemble_extension_candidates_for_trait(
|
||||||
|
&smallvec![],
|
||||||
|
trait_info.def_id,
|
||||||
|
false,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1055,6 +1066,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
import_ids: &SmallVec<[LocalDefId; 1]>,
|
import_ids: &SmallVec<[LocalDefId; 1]>,
|
||||||
trait_def_id: DefId,
|
trait_def_id: DefId,
|
||||||
|
lint_ambiguous: bool,
|
||||||
) {
|
) {
|
||||||
let trait_args = self.fresh_args_for_item(self.span, trait_def_id);
|
let trait_args = self.fresh_args_for_item(self.span, trait_def_id);
|
||||||
let trait_ref = ty::TraitRef::new_from_args(self.tcx, trait_def_id, trait_args);
|
let trait_ref = ty::TraitRef::new_from_args(self.tcx, trait_def_id, trait_args);
|
||||||
|
|
@ -1076,7 +1088,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
Candidate {
|
Candidate {
|
||||||
item,
|
item,
|
||||||
import_ids: import_ids.clone(),
|
import_ids: import_ids.clone(),
|
||||||
kind: TraitCandidate(bound_trait_ref),
|
kind: TraitCandidate(bound_trait_ref, lint_ambiguous),
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
@ -1099,7 +1111,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
Candidate {
|
Candidate {
|
||||||
item,
|
item,
|
||||||
import_ids: import_ids.clone(),
|
import_ids: import_ids.clone(),
|
||||||
kind: TraitCandidate(ty::Binder::dummy(trait_ref)),
|
kind: TraitCandidate(ty::Binder::dummy(trait_ref), lint_ambiguous),
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
@ -1842,7 +1854,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
ObjectCandidate(_) | WhereClauseCandidate(_) => {
|
ObjectCandidate(_) | WhereClauseCandidate(_) => {
|
||||||
CandidateSource::Trait(candidate.item.container_id(self.tcx))
|
CandidateSource::Trait(candidate.item.container_id(self.tcx))
|
||||||
}
|
}
|
||||||
TraitCandidate(trait_ref) => self.probe(|_| {
|
TraitCandidate(trait_ref, _) => self.probe(|_| {
|
||||||
let trait_ref = self.instantiate_binder_with_fresh_vars(
|
let trait_ref = self.instantiate_binder_with_fresh_vars(
|
||||||
self.span,
|
self.span,
|
||||||
BoundRegionConversionTime::FnCall,
|
BoundRegionConversionTime::FnCall,
|
||||||
|
|
@ -1872,7 +1884,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
fn candidate_source_from_pick(&self, pick: &Pick<'tcx>) -> CandidateSource {
|
fn candidate_source_from_pick(&self, pick: &Pick<'tcx>) -> CandidateSource {
|
||||||
match pick.kind {
|
match pick.kind {
|
||||||
InherentImplPick => CandidateSource::Impl(pick.item.container_id(self.tcx)),
|
InherentImplPick => CandidateSource::Impl(pick.item.container_id(self.tcx)),
|
||||||
ObjectPick | WhereClausePick(_) | TraitPick => {
|
ObjectPick | WhereClausePick(_) | TraitPick(_) => {
|
||||||
CandidateSource::Trait(pick.item.container_id(self.tcx))
|
CandidateSource::Trait(pick.item.container_id(self.tcx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1948,7 +1960,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
impl_bounds,
|
impl_bounds,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
TraitCandidate(poly_trait_ref) => {
|
TraitCandidate(poly_trait_ref, _) => {
|
||||||
// Some trait methods are excluded for arrays before 2021.
|
// Some trait methods are excluded for arrays before 2021.
|
||||||
// (`array.into_iter()` wants a slice iterator for compatibility.)
|
// (`array.into_iter()` wants a slice iterator for compatibility.)
|
||||||
if let Some(method_name) = self.method_name {
|
if let Some(method_name) = self.method_name {
|
||||||
|
|
@ -2274,11 +2286,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let lint_ambiguous = match probes[0].0.kind {
|
||||||
|
TraitCandidate(_, lint) => lint,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
// FIXME: check the return type here somehow.
|
// FIXME: check the return type here somehow.
|
||||||
// If so, just use this trait and call it a day.
|
// If so, just use this trait and call it a day.
|
||||||
Some(Pick {
|
Some(Pick {
|
||||||
item: probes[0].0.item,
|
item: probes[0].0.item,
|
||||||
kind: TraitPick,
|
kind: TraitPick(lint_ambiguous),
|
||||||
import_ids: probes[0].0.import_ids.clone(),
|
import_ids: probes[0].0.import_ids.clone(),
|
||||||
autoderefs: 0,
|
autoderefs: 0,
|
||||||
autoref_or_ptr_adjustment: None,
|
autoref_or_ptr_adjustment: None,
|
||||||
|
|
@ -2348,9 +2365,14 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let lint_ambiguous = match probes[0].0.kind {
|
||||||
|
TraitCandidate(_, lint) => lint,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
Some(Pick {
|
Some(Pick {
|
||||||
item: child_candidate.item,
|
item: child_candidate.item,
|
||||||
kind: TraitPick,
|
kind: TraitPick(lint_ambiguous),
|
||||||
import_ids: child_candidate.import_ids.clone(),
|
import_ids: child_candidate.import_ids.clone(),
|
||||||
autoderefs: 0,
|
autoderefs: 0,
|
||||||
autoref_or_ptr_adjustment: None,
|
autoref_or_ptr_adjustment: None,
|
||||||
|
|
@ -2613,7 +2635,7 @@ impl<'tcx> Candidate<'tcx> {
|
||||||
kind: match self.kind {
|
kind: match self.kind {
|
||||||
InherentImplCandidate { .. } => InherentImplPick,
|
InherentImplCandidate { .. } => InherentImplPick,
|
||||||
ObjectCandidate(_) => ObjectPick,
|
ObjectCandidate(_) => ObjectPick,
|
||||||
TraitCandidate(_) => TraitPick,
|
TraitCandidate(_, lint_ambiguous) => TraitPick(lint_ambiguous),
|
||||||
WhereClauseCandidate(trait_ref) => {
|
WhereClauseCandidate(trait_ref) => {
|
||||||
// Only trait derived from where-clauses should
|
// Only trait derived from where-clauses should
|
||||||
// appear here, so they should not contain any
|
// appear here, so they should not contain any
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ declare_lint_pass! {
|
||||||
AARCH64_SOFTFLOAT_NEON,
|
AARCH64_SOFTFLOAT_NEON,
|
||||||
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
|
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
|
||||||
AMBIGUOUS_ASSOCIATED_ITEMS,
|
AMBIGUOUS_ASSOCIATED_ITEMS,
|
||||||
|
AMBIGUOUS_GLOB_IMPORTED_TRAITS,
|
||||||
AMBIGUOUS_GLOB_IMPORTS,
|
AMBIGUOUS_GLOB_IMPORTS,
|
||||||
AMBIGUOUS_GLOB_REEXPORTS,
|
AMBIGUOUS_GLOB_REEXPORTS,
|
||||||
AMBIGUOUS_PANIC_IMPORTS,
|
AMBIGUOUS_PANIC_IMPORTS,
|
||||||
|
|
@ -4473,6 +4474,60 @@ declare_lint! {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare_lint! {
|
||||||
|
/// The `ambiguous_glob_imported_traits` lint reports uses of traits that are
|
||||||
|
/// imported ambiguously via glob imports. Previously, this was not enforced
|
||||||
|
/// due to a bug in rustc.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
///
|
||||||
|
/// ```rust,compile_fail
|
||||||
|
/// #![deny(ambiguous_glob_imported_traits)]
|
||||||
|
/// mod m1 {
|
||||||
|
/// pub trait Trait {
|
||||||
|
/// fn method1(&self) {}
|
||||||
|
/// }
|
||||||
|
/// impl Trait for u8 {}
|
||||||
|
/// }
|
||||||
|
/// mod m2 {
|
||||||
|
/// pub trait Trait {
|
||||||
|
/// fn method2(&self) {}
|
||||||
|
/// }
|
||||||
|
/// impl Trait for u8 {}
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// fn main() {
|
||||||
|
/// use m1::*;
|
||||||
|
/// use m2::*;
|
||||||
|
/// 0u8.method1();
|
||||||
|
/// 0u8.method2();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// {{produces}}
|
||||||
|
///
|
||||||
|
/// ### Explanation
|
||||||
|
///
|
||||||
|
/// When multiple traits with the same name are brought into scope through glob imports,
|
||||||
|
/// one trait becomes the "primary" one while the others are shadowed. Methods from the
|
||||||
|
/// shadowed traits (e.g. `method2`) become inaccessible, while methods from the "primary"
|
||||||
|
/// trait (e.g. `method1`) still resolve. Ideally, none of the ambiguous traits would be in scope,
|
||||||
|
/// but we have to allow this for now because of backwards compatibility.
|
||||||
|
/// This lint reports uses of these "primary" traits that are ambiguous.
|
||||||
|
///
|
||||||
|
/// This is a [future-incompatible] lint to transition this to a
|
||||||
|
/// hard error in the future.
|
||||||
|
///
|
||||||
|
/// [future-incompatible]: ../index.md#future-incompatible-lints
|
||||||
|
pub AMBIGUOUS_GLOB_IMPORTED_TRAITS,
|
||||||
|
Warn,
|
||||||
|
"detects uses of ambiguously glob imported traits",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reason: fcw!(FutureReleaseError #147992),
|
||||||
|
report_in_deps: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// The `ambiguous_panic_imports` lint detects ambiguous core and std panic imports, but
|
/// The `ambiguous_panic_imports` lint detects ambiguous core and std panic imports, but
|
||||||
/// previously didn't do that due to `#[macro_use]` prelude macro import.
|
/// previously didn't do that due to `#[macro_use]` prelude macro import.
|
||||||
|
|
|
||||||
|
|
@ -378,9 +378,6 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
|
||||||
return_result_from_ensure_ok,
|
return_result_from_ensure_ok,
|
||||||
);
|
);
|
||||||
|
|
||||||
if modifiers.cache.is_some() {
|
|
||||||
attributes.push(quote! { (cache) });
|
|
||||||
}
|
|
||||||
// Pass on the cache modifier
|
// Pass on the cache modifier
|
||||||
if modifiers.cache.is_some() {
|
if modifiers.cache.is_some() {
|
||||||
attributes.push(quote! { (cache) });
|
attributes.push(quote! { (cache) });
|
||||||
|
|
|
||||||
|
|
@ -622,7 +622,18 @@ struct ModuleData<'ra> {
|
||||||
globs: CmRefCell<Vec<Import<'ra>>>,
|
globs: CmRefCell<Vec<Import<'ra>>>,
|
||||||
|
|
||||||
/// Used to memoize the traits in this module for faster searches through all traits in scope.
|
/// Used to memoize the traits in this module for faster searches through all traits in scope.
|
||||||
traits: CmRefCell<Option<Box<[(Macros20NormalizedIdent, Decl<'ra>, Option<Module<'ra>>)]>>>,
|
traits: CmRefCell<
|
||||||
|
Option<
|
||||||
|
Box<
|
||||||
|
[(
|
||||||
|
Macros20NormalizedIdent,
|
||||||
|
Decl<'ra>,
|
||||||
|
Option<Module<'ra>>,
|
||||||
|
bool, /* lint ambiguous */
|
||||||
|
)],
|
||||||
|
>,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
|
|
||||||
/// Span of the module itself. Used for error reporting.
|
/// Span of the module itself. Used for error reporting.
|
||||||
span: Span,
|
span: Span,
|
||||||
|
|
@ -719,7 +730,12 @@ impl<'ra> Module<'ra> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) = binding.res() {
|
if let Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) = binding.res() {
|
||||||
collected_traits.push((name, binding, r.as_ref().get_module(def_id)))
|
collected_traits.push((
|
||||||
|
name,
|
||||||
|
binding,
|
||||||
|
r.as_ref().get_module(def_id),
|
||||||
|
binding.is_ambiguity_recursive(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
*traits = Some(collected_traits.into_boxed_slice());
|
*traits = Some(collected_traits.into_boxed_slice());
|
||||||
|
|
@ -1877,7 +1893,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||||
if let Some(module) = current_trait {
|
if let Some(module) = current_trait {
|
||||||
if self.trait_may_have_item(Some(module), assoc_item) {
|
if self.trait_may_have_item(Some(module), assoc_item) {
|
||||||
let def_id = module.def_id();
|
let def_id = module.def_id();
|
||||||
found_traits.push(TraitCandidate { def_id, import_ids: smallvec![] });
|
found_traits.push(TraitCandidate {
|
||||||
|
def_id,
|
||||||
|
import_ids: smallvec![],
|
||||||
|
lint_ambiguous: false,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1915,11 +1935,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||||
) {
|
) {
|
||||||
module.ensure_traits(self);
|
module.ensure_traits(self);
|
||||||
let traits = module.traits.borrow();
|
let traits = module.traits.borrow();
|
||||||
for &(trait_name, trait_binding, trait_module) in traits.as_ref().unwrap().iter() {
|
for &(trait_name, trait_binding, trait_module, lint_ambiguous) in
|
||||||
|
traits.as_ref().unwrap().iter()
|
||||||
|
{
|
||||||
if self.trait_may_have_item(trait_module, assoc_item) {
|
if self.trait_may_have_item(trait_module, assoc_item) {
|
||||||
let def_id = trait_binding.res().def_id();
|
let def_id = trait_binding.res().def_id();
|
||||||
let import_ids = self.find_transitive_imports(&trait_binding.kind, trait_name.0);
|
let import_ids = self.find_transitive_imports(&trait_binding.kind, trait_name.0);
|
||||||
found_traits.push(TraitCandidate { def_id, import_ids });
|
found_traits.push(TraitCandidate { def_id, import_ids, lint_ambiguous });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,9 @@ use rustc_hashes::Hash64;
|
||||||
use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic};
|
use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic};
|
||||||
use rustc_span::edition::{DEFAULT_EDITION, EDITION_NAME_LIST, Edition, LATEST_STABLE_EDITION};
|
use rustc_span::edition::{DEFAULT_EDITION, EDITION_NAME_LIST, Edition, LATEST_STABLE_EDITION};
|
||||||
use rustc_span::source_map::FilePathMapping;
|
use rustc_span::source_map::FilePathMapping;
|
||||||
use rustc_span::{FileName, RealFileName, SourceFileHashAlgorithm, Symbol, sym};
|
use rustc_span::{
|
||||||
|
FileName, RealFileName, RemapPathScopeComponents, SourceFileHashAlgorithm, Symbol, sym,
|
||||||
|
};
|
||||||
use rustc_target::spec::{
|
use rustc_target::spec::{
|
||||||
FramePointer, LinkSelfContainedComponents, LinkerFeatures, PanicStrategy, SplitDebuginfo,
|
FramePointer, LinkSelfContainedComponents, LinkerFeatures, PanicStrategy, SplitDebuginfo,
|
||||||
Target, TargetTuple,
|
Target, TargetTuple,
|
||||||
|
|
@ -1317,6 +1319,29 @@ impl OutputFilenames {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn parse_remap_path_scope(
|
||||||
|
early_dcx: &EarlyDiagCtxt,
|
||||||
|
matches: &getopts::Matches,
|
||||||
|
) -> RemapPathScopeComponents {
|
||||||
|
if let Some(v) = matches.opt_str("remap-path-scope") {
|
||||||
|
let mut slot = RemapPathScopeComponents::empty();
|
||||||
|
for s in v.split(',') {
|
||||||
|
slot |= match s {
|
||||||
|
"macro" => RemapPathScopeComponents::MACRO,
|
||||||
|
"diagnostics" => RemapPathScopeComponents::DIAGNOSTICS,
|
||||||
|
"debuginfo" => RemapPathScopeComponents::DEBUGINFO,
|
||||||
|
"coverage" => RemapPathScopeComponents::COVERAGE,
|
||||||
|
"object" => RemapPathScopeComponents::OBJECT,
|
||||||
|
"all" => RemapPathScopeComponents::all(),
|
||||||
|
_ => early_dcx.early_fatal("argument for `--remap-path-scope` must be a comma separated list of scopes: `macro`, `diagnostics`, `debuginfo`, `coverage`, `object`, `all`"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
slot
|
||||||
|
} else {
|
||||||
|
RemapPathScopeComponents::all()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Sysroot {
|
pub struct Sysroot {
|
||||||
pub explicit: Option<PathBuf>,
|
pub explicit: Option<PathBuf>,
|
||||||
|
|
@ -1353,9 +1378,9 @@ pub fn host_tuple() -> &'static str {
|
||||||
|
|
||||||
fn file_path_mapping(
|
fn file_path_mapping(
|
||||||
remap_path_prefix: Vec<(PathBuf, PathBuf)>,
|
remap_path_prefix: Vec<(PathBuf, PathBuf)>,
|
||||||
unstable_opts: &UnstableOptions,
|
remap_path_scope: RemapPathScopeComponents,
|
||||||
) -> FilePathMapping {
|
) -> FilePathMapping {
|
||||||
FilePathMapping::new(remap_path_prefix.clone(), unstable_opts.remap_path_scope)
|
FilePathMapping::new(remap_path_prefix.clone(), remap_path_scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Options {
|
impl Default for Options {
|
||||||
|
|
@ -1367,7 +1392,7 @@ impl Default for Options {
|
||||||
// to create a default working directory.
|
// to create a default working directory.
|
||||||
let working_dir = {
|
let working_dir = {
|
||||||
let working_dir = std::env::current_dir().unwrap();
|
let working_dir = std::env::current_dir().unwrap();
|
||||||
let file_mapping = file_path_mapping(Vec::new(), &unstable_opts);
|
let file_mapping = file_path_mapping(Vec::new(), RemapPathScopeComponents::empty());
|
||||||
file_mapping.to_real_filename(&RealFileName::empty(), &working_dir)
|
file_mapping.to_real_filename(&RealFileName::empty(), &working_dir)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1402,6 +1427,7 @@ impl Default for Options {
|
||||||
cli_forced_codegen_units: None,
|
cli_forced_codegen_units: None,
|
||||||
cli_forced_local_thinlto_off: false,
|
cli_forced_local_thinlto_off: false,
|
||||||
remap_path_prefix: Vec::new(),
|
remap_path_prefix: Vec::new(),
|
||||||
|
remap_path_scope: RemapPathScopeComponents::all(),
|
||||||
real_rust_source_base_dir: None,
|
real_rust_source_base_dir: None,
|
||||||
real_rustc_dev_source_base_dir: None,
|
real_rustc_dev_source_base_dir: None,
|
||||||
edition: DEFAULT_EDITION,
|
edition: DEFAULT_EDITION,
|
||||||
|
|
@ -1428,7 +1454,7 @@ impl Options {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn file_path_mapping(&self) -> FilePathMapping {
|
pub fn file_path_mapping(&self) -> FilePathMapping {
|
||||||
file_path_mapping(self.remap_path_prefix.clone(), &self.unstable_opts)
|
file_path_mapping(self.remap_path_prefix.clone(), self.remap_path_scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if there will be an output file generated.
|
/// Returns `true` if there will be an output file generated.
|
||||||
|
|
@ -1866,6 +1892,14 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
|
||||||
"Remap source names in all output (compiler messages and output files)",
|
"Remap source names in all output (compiler messages and output files)",
|
||||||
"<FROM>=<TO>",
|
"<FROM>=<TO>",
|
||||||
),
|
),
|
||||||
|
opt(
|
||||||
|
Stable,
|
||||||
|
Opt,
|
||||||
|
"",
|
||||||
|
"remap-path-scope",
|
||||||
|
"Defines which scopes of paths should be remapped by `--remap-path-prefix`",
|
||||||
|
"<macro,diagnostics,debuginfo,coverage,object,all>",
|
||||||
|
),
|
||||||
opt(Unstable, Multi, "", "env-set", "Inject an environment variable", "<VAR>=<VALUE>"),
|
opt(Unstable, Multi, "", "env-set", "Inject an environment variable", "<VAR>=<VALUE>"),
|
||||||
];
|
];
|
||||||
options.extend(verbose_only.into_iter().map(|mut opt| {
|
options.extend(verbose_only.into_iter().map(|mut opt| {
|
||||||
|
|
@ -2669,6 +2703,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
|
||||||
let externs = parse_externs(early_dcx, matches, &unstable_opts);
|
let externs = parse_externs(early_dcx, matches, &unstable_opts);
|
||||||
|
|
||||||
let remap_path_prefix = parse_remap_path_prefix(early_dcx, matches, &unstable_opts);
|
let remap_path_prefix = parse_remap_path_prefix(early_dcx, matches, &unstable_opts);
|
||||||
|
let remap_path_scope = parse_remap_path_scope(early_dcx, matches);
|
||||||
|
|
||||||
let pretty = parse_pretty(early_dcx, &unstable_opts);
|
let pretty = parse_pretty(early_dcx, &unstable_opts);
|
||||||
|
|
||||||
|
|
@ -2735,7 +2770,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
|
||||||
early_dcx.early_fatal(format!("Current directory is invalid: {e}"));
|
early_dcx.early_fatal(format!("Current directory is invalid: {e}"));
|
||||||
});
|
});
|
||||||
|
|
||||||
let file_mapping = file_path_mapping(remap_path_prefix.clone(), &unstable_opts);
|
let file_mapping = file_path_mapping(remap_path_prefix.clone(), remap_path_scope);
|
||||||
file_mapping.to_real_filename(&RealFileName::empty(), &working_dir)
|
file_mapping.to_real_filename(&RealFileName::empty(), &working_dir)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -2772,6 +2807,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
|
||||||
cli_forced_codegen_units: codegen_units,
|
cli_forced_codegen_units: codegen_units,
|
||||||
cli_forced_local_thinlto_off: disable_local_thinlto,
|
cli_forced_local_thinlto_off: disable_local_thinlto,
|
||||||
remap_path_prefix,
|
remap_path_prefix,
|
||||||
|
remap_path_scope,
|
||||||
real_rust_source_base_dir,
|
real_rust_source_base_dir,
|
||||||
real_rustc_dev_source_base_dir,
|
real_rustc_dev_source_base_dir,
|
||||||
edition,
|
edition,
|
||||||
|
|
|
||||||
|
|
@ -454,6 +454,8 @@ top_level_options!(
|
||||||
|
|
||||||
/// Remap source path prefixes in all output (messages, object files, debug, etc.).
|
/// Remap source path prefixes in all output (messages, object files, debug, etc.).
|
||||||
remap_path_prefix: Vec<(PathBuf, PathBuf)> [TRACKED_NO_CRATE_HASH],
|
remap_path_prefix: Vec<(PathBuf, PathBuf)> [TRACKED_NO_CRATE_HASH],
|
||||||
|
/// Defines which scopes of paths should be remapped by `--remap-path-prefix`.
|
||||||
|
remap_path_scope: RemapPathScopeComponents [TRACKED_NO_CRATE_HASH],
|
||||||
|
|
||||||
/// Base directory containing the `library/` directory for the Rust standard library.
|
/// Base directory containing the `library/` directory for the Rust standard library.
|
||||||
/// Right now it's always `$sysroot/lib/rustlib/src/rust`
|
/// Right now it's always `$sysroot/lib/rustlib/src/rust`
|
||||||
|
|
@ -872,7 +874,6 @@ mod desc {
|
||||||
pub(crate) const parse_branch_protection: &str = "a `,` separated combination of `bti`, `gcs`, `pac-ret`, (optionally with `pc`, `b-key`, `leaf` if `pac-ret` is set)";
|
pub(crate) const parse_branch_protection: &str = "a `,` separated combination of `bti`, `gcs`, `pac-ret`, (optionally with `pc`, `b-key`, `leaf` if `pac-ret` is set)";
|
||||||
pub(crate) const parse_proc_macro_execution_strategy: &str =
|
pub(crate) const parse_proc_macro_execution_strategy: &str =
|
||||||
"one of supported execution strategies (`same-thread`, or `cross-thread`)";
|
"one of supported execution strategies (`same-thread`, or `cross-thread`)";
|
||||||
pub(crate) const parse_remap_path_scope: &str = "comma separated list of scopes: `macro`, `diagnostics`, `debuginfo`, `coverage`, `object`, `all`";
|
|
||||||
pub(crate) const parse_inlining_threshold: &str =
|
pub(crate) const parse_inlining_threshold: &str =
|
||||||
"either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number";
|
"either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number";
|
||||||
pub(crate) const parse_llvm_module_flag: &str = "<key>:<type>:<value>:<behavior>. Type must currently be `u32`. Behavior should be one of (`error`, `warning`, `require`, `override`, `append`, `appendunique`, `max`, `min`)";
|
pub(crate) const parse_llvm_module_flag: &str = "<key>:<type>:<value>:<behavior>. Type must currently be `u32`. Behavior should be one of (`error`, `warning`, `require`, `override`, `append`, `appendunique`, `max`, `min`)";
|
||||||
|
|
@ -1737,29 +1738,6 @@ pub mod parse {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn parse_remap_path_scope(
|
|
||||||
slot: &mut RemapPathScopeComponents,
|
|
||||||
v: Option<&str>,
|
|
||||||
) -> bool {
|
|
||||||
if let Some(v) = v {
|
|
||||||
*slot = RemapPathScopeComponents::empty();
|
|
||||||
for s in v.split(',') {
|
|
||||||
*slot |= match s {
|
|
||||||
"macro" => RemapPathScopeComponents::MACRO,
|
|
||||||
"diagnostics" => RemapPathScopeComponents::DIAGNOSTICS,
|
|
||||||
"debuginfo" => RemapPathScopeComponents::DEBUGINFO,
|
|
||||||
"coverage" => RemapPathScopeComponents::COVERAGE,
|
|
||||||
"object" => RemapPathScopeComponents::OBJECT,
|
|
||||||
"all" => RemapPathScopeComponents::all(),
|
|
||||||
_ => return false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn parse_relocation_model(slot: &mut Option<RelocModel>, v: Option<&str>) -> bool {
|
pub(crate) fn parse_relocation_model(slot: &mut Option<RelocModel>, v: Option<&str>) -> bool {
|
||||||
match v.and_then(|s| RelocModel::from_str(s).ok()) {
|
match v.and_then(|s| RelocModel::from_str(s).ok()) {
|
||||||
Some(relocation_model) => *slot = Some(relocation_model),
|
Some(relocation_model) => *slot = Some(relocation_model),
|
||||||
|
|
@ -2614,8 +2592,6 @@ options! {
|
||||||
"whether ELF relocations can be relaxed"),
|
"whether ELF relocations can be relaxed"),
|
||||||
remap_cwd_prefix: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
|
remap_cwd_prefix: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
|
||||||
"remap paths under the current working directory to this path prefix"),
|
"remap paths under the current working directory to this path prefix"),
|
||||||
remap_path_scope: RemapPathScopeComponents = (RemapPathScopeComponents::all(), parse_remap_path_scope, [TRACKED],
|
|
||||||
"remap path scope (default: all)"),
|
|
||||||
remark_dir: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
|
remark_dir: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
|
||||||
"directory into which to write optimization remarks (if not specified, they will be \
|
"directory into which to write optimization remarks (if not specified, they will be \
|
||||||
written to standard error output)"),
|
written to standard error output)"),
|
||||||
|
|
|
||||||
|
|
@ -1801,6 +1801,8 @@ supported_targets! {
|
||||||
("x86_64-lynx-lynxos178", x86_64_lynx_lynxos178),
|
("x86_64-lynx-lynxos178", x86_64_lynx_lynxos178),
|
||||||
|
|
||||||
("x86_64-pc-cygwin", x86_64_pc_cygwin),
|
("x86_64-pc-cygwin", x86_64_pc_cygwin),
|
||||||
|
|
||||||
|
("x86_64-unknown-linux-gnuasan", x86_64_unknown_linux_gnuasan),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cow-Vec-Str: Cow<'static, [Cow<'static, str>]>
|
/// Cow-Vec-Str: Cow<'static, [Cow<'static, str>]>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ pub(crate) fn target() -> Target {
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "i586-unknown-redox".into(),
|
llvm_target: "i586-unknown-redox".into(),
|
||||||
metadata: TargetMetadata { description: None, tier: None, host_tools: None, std: None },
|
metadata: TargetMetadata { description: None, tier: Some(3), host_tools: None, std: None },
|
||||||
pointer_width: 32,
|
pointer_width: 32,
|
||||||
data_layout:
|
data_layout:
|
||||||
"e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128"
|
"e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
use crate::spec::{SanitizerSet, Target, TargetMetadata};
|
||||||
|
|
||||||
|
pub(crate) fn target() -> Target {
|
||||||
|
let mut base = super::x86_64_unknown_linux_gnu::target();
|
||||||
|
base.metadata = TargetMetadata {
|
||||||
|
description: Some(
|
||||||
|
"64-bit Linux (kernel 3.2+, glibc 2.17+) with ASAN enabled by default".into(),
|
||||||
|
),
|
||||||
|
tier: Some(2),
|
||||||
|
host_tools: Some(false),
|
||||||
|
std: Some(true),
|
||||||
|
};
|
||||||
|
base.supported_sanitizers = SanitizerSet::ADDRESS;
|
||||||
|
base.default_sanitizers = SanitizerSet::ADDRESS;
|
||||||
|
base
|
||||||
|
}
|
||||||
|
|
@ -15,7 +15,7 @@ pub(crate) fn target() -> Target {
|
||||||
llvm_target: "x86_64-unknown-linux-none".into(),
|
llvm_target: "x86_64-unknown-linux-none".into(),
|
||||||
metadata: TargetMetadata {
|
metadata: TargetMetadata {
|
||||||
description: None,
|
description: None,
|
||||||
tier: None,
|
tier: Some(3),
|
||||||
host_tools: None,
|
host_tools: None,
|
||||||
std: Some(false),
|
std: Some(false),
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ pub(crate) fn target() -> Target {
|
||||||
pointer_width: 32,
|
pointer_width: 32,
|
||||||
data_layout: "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32".into(),
|
data_layout: "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32".into(),
|
||||||
arch: Arch::Xtensa,
|
arch: Arch::Xtensa,
|
||||||
metadata: TargetMetadata { description: None, tier: None, host_tools: None, std: None },
|
metadata: TargetMetadata { description: None, tier: Some(3), host_tools: None, std: None },
|
||||||
|
|
||||||
options: TargetOptions {
|
options: TargetOptions {
|
||||||
endian: Endian::Little,
|
endian: Endian::Little,
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ pub(crate) fn target() -> Target {
|
||||||
pointer_width: 32,
|
pointer_width: 32,
|
||||||
data_layout: "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32".into(),
|
data_layout: "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32".into(),
|
||||||
arch: Arch::Xtensa,
|
arch: Arch::Xtensa,
|
||||||
metadata: TargetMetadata { description: None, tier: None, host_tools: None, std: None },
|
metadata: TargetMetadata { description: None, tier: Some(3), host_tools: None, std: None },
|
||||||
|
|
||||||
options: TargetOptions {
|
options: TargetOptions {
|
||||||
endian: Endian::Little,
|
endian: Endian::Little,
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ pub(crate) fn target() -> Target {
|
||||||
pointer_width: 32,
|
pointer_width: 32,
|
||||||
data_layout: "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32".into(),
|
data_layout: "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32".into(),
|
||||||
arch: Arch::Xtensa,
|
arch: Arch::Xtensa,
|
||||||
metadata: TargetMetadata { description: None, tier: None, host_tools: None, std: None },
|
metadata: TargetMetadata { description: None, tier: Some(3), host_tools: None, std: None },
|
||||||
|
|
||||||
options: TargetOptions {
|
options: TargetOptions {
|
||||||
endian: Endian::Little,
|
endian: Endian::Little,
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,11 @@ check-aux:
|
||||||
src/tools/cargotest \
|
src/tools/cargotest \
|
||||||
src/tools/test-float-parse \
|
src/tools/test-float-parse \
|
||||||
$(BOOTSTRAP_ARGS)
|
$(BOOTSTRAP_ARGS)
|
||||||
|
# The build-std suite is off by default because it is uncommonly slow
|
||||||
|
# and memory-hungry.
|
||||||
|
$(Q)$(BOOTSTRAP) test --stage 2 \
|
||||||
|
build-std \
|
||||||
|
$(BOOTSTRAP_ARGS)
|
||||||
# Run standard library tests in Miri.
|
# Run standard library tests in Miri.
|
||||||
$(Q)MIRIFLAGS="-Zmiri-strict-provenance" \
|
$(Q)MIRIFLAGS="-Zmiri-strict-provenance" \
|
||||||
$(BOOTSTRAP) miri --stage 2 \
|
$(BOOTSTRAP) miri --stage 2 \
|
||||||
|
|
|
||||||
|
|
@ -1515,6 +1515,7 @@ fn supported_sanitizers(
|
||||||
"x86_64",
|
"x86_64",
|
||||||
&["asan", "dfsan", "lsan", "msan", "safestack", "tsan", "rtsan"],
|
&["asan", "dfsan", "lsan", "msan", "safestack", "tsan", "rtsan"],
|
||||||
),
|
),
|
||||||
|
"x86_64-unknown-linux-gnuasan" => common_libs("linux", "x86_64", &["asan"]),
|
||||||
"x86_64-unknown-linux-musl" => {
|
"x86_64-unknown-linux-musl" => {
|
||||||
common_libs("linux", "x86_64", &["asan", "lsan", "msan", "tsan"])
|
common_libs("linux", "x86_64", &["asan", "lsan", "msan", "tsan"])
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1625,6 +1625,12 @@ test!(RunMakeCargo {
|
||||||
suite: "run-make-cargo",
|
suite: "run-make-cargo",
|
||||||
default: true
|
default: true
|
||||||
});
|
});
|
||||||
|
test!(BuildStd {
|
||||||
|
path: "tests/build-std",
|
||||||
|
mode: CompiletestMode::RunMake,
|
||||||
|
suite: "build-std",
|
||||||
|
default: false
|
||||||
|
});
|
||||||
|
|
||||||
test!(AssemblyLlvm {
|
test!(AssemblyLlvm {
|
||||||
path: "tests/assembly-llvm",
|
path: "tests/assembly-llvm",
|
||||||
|
|
@ -1948,7 +1954,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
|
||||||
let stage0_rustc_path = builder.compiler(0, test_compiler.host);
|
let stage0_rustc_path = builder.compiler(0, test_compiler.host);
|
||||||
cmd.arg("--stage0-rustc-path").arg(builder.rustc(stage0_rustc_path));
|
cmd.arg("--stage0-rustc-path").arg(builder.rustc(stage0_rustc_path));
|
||||||
|
|
||||||
if suite == "run-make-cargo" {
|
if matches!(suite, "run-make-cargo" | "build-std") {
|
||||||
let cargo_path = if test_compiler.stage == 0 {
|
let cargo_path = if test_compiler.stage == 0 {
|
||||||
// If we're using `--stage 0`, we should provide the bootstrap cargo.
|
// If we're using `--stage 0`, we should provide the bootstrap cargo.
|
||||||
builder.initial_cargo.clone()
|
builder.initial_cargo.clone()
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ pub(crate) const PATH_REMAP: &[(&str, &[&str])] = &[
|
||||||
&[
|
&[
|
||||||
// tidy-alphabetical-start
|
// tidy-alphabetical-start
|
||||||
"tests/assembly-llvm",
|
"tests/assembly-llvm",
|
||||||
|
"tests/build-std",
|
||||||
"tests/codegen-llvm",
|
"tests/codegen-llvm",
|
||||||
"tests/codegen-units",
|
"tests/codegen-units",
|
||||||
"tests/coverage",
|
"tests/coverage",
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,9 @@ expression: test tests
|
||||||
[Test] test::AssemblyLlvm
|
[Test] test::AssemblyLlvm
|
||||||
targets: [aarch64-unknown-linux-gnu]
|
targets: [aarch64-unknown-linux-gnu]
|
||||||
- Suite(test::tests/assembly-llvm)
|
- Suite(test::tests/assembly-llvm)
|
||||||
|
[Test] test::BuildStd
|
||||||
|
targets: [aarch64-unknown-linux-gnu]
|
||||||
|
- Suite(test::tests/build-std)
|
||||||
[Test] test::CodegenLlvm
|
[Test] test::CodegenLlvm
|
||||||
targets: [aarch64-unknown-linux-gnu]
|
targets: [aarch64-unknown-linux-gnu]
|
||||||
- Suite(test::tests/codegen-llvm)
|
- Suite(test::tests/codegen-llvm)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,9 @@ expression: test tests --skip=coverage
|
||||||
[Test] test::AssemblyLlvm
|
[Test] test::AssemblyLlvm
|
||||||
targets: [aarch64-unknown-linux-gnu]
|
targets: [aarch64-unknown-linux-gnu]
|
||||||
- Suite(test::tests/assembly-llvm)
|
- Suite(test::tests/assembly-llvm)
|
||||||
|
[Test] test::BuildStd
|
||||||
|
targets: [aarch64-unknown-linux-gnu]
|
||||||
|
- Suite(test::tests/build-std)
|
||||||
[Test] test::CodegenLlvm
|
[Test] test::CodegenLlvm
|
||||||
targets: [aarch64-unknown-linux-gnu]
|
targets: [aarch64-unknown-linux-gnu]
|
||||||
- Suite(test::tests/codegen-llvm)
|
- Suite(test::tests/codegen-llvm)
|
||||||
|
|
|
||||||
|
|
@ -927,6 +927,7 @@ impl<'a> Builder<'a> {
|
||||||
test::CollectLicenseMetadata,
|
test::CollectLicenseMetadata,
|
||||||
test::RunMake,
|
test::RunMake,
|
||||||
test::RunMakeCargo,
|
test::RunMakeCargo,
|
||||||
|
test::BuildStd,
|
||||||
),
|
),
|
||||||
Kind::Miri => describe!(test::Crate),
|
Kind::Miri => describe!(test::Crate),
|
||||||
Kind::Bench => describe!(test::Crate, test::CrateLibrustc, test::CrateRustdoc),
|
Kind::Bench => describe!(test::Crate, test::CrateLibrustc, test::CrateRustdoc),
|
||||||
|
|
|
||||||
|
|
@ -2077,7 +2077,7 @@ mod snapshot {
|
||||||
let ctx = TestCtx::new();
|
let ctx = TestCtx::new();
|
||||||
insta::assert_snapshot!(
|
insta::assert_snapshot!(
|
||||||
prepare_test_config(&ctx)
|
prepare_test_config(&ctx)
|
||||||
.render_steps(), @r"
|
.render_steps(), @"
|
||||||
[build] rustc 0 <host> -> Tidy 1 <host>
|
[build] rustc 0 <host> -> Tidy 1 <host>
|
||||||
[test] tidy <>
|
[test] tidy <>
|
||||||
[build] rustdoc 0 <host>
|
[build] rustdoc 0 <host>
|
||||||
|
|
@ -2255,7 +2255,7 @@ mod snapshot {
|
||||||
insta::assert_snapshot!(
|
insta::assert_snapshot!(
|
||||||
prepare_test_config(&ctx)
|
prepare_test_config(&ctx)
|
||||||
.stage(2)
|
.stage(2)
|
||||||
.render_steps(), @r"
|
.render_steps(), @"
|
||||||
[build] rustc 0 <host> -> Tidy 1 <host>
|
[build] rustc 0 <host> -> Tidy 1 <host>
|
||||||
[test] tidy <>
|
[test] tidy <>
|
||||||
[build] rustdoc 0 <host>
|
[build] rustdoc 0 <host>
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ pub struct Finder {
|
||||||
const STAGE0_MISSING_TARGETS: &[&str] = &[
|
const STAGE0_MISSING_TARGETS: &[&str] = &[
|
||||||
// just a dummy comment so the list doesn't get onelined
|
// just a dummy comment so the list doesn't get onelined
|
||||||
"riscv64im-unknown-none-elf",
|
"riscv64im-unknown-none-elf",
|
||||||
|
"x86_64-unknown-linux-gnuasan",
|
||||||
];
|
];
|
||||||
|
|
||||||
/// Minimum version threshold for libstdc++ required when using prebuilt LLVM
|
/// Minimum version threshold for libstdc++ required when using prebuilt LLVM
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,10 @@ The following test suites are available, with links for more information:
|
||||||
|
|
||||||
[`run-make`](#run-make-tests) are general purpose tests using Rust programs.
|
[`run-make`](#run-make-tests) are general purpose tests using Rust programs.
|
||||||
|
|
||||||
|
### The build-std test suite
|
||||||
|
|
||||||
|
[`build-std`](#build-std-tests) test that -Zbuild-std works.
|
||||||
|
|
||||||
### Rustdoc test suites
|
### Rustdoc test suites
|
||||||
|
|
||||||
| Test suite | Purpose |
|
| Test suite | Purpose |
|
||||||
|
|
@ -429,6 +433,12 @@ use cases that require testing in-tree `cargo` in conjunction with in-tree `rust
|
||||||
The `run-make` test suite does not have access to in-tree `cargo` (so it can be the
|
The `run-make` test suite does not have access to in-tree `cargo` (so it can be the
|
||||||
faster-to-iterate test suite).
|
faster-to-iterate test suite).
|
||||||
|
|
||||||
|
### `build-std` tests
|
||||||
|
|
||||||
|
The tests in [`tests/build-std`] check that `-Zbuild-std` works. This is currently
|
||||||
|
just a run-make test suite with a single recipe. The recipe generates test cases
|
||||||
|
and runs them in parallel.
|
||||||
|
|
||||||
#### Using Rust recipes
|
#### Using Rust recipes
|
||||||
|
|
||||||
Each test should be in a separate directory with a `rmake.rs` Rust program,
|
Each test should be in a separate directory with a `rmake.rs` Rust program,
|
||||||
|
|
|
||||||
|
|
@ -151,5 +151,6 @@
|
||||||
- [x86_64-pc-cygwin](platform-support/x86_64-pc-cygwin.md)
|
- [x86_64-pc-cygwin](platform-support/x86_64-pc-cygwin.md)
|
||||||
- [x86_64-unknown-linux-none](platform-support/x86_64-unknown-linux-none.md)
|
- [x86_64-unknown-linux-none](platform-support/x86_64-unknown-linux-none.md)
|
||||||
- [x86_64-unknown-none](platform-support/x86_64-unknown-none.md)
|
- [x86_64-unknown-none](platform-support/x86_64-unknown-none.md)
|
||||||
|
- [x86_64-unknown-linux-gnuasan](platform-support/x86_64-unknown-linux-gnuasan.md)
|
||||||
- [xtensa-\*-none-elf](platform-support/xtensa.md)
|
- [xtensa-\*-none-elf](platform-support/xtensa.md)
|
||||||
- [\*-nuttx-\*](platform-support/nuttx.md)
|
- [\*-nuttx-\*](platform-support/nuttx.md)
|
||||||
|
|
|
||||||
|
|
@ -428,6 +428,14 @@ specified multiple times.
|
||||||
Refer to the [Remap source paths](remap-source-paths.md) section of this book for
|
Refer to the [Remap source paths](remap-source-paths.md) section of this book for
|
||||||
further details and explanation.
|
further details and explanation.
|
||||||
|
|
||||||
|
<a id="option-remap-path-scope"></a>
|
||||||
|
## `--remap-path-scope`: remap source paths in output
|
||||||
|
|
||||||
|
Defines which scopes of paths should be remapped by `--remap-path-prefix`.
|
||||||
|
|
||||||
|
Refer to the [Remap source paths](remap-source-paths.md) section of this book for
|
||||||
|
further details and explanation.
|
||||||
|
|
||||||
<a id="option-json"></a>
|
<a id="option-json"></a>
|
||||||
## `--json`: configure json messages printed by the compiler
|
## `--json`: configure json messages printed by the compiler
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,7 @@ target | std | notes
|
||||||
[`x86_64-apple-ios-macabi`](platform-support/apple-ios-macabi.md) | ✓ | Mac Catalyst on x86_64
|
[`x86_64-apple-ios-macabi`](platform-support/apple-ios-macabi.md) | ✓ | Mac Catalyst on x86_64
|
||||||
[`x86_64-fortanix-unknown-sgx`](platform-support/x86_64-fortanix-unknown-sgx.md) | ✓ | [Fortanix ABI] for 64-bit Intel SGX
|
[`x86_64-fortanix-unknown-sgx`](platform-support/x86_64-fortanix-unknown-sgx.md) | ✓ | [Fortanix ABI] for 64-bit Intel SGX
|
||||||
[`x86_64-linux-android`](platform-support/android.md) | ✓ | 64-bit x86 Android
|
[`x86_64-linux-android`](platform-support/android.md) | ✓ | 64-bit x86 Android
|
||||||
|
[`x86_64-unknown-linux-gnuasan`](platform-support/x86_64-unknown-linux-gnuasan.md) | ✓ | 64-bit Linux (kernel 3.2+, glibc 2.17+) with ASAN enabled by default
|
||||||
[`x86_64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | 64-bit x86 Fuchsia
|
[`x86_64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | 64-bit x86 Fuchsia
|
||||||
`x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15+, glibc 2.27)
|
`x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15+, glibc 2.27)
|
||||||
[`x86_64-unknown-none`](platform-support/x86_64-unknown-none.md) | * | Freestanding/bare-metal x86_64, softfloat
|
[`x86_64-unknown-none`](platform-support/x86_64-unknown-none.md) | * | Freestanding/bare-metal x86_64, softfloat
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
# `x86_64-unknown-linux-gnuasan`
|
||||||
|
|
||||||
|
**Tier: 2**
|
||||||
|
|
||||||
|
Target mirroring `x86_64-unknown-linux-gnu` with AddressSanitizer enabled by
|
||||||
|
default.
|
||||||
|
The goal of this target is to allow shipping ASAN-instrumented standard
|
||||||
|
libraries through rustup, enabling a fully instrumented binary without requiring
|
||||||
|
nightly features (build-std).
|
||||||
|
Once build-std stabilizes, this target is no longer needed and will be removed.
|
||||||
|
|
||||||
|
## Target maintainers
|
||||||
|
|
||||||
|
- [@jakos-sec](https://github.com/jakos-sec)
|
||||||
|
- [@1c3t3a](https://github.com/1c3t3a)
|
||||||
|
- [@rust-lang/project-exploit-mitigations][project-exploit-mitigations]
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
The target is for cross-compilation only. Host tools are not supported, since
|
||||||
|
there is no need to have the host tools instrumented with ASAN. std is fully
|
||||||
|
supported.
|
||||||
|
|
||||||
|
In all other aspects the target is equivalent to `x86_64-unknown-linux-gnu`.
|
||||||
|
|
||||||
|
## Building the target
|
||||||
|
|
||||||
|
The target can be built by enabling it for a rustc build:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[build]
|
||||||
|
target = ["x86_64-unknown-linux-gnuasan"]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building Rust programs
|
||||||
|
|
||||||
|
Rust programs can be compiled by adding this target via rustup:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ rustup target add x86_64-unknown-linux-gnuasan
|
||||||
|
```
|
||||||
|
|
||||||
|
and then compiling with the target:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ rustc foo.rs --target x86_64-unknown-linux-gnuasan
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
Created binaries will run on Linux without any external requirements.
|
||||||
|
|
||||||
|
## Cross-compilation toolchains and C code
|
||||||
|
|
||||||
|
The target supports C code and should use the same toolchain target as
|
||||||
|
`x86_64-unknown-linux-gnu`.
|
||||||
|
|
@ -6,7 +6,7 @@ output, including compiler diagnostics, debugging information, macro expansions,
|
||||||
This is useful for normalizing build products, for example, by removing the current directory
|
This is useful for normalizing build products, for example, by removing the current directory
|
||||||
out of the paths emitted into object files.
|
out of the paths emitted into object files.
|
||||||
|
|
||||||
The remapping is done via the `--remap-path-prefix` option.
|
The remapping is done via the `--remap-path-prefix` flag and can be customized via the `--remap-path-scope` flag.
|
||||||
|
|
||||||
## `--remap-path-prefix`
|
## `--remap-path-prefix`
|
||||||
|
|
||||||
|
|
@ -39,6 +39,31 @@ rustc --remap-path-prefix "/home/user/project=/redacted"
|
||||||
|
|
||||||
This example replaces all occurrences of `/home/user/project` in emitted paths with `/redacted`.
|
This example replaces all occurrences of `/home/user/project` in emitted paths with `/redacted`.
|
||||||
|
|
||||||
|
## `--remap-path-scope`
|
||||||
|
|
||||||
|
Defines which scopes of paths should be remapped by `--remap-path-prefix`.
|
||||||
|
|
||||||
|
This flag accepts a comma-separated list of values and may be specified multiple times, in which case the scopes are aggregated together.
|
||||||
|
|
||||||
|
The valid scopes are:
|
||||||
|
|
||||||
|
- `macro` - apply remappings to the expansion of `std::file!()` macro. This is where paths in embedded panic messages come from
|
||||||
|
- `diagnostics` - apply remappings to printed compiler diagnostics
|
||||||
|
- `debuginfo` - apply remappings to debug information
|
||||||
|
- `coverage` - apply remappings to coverage information
|
||||||
|
- `object` - apply remappings to all paths in compiled executables or libraries, but not elsewhere. Currently an alias for `macro,coverage,debuginfo`.
|
||||||
|
- `all` (default) - an alias for all of the above, also equivalent to supplying only `--remap-path-prefix` without `--remap-path-scope`.
|
||||||
|
|
||||||
|
The scopes accepted by `--remap-path-scope` are not exhaustive - new scopes may be added in future releases for eventual stabilisation.
|
||||||
|
This implies that the `all` scope can correspond to different scopes between releases.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# With `object` scope only the build outputs will be remapped, the diagnostics won't be remapped.
|
||||||
|
rustc --remap-path-prefix=$(PWD)=/remapped --remap-path-scope=object main.rs
|
||||||
|
```
|
||||||
|
|
||||||
## Caveats and Limitations
|
## Caveats and Limitations
|
||||||
|
|
||||||
### Paths generated by linkers
|
### Paths generated by linkers
|
||||||
|
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
# `remap-path-scope`
|
|
||||||
|
|
||||||
The tracking issue for this feature is: [#111540](https://github.com/rust-lang/rust/issues/111540).
|
|
||||||
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
When the `--remap-path-prefix` option is passed to rustc, source path prefixes in all output will be affected by default.
|
|
||||||
The `--remap-path-scope` argument can be used in conjunction with `--remap-path-prefix` to determine paths in which output context should be affected.
|
|
||||||
This flag accepts a comma-separated list of values and may be specified multiple times, in which case the scopes are aggregated together. The valid scopes are:
|
|
||||||
|
|
||||||
- `macro` - apply remappings to the expansion of `std::file!()` macro. This is where paths in embedded panic messages come from
|
|
||||||
- `diagnostics` - apply remappings to printed compiler diagnostics
|
|
||||||
- `debuginfo` - apply remappings to debug information
|
|
||||||
- `coverage` - apply remappings to coverage information
|
|
||||||
- `object` - apply remappings to all paths in compiled executables or libraries, but not elsewhere. Currently an alias for `macro,debuginfo`.
|
|
||||||
- `all` - an alias for all of the above, also equivalent to supplying only `--remap-path-prefix` without `--remap-path-scope`.
|
|
||||||
|
|
||||||
## Example
|
|
||||||
```sh
|
|
||||||
# This would produce an absolute path to main.rs in build outputs of
|
|
||||||
# "./main.rs".
|
|
||||||
rustc --remap-path-prefix=$(PWD)=/remapped -Zremap-path-scope=object main.rs
|
|
||||||
```
|
|
||||||
|
|
@ -77,6 +77,7 @@ string_enum! {
|
||||||
RustdocUi => "rustdoc-ui",
|
RustdocUi => "rustdoc-ui",
|
||||||
Ui => "ui",
|
Ui => "ui",
|
||||||
UiFullDeps => "ui-fulldeps",
|
UiFullDeps => "ui-fulldeps",
|
||||||
|
BuildStd => "build-std",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -190,8 +190,8 @@ impl TestCx<'_> {
|
||||||
// through a specific CI runner).
|
// through a specific CI runner).
|
||||||
.env("LLVM_COMPONENTS", &self.config.llvm_components);
|
.env("LLVM_COMPONENTS", &self.config.llvm_components);
|
||||||
|
|
||||||
// Only `run-make-cargo` test suite gets an in-tree `cargo`, not `run-make`.
|
// The `run-make-cargo` and `build-std` suites need an in-tree `cargo`, `run-make` does not.
|
||||||
if self.config.suite == TestSuite::RunMakeCargo {
|
if matches!(self.config.suite, TestSuite::RunMakeCargo | TestSuite::BuildStd) {
|
||||||
cmd.env(
|
cmd.env(
|
||||||
"CARGO",
|
"CARGO",
|
||||||
self.config.cargo_path.as_ref().expect("cargo must be built and made available"),
|
self.config.cargo_path.as_ref().expect("cargo must be built and made available"),
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ impl Session {
|
||||||
.arg("-o")
|
.arg("-o")
|
||||||
.arg(&self.link_path)
|
.arg(&self.link_path)
|
||||||
.output()
|
.output()
|
||||||
.context("An error occured when calling llvm-link. Make sure the llvm-tools component is installed.")?;
|
.context("An error occurred when calling llvm-link. Make sure the llvm-tools component is installed.")?;
|
||||||
|
|
||||||
if !llvm_link_output.status.success() {
|
if !llvm_link_output.status.success() {
|
||||||
tracing::error!(
|
tracing::error!(
|
||||||
|
|
@ -115,7 +115,7 @@ impl Session {
|
||||||
}
|
}
|
||||||
|
|
||||||
let opt_output = opt_cmd.output().context(
|
let opt_output = opt_cmd.output().context(
|
||||||
"An error occured when calling opt. Make sure the llvm-tools component is installed.",
|
"An error occurred when calling opt. Make sure the llvm-tools component is installed.",
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if !opt_output.status.success() {
|
if !opt_output.status.success() {
|
||||||
|
|
@ -149,7 +149,7 @@ impl Session {
|
||||||
.arg(&self.opt_path)
|
.arg(&self.opt_path)
|
||||||
.arg("-o").arg(&self.out_path)
|
.arg("-o").arg(&self.out_path)
|
||||||
.output()
|
.output()
|
||||||
.context("An error occured when calling llc. Make sure the llvm-tools component is installed.")?;
|
.context("An error occurred when calling llc. Make sure the llvm-tools component is installed.")?;
|
||||||
|
|
||||||
if !lcc_output.status.success() {
|
if !lcc_output.status.success() {
|
||||||
tracing::error!(
|
tracing::error!(
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ struct MiriGenmcShim : private GenMCDriver {
|
||||||
void handle_execution_start();
|
void handle_execution_start();
|
||||||
// This function must be called at the end of any execution, even if an error was found
|
// This function must be called at the end of any execution, even if an error was found
|
||||||
// during the execution.
|
// during the execution.
|
||||||
// Returns `null`, or a string containing an error message if an error occured.
|
// Returns `null`, or a string containing an error message if an error occurred.
|
||||||
std::unique_ptr<std::string> handle_execution_end();
|
std::unique_ptr<std::string> handle_execution_end();
|
||||||
|
|
||||||
/***** Functions for handling events encountered during program execution. *****/
|
/***** Functions for handling events encountered during program execution. *****/
|
||||||
|
|
|
||||||
|
|
@ -379,7 +379,7 @@ mod ffi {
|
||||||
/// This function must be called at the start of any execution, before any events are reported to GenMC.
|
/// This function must be called at the start of any execution, before any events are reported to GenMC.
|
||||||
fn handle_execution_start(self: Pin<&mut MiriGenmcShim>);
|
fn handle_execution_start(self: Pin<&mut MiriGenmcShim>);
|
||||||
/// This function must be called at the end of any execution, even if an error was found during the execution.
|
/// This function must be called at the end of any execution, even if an error was found during the execution.
|
||||||
/// Returns `null`, or a string containing an error message if an error occured.
|
/// Returns `null`, or a string containing an error message if an error occurred.
|
||||||
fn handle_execution_end(self: Pin<&mut MiriGenmcShim>) -> UniquePtr<CxxString>;
|
fn handle_execution_end(self: Pin<&mut MiriGenmcShim>) -> UniquePtr<CxxString>;
|
||||||
|
|
||||||
/***** Functions for handling events encountered during program execution. *****/
|
/***** Functions for handling events encountered during program execution. *****/
|
||||||
|
|
|
||||||
|
|
@ -220,7 +220,7 @@ impl GenmcCtx {
|
||||||
/// Don't call this function if an error was found.
|
/// Don't call this function if an error was found.
|
||||||
///
|
///
|
||||||
/// GenMC detects certain errors only when the execution ends.
|
/// GenMC detects certain errors only when the execution ends.
|
||||||
/// If an error occured, a string containing a short error description is returned.
|
/// If an error occurred, a string containing a short error description is returned.
|
||||||
///
|
///
|
||||||
/// GenMC currently doesn't return an error in all cases immediately when one happens.
|
/// GenMC currently doesn't return an error in all cases immediately when one happens.
|
||||||
/// This function will also check for those, and return their error description.
|
/// This function will also check for those, and return their error description.
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ object = "0.37"
|
||||||
regex = "1.11"
|
regex = "1.11"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
similar = "2.7"
|
similar = "2.7"
|
||||||
|
tempfile = "3"
|
||||||
wasmparser = { version = "0.236", default-features = false, features = ["std", "features", "validate"] }
|
wasmparser = { version = "0.236", default-features = false, features = ["std", "features", "validate"] }
|
||||||
# tidy-alphabetical-end
|
# tidy-alphabetical-end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,8 @@ pub struct Command {
|
||||||
// Emulate linear type semantics.
|
// Emulate linear type semantics.
|
||||||
drop_bomb: DropBomb,
|
drop_bomb: DropBomb,
|
||||||
already_executed: bool,
|
already_executed: bool,
|
||||||
|
|
||||||
|
context: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Command {
|
impl Command {
|
||||||
|
|
@ -60,6 +62,7 @@ impl Command {
|
||||||
stdout: None,
|
stdout: None,
|
||||||
stderr: None,
|
stderr: None,
|
||||||
already_executed: false,
|
already_executed: false,
|
||||||
|
context: String::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,6 +72,16 @@ impl Command {
|
||||||
self.cmd
|
self.cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_context(&self) -> &str {
|
||||||
|
&self.context
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Appends context to the command, to provide a better error message if the command fails.
|
||||||
|
pub fn context(&mut self, ctx: &str) -> &mut Self {
|
||||||
|
self.context.push_str(&format!("{ctx}\n"));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Specify a stdin input buffer. This is a convenience helper,
|
/// Specify a stdin input buffer. This is a convenience helper,
|
||||||
pub fn stdin_buf<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
|
pub fn stdin_buf<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
|
||||||
self.stdin_buf = Some(input.as_ref().to_vec().into_boxed_slice());
|
self.stdin_buf = Some(input.as_ref().to_vec().into_boxed_slice());
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,9 @@ pub mod rfs {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-exports of third-party library crates.
|
// Re-exports of third-party library crates.
|
||||||
pub use {bstr, gimli, libc, object, regex, rustdoc_json_types, serde_json, similar, wasmparser};
|
pub use {
|
||||||
|
bstr, gimli, libc, object, regex, rustdoc_json_types, serde_json, similar, tempfile, wasmparser,
|
||||||
|
};
|
||||||
|
|
||||||
// Helpers for building names of output artifacts that are potentially target-specific.
|
// Helpers for building names of output artifacts that are potentially target-specific.
|
||||||
pub use crate::artifact_names::{
|
pub use crate::artifact_names::{
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,9 @@ pub(crate) fn handle_failed_output(
|
||||||
eprintln!("output status: `{}`", output.status());
|
eprintln!("output status: `{}`", output.status());
|
||||||
eprintln!("=== STDOUT ===\n{}\n\n", output.stdout_utf8());
|
eprintln!("=== STDOUT ===\n{}\n\n", output.stdout_utf8());
|
||||||
eprintln!("=== STDERR ===\n{}\n\n", output.stderr_utf8());
|
eprintln!("=== STDERR ===\n{}\n\n", output.stderr_utf8());
|
||||||
|
if !cmd.get_context().is_empty() {
|
||||||
|
eprintln!("Context:\n{}", cmd.get_context());
|
||||||
|
}
|
||||||
std::process::exit(1)
|
std::process::exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -213,7 +213,7 @@ impl RunningCheck {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Has an error already occured for this check?
|
/// Has an error already occurred for this check?
|
||||||
pub fn is_bad(&self) -> bool {
|
pub fn is_bad(&self) -> bool {
|
||||||
self.bad
|
self.bad
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -673,6 +673,9 @@
|
||||||
//@ revisions: x86_64_unknown_linux_gnux32
|
//@ revisions: x86_64_unknown_linux_gnux32
|
||||||
//@ [x86_64_unknown_linux_gnux32] compile-flags: --target x86_64-unknown-linux-gnux32
|
//@ [x86_64_unknown_linux_gnux32] compile-flags: --target x86_64-unknown-linux-gnux32
|
||||||
//@ [x86_64_unknown_linux_gnux32] needs-llvm-components: x86
|
//@ [x86_64_unknown_linux_gnux32] needs-llvm-components: x86
|
||||||
|
//@ revisions: x86_64_unknown_linux_gnuasan
|
||||||
|
//@ [x86_64_unknown_linux_gnuasan] compile-flags: --target x86_64-unknown-linux-gnuasan
|
||||||
|
//@ [x86_64_unknown_linux_gnuasan] needs-llvm-components: x86
|
||||||
//@ revisions: x86_64_unknown_linux_musl
|
//@ revisions: x86_64_unknown_linux_musl
|
||||||
//@ [x86_64_unknown_linux_musl] compile-flags: --target x86_64-unknown-linux-musl
|
//@ [x86_64_unknown_linux_musl] compile-flags: --target x86_64-unknown-linux-musl
|
||||||
//@ [x86_64_unknown_linux_musl] needs-llvm-components: x86
|
//@ [x86_64_unknown_linux_musl] needs-llvm-components: x86
|
||||||
|
|
|
||||||
131
tests/build-std/configurations/rmake.rs
Normal file
131
tests/build-std/configurations/rmake.rs
Normal file
|
|
@ -0,0 +1,131 @@
|
||||||
|
// This test ensures we are able to compile -Zbuild-std=core under a variety of profiles.
|
||||||
|
// Currently, it tests that we can compile to all Tier 1 targets, and it does this by checking what
|
||||||
|
// the tier metadata in target-spec JSON. This means that all in-tree targets must have a tier set.
|
||||||
|
|
||||||
|
#![deny(warnings)]
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
use std::thread;
|
||||||
|
|
||||||
|
use run_make_support::serde_json::{self, Value};
|
||||||
|
use run_make_support::tempfile::TempDir;
|
||||||
|
use run_make_support::{cargo, rfs, rustc};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Task {
|
||||||
|
target: String,
|
||||||
|
opt_level: u8,
|
||||||
|
debug: u8,
|
||||||
|
panic: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn manifest(task: &Task) -> String {
|
||||||
|
let Task { opt_level, debug, panic, target: _ } = task;
|
||||||
|
format!(
|
||||||
|
r#"[package]
|
||||||
|
name = "scratch"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "lib.rs"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
opt-level = {opt_level}
|
||||||
|
debug = {debug}
|
||||||
|
panic = "{panic}"
|
||||||
|
"#
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut targets = Vec::new();
|
||||||
|
let all_targets =
|
||||||
|
rustc().args(&["--print=all-target-specs-json", "-Zunstable-options"]).run().stdout_utf8();
|
||||||
|
let all_targets: HashMap<String, Value> = serde_json::from_str(&all_targets).unwrap();
|
||||||
|
for (target, spec) in all_targets {
|
||||||
|
let metadata = spec.as_object().unwrap()["metadata"].as_object().unwrap();
|
||||||
|
let tier = metadata["tier"]
|
||||||
|
.as_u64()
|
||||||
|
.expect(&format!("Target {} is missing tier metadata", target));
|
||||||
|
if tier == 1 {
|
||||||
|
targets.push(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut tasks = Vec::new();
|
||||||
|
|
||||||
|
// Testing every combination of compiler flags is infeasible. So we are making some attempt to
|
||||||
|
// choose combinations that will tend to run into problems.
|
||||||
|
//
|
||||||
|
// The particular combination of settings below is tuned to look for problems generating the
|
||||||
|
// code for compiler-builtins.
|
||||||
|
// We only exercise opt-level 0 and 3 to exercise mir-opt-level 1 and 2.
|
||||||
|
// We only exercise debug 0 and 2 because level 2 turns off some MIR optimizations.
|
||||||
|
// We only test abort and immediate-abort because abort vs unwind doesn't change MIR much at
|
||||||
|
// all. but immediate-abort does.
|
||||||
|
//
|
||||||
|
// Currently this only tests that we can compile the tier 1 targets. But since we are using
|
||||||
|
// -Zbuild-std=core, we could have any list of targets.
|
||||||
|
|
||||||
|
for opt_level in [0, 3] {
|
||||||
|
for debug in [0, 2] {
|
||||||
|
for panic in ["abort", "immediate-abort"] {
|
||||||
|
for target in &targets {
|
||||||
|
tasks.push(Task { target: target.clone(), opt_level, debug, panic });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let tasks = Arc::new(Mutex::new(tasks));
|
||||||
|
let mut threads = Vec::new();
|
||||||
|
|
||||||
|
// Try to obey the -j argument passed to bootstrap, otherwise fall back to using all the system
|
||||||
|
// resouces. This test can be rather memory-hungry (~1 GB/thread); if it causes trouble in
|
||||||
|
// practice do not hesitate to limit its parallelism.
|
||||||
|
for _ in 0..run_make_support::env::jobs() {
|
||||||
|
let tasks = Arc::clone(&tasks);
|
||||||
|
let handle = thread::spawn(move || {
|
||||||
|
loop {
|
||||||
|
let maybe_task = tasks.lock().unwrap().pop();
|
||||||
|
if let Some(task) = maybe_task {
|
||||||
|
test(task);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
threads.push(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
for t in threads {
|
||||||
|
t.join().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test(task: Task) {
|
||||||
|
let dir = TempDir::new().unwrap();
|
||||||
|
|
||||||
|
let manifest = manifest(&task);
|
||||||
|
rfs::write(dir.path().join("Cargo.toml"), &manifest);
|
||||||
|
rfs::write(dir.path().join("lib.rs"), "#![no_std]");
|
||||||
|
|
||||||
|
let mut args = vec!["build", "--release", "-Zbuild-std=core", "--target", &task.target, "-j1"];
|
||||||
|
if task.panic == "immediate-abort" {
|
||||||
|
args.push("-Zpanic-immediate-abort");
|
||||||
|
}
|
||||||
|
cargo()
|
||||||
|
.current_dir(dir.path())
|
||||||
|
.args(&args)
|
||||||
|
.env("RUSTC_BOOTSTRAP", "1")
|
||||||
|
// Visual Studio 2022 requires that the LIB env var be set so it can
|
||||||
|
// find the Windows SDK.
|
||||||
|
.env("LIB", std::env::var("LIB").unwrap_or_default())
|
||||||
|
.context(&format!(
|
||||||
|
"build-std for target `{}` failed with the following Cargo.toml:\n\n{manifest}",
|
||||||
|
task.target
|
||||||
|
))
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
@ -10,8 +10,8 @@
|
||||||
//@ revisions: with_remap with_coverage_scope with_object_scope with_macro_scope
|
//@ revisions: with_remap with_coverage_scope with_object_scope with_macro_scope
|
||||||
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
|
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
|
||||||
//
|
//
|
||||||
//@[with_coverage_scope] compile-flags: -Zremap-path-scope=coverage
|
//@[with_coverage_scope] compile-flags: --remap-path-scope=coverage
|
||||||
//@[with_object_scope] compile-flags: -Zremap-path-scope=object
|
//@[with_object_scope] compile-flags: --remap-path-scope=object
|
||||||
//@[with_macro_scope] compile-flags: -Zremap-path-scope=macro
|
//@[with_macro_scope] compile-flags: --remap-path-scope=macro
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,9 @@
|
||||||
LL| |//@ revisions: with_remap with_coverage_scope with_object_scope with_macro_scope
|
LL| |//@ revisions: with_remap with_coverage_scope with_object_scope with_macro_scope
|
||||||
LL| |//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
|
LL| |//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
|
||||||
LL| |//
|
LL| |//
|
||||||
LL| |//@[with_coverage_scope] compile-flags: -Zremap-path-scope=coverage
|
LL| |//@[with_coverage_scope] compile-flags: --remap-path-scope=coverage
|
||||||
LL| |//@[with_object_scope] compile-flags: -Zremap-path-scope=object
|
LL| |//@[with_object_scope] compile-flags: --remap-path-scope=object
|
||||||
LL| |//@[with_macro_scope] compile-flags: -Zremap-path-scope=macro
|
LL| |//@[with_macro_scope] compile-flags: --remap-path-scope=macro
|
||||||
LL| |
|
LL| |
|
||||||
LL| 1|fn main() {}
|
LL| 1|fn main() {}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ fn main() {
|
||||||
location_caller
|
location_caller
|
||||||
.crate_type("lib")
|
.crate_type("lib")
|
||||||
.remap_path_prefix(cwd(), "/remapped")
|
.remap_path_prefix(cwd(), "/remapped")
|
||||||
.arg("-Zremap-path-scope=object")
|
.arg("--remap-path-scope=object")
|
||||||
.input(cwd().join("location-caller.rs"));
|
.input(cwd().join("location-caller.rs"));
|
||||||
location_caller.run();
|
location_caller.run();
|
||||||
|
|
||||||
|
|
@ -105,7 +105,7 @@ fn main() {
|
||||||
runner
|
runner
|
||||||
.crate_type("bin")
|
.crate_type("bin")
|
||||||
.remap_path_prefix(cwd(), "/remapped")
|
.remap_path_prefix(cwd(), "/remapped")
|
||||||
.arg("-Zremap-path-scope=diagnostics")
|
.arg("--remap-path-scope=diagnostics")
|
||||||
.input(cwd().join("runner.rs"))
|
.input(cwd().join("runner.rs"))
|
||||||
.output(&runner_bin);
|
.output(&runner_bin);
|
||||||
runner.run();
|
runner.run();
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ fn check_dwarf_deps(scope: &str, dwarf_test: DwarfDump) {
|
||||||
let mut rustc_sm = rustc();
|
let mut rustc_sm = rustc();
|
||||||
rustc_sm.input(cwd().join("src/some_value.rs"));
|
rustc_sm.input(cwd().join("src/some_value.rs"));
|
||||||
rustc_sm.arg("-Cdebuginfo=2");
|
rustc_sm.arg("-Cdebuginfo=2");
|
||||||
rustc_sm.arg(format!("-Zremap-path-scope={}", scope));
|
rustc_sm.arg(format!("--remap-path-scope={}", scope));
|
||||||
rustc_sm.arg("--remap-path-prefix");
|
rustc_sm.arg("--remap-path-prefix");
|
||||||
rustc_sm.arg(format!("{}=/REMAPPED", cwd().display()));
|
rustc_sm.arg(format!("{}=/REMAPPED", cwd().display()));
|
||||||
rustc_sm.arg("-Csplit-debuginfo=off");
|
rustc_sm.arg("-Csplit-debuginfo=off");
|
||||||
|
|
@ -117,7 +117,7 @@ fn check_dwarf_deps(scope: &str, dwarf_test: DwarfDump) {
|
||||||
rustc_pv.input(cwd().join("src/print_value.rs"));
|
rustc_pv.input(cwd().join("src/print_value.rs"));
|
||||||
rustc_pv.output(&print_value_rlib);
|
rustc_pv.output(&print_value_rlib);
|
||||||
rustc_pv.arg("-Cdebuginfo=2");
|
rustc_pv.arg("-Cdebuginfo=2");
|
||||||
rustc_pv.arg(format!("-Zremap-path-scope={}", scope));
|
rustc_pv.arg(format!("--remap-path-scope={}", scope));
|
||||||
rustc_pv.arg("--remap-path-prefix");
|
rustc_pv.arg("--remap-path-prefix");
|
||||||
rustc_pv.arg(format!("{}=/REMAPPED", cwd().display()));
|
rustc_pv.arg(format!("{}=/REMAPPED", cwd().display()));
|
||||||
rustc_pv.arg("-Csplit-debuginfo=off");
|
rustc_pv.arg("-Csplit-debuginfo=off");
|
||||||
|
|
@ -158,8 +158,8 @@ fn check_dwarf(test: DwarfTest) {
|
||||||
rustc.arg("-Cdebuginfo=2");
|
rustc.arg("-Cdebuginfo=2");
|
||||||
if let Some(scope) = test.scope {
|
if let Some(scope) = test.scope {
|
||||||
match scope {
|
match scope {
|
||||||
ScopeType::Object => rustc.arg("-Zremap-path-scope=object"),
|
ScopeType::Object => rustc.arg("--remap-path-scope=object"),
|
||||||
ScopeType::Diagnostics => rustc.arg("-Zremap-path-scope=diagnostics"),
|
ScopeType::Diagnostics => rustc.arg("--remap-path-scope=diagnostics"),
|
||||||
};
|
};
|
||||||
if is_darwin() {
|
if is_darwin() {
|
||||||
rustc.arg("-Csplit-debuginfo=off");
|
rustc.arg("-Csplit-debuginfo=off");
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,9 @@ fn main() {
|
||||||
rmeta_contains("/the/aux/lib.rs");
|
rmeta_contains("/the/aux/lib.rs");
|
||||||
rmeta_not_contains("auxiliary");
|
rmeta_not_contains("auxiliary");
|
||||||
|
|
||||||
out_object.arg("-Zremap-path-scope=object");
|
out_object.arg("--remap-path-scope=object");
|
||||||
out_macro.arg("-Zremap-path-scope=macro");
|
out_macro.arg("--remap-path-scope=macro");
|
||||||
out_diagobj.arg("-Zremap-path-scope=diagnostics,object");
|
out_diagobj.arg("--remap-path-scope=diagnostics,object");
|
||||||
if is_darwin() {
|
if is_darwin() {
|
||||||
out_object.arg("-Csplit-debuginfo=off");
|
out_object.arg("-Csplit-debuginfo=off");
|
||||||
out_macro.arg("-Csplit-debuginfo=off");
|
out_macro.arg("-Csplit-debuginfo=off");
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
@@ -65,10 +65,28 @@
|
@@ -65,10 +65,31 @@
|
||||||
Set a codegen option
|
Set a codegen option
|
||||||
-V, --version Print version info and exit
|
-V, --version Print version info and exit
|
||||||
-v, --verbose Use verbose output
|
-v, --verbose Use verbose output
|
||||||
|
|
@ -20,6 +20,9 @@
|
||||||
+ --remap-path-prefix <FROM>=<TO>
|
+ --remap-path-prefix <FROM>=<TO>
|
||||||
+ Remap source names in all output (compiler messages
|
+ Remap source names in all output (compiler messages
|
||||||
+ and output files)
|
+ and output files)
|
||||||
|
+ --remap-path-scope <macro,diagnostics,debuginfo,coverage,object,all>
|
||||||
|
+ Defines which scopes of paths should be remapped by
|
||||||
|
+ `--remap-path-prefix`
|
||||||
+ @path Read newline separated options from `path`
|
+ @path Read newline separated options from `path`
|
||||||
|
|
||||||
Additional help:
|
Additional help:
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,9 @@ Options:
|
||||||
--remap-path-prefix <FROM>=<TO>
|
--remap-path-prefix <FROM>=<TO>
|
||||||
Remap source names in all output (compiler messages
|
Remap source names in all output (compiler messages
|
||||||
and output files)
|
and output files)
|
||||||
|
--remap-path-scope <macro,diagnostics,debuginfo,coverage,object,all>
|
||||||
|
Defines which scopes of paths should be remapped by
|
||||||
|
`--remap-path-prefix`
|
||||||
@path Read newline separated options from `path`
|
@path Read newline separated options from `path`
|
||||||
|
|
||||||
Additional help:
|
Additional help:
|
||||||
|
|
|
||||||
|
|
@ -171,8 +171,7 @@ enum RemapPathPrefix {
|
||||||
Unspecified,
|
Unspecified,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `-Zremap-path-scope`. See
|
/// `--remap-path-scope`
|
||||||
/// <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/remap-path-scope.html#remap-path-scope>.
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
enum RemapPathScope {
|
enum RemapPathScope {
|
||||||
/// Comma-separated list of remap scopes: `macro`, `diagnostics`, `debuginfo`, `object`, `all`.
|
/// Comma-separated list of remap scopes: `macro`, `diagnostics`, `debuginfo`, `object`, `all`.
|
||||||
|
|
@ -921,7 +920,7 @@ mod shared_linux_other_tests {
|
||||||
.debuginfo(level.cli_value())
|
.debuginfo(level.cli_value())
|
||||||
.arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value()))
|
.arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value()))
|
||||||
.remap_path_prefix(cwd(), remapped_prefix)
|
.remap_path_prefix(cwd(), remapped_prefix)
|
||||||
.arg(format!("-Zremap-path-scope={scope}"))
|
.arg(format!("--remap-path-scope={scope}"))
|
||||||
.run();
|
.run();
|
||||||
let found_files = cwd_filenames();
|
let found_files = cwd_filenames();
|
||||||
FileAssertions { expected_files: BTreeSet::from(["foo", "foo.dwp"]) }
|
FileAssertions { expected_files: BTreeSet::from(["foo", "foo.dwp"]) }
|
||||||
|
|
@ -950,7 +949,7 @@ mod shared_linux_other_tests {
|
||||||
.debuginfo(level.cli_value())
|
.debuginfo(level.cli_value())
|
||||||
.arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value()))
|
.arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value()))
|
||||||
.remap_path_prefix(cwd(), remapped_prefix)
|
.remap_path_prefix(cwd(), remapped_prefix)
|
||||||
.arg(format!("-Zremap-path-scope={scope}"))
|
.arg(format!("--remap-path-scope={scope}"))
|
||||||
.run();
|
.run();
|
||||||
let found_files = cwd_filenames();
|
let found_files = cwd_filenames();
|
||||||
FileAssertions { expected_files: BTreeSet::from(["foo", "foo.dwp"]) }
|
FileAssertions { expected_files: BTreeSet::from(["foo", "foo.dwp"]) }
|
||||||
|
|
@ -1202,7 +1201,7 @@ mod shared_linux_other_tests {
|
||||||
.debuginfo(level.cli_value())
|
.debuginfo(level.cli_value())
|
||||||
.arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value()))
|
.arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value()))
|
||||||
.remap_path_prefix(cwd(), remapped_prefix)
|
.remap_path_prefix(cwd(), remapped_prefix)
|
||||||
.arg(format!("-Zremap-path-scope={scope}"))
|
.arg(format!("--remap-path-scope={scope}"))
|
||||||
.run();
|
.run();
|
||||||
|
|
||||||
let found_files = cwd_filenames();
|
let found_files = cwd_filenames();
|
||||||
|
|
@ -1242,7 +1241,7 @@ mod shared_linux_other_tests {
|
||||||
.debuginfo(level.cli_value())
|
.debuginfo(level.cli_value())
|
||||||
.arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value()))
|
.arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value()))
|
||||||
.remap_path_prefix(cwd(), remapped_prefix)
|
.remap_path_prefix(cwd(), remapped_prefix)
|
||||||
.arg(format!("-Zremap-path-scope={scope}"))
|
.arg(format!("--remap-path-scope={scope}"))
|
||||||
.run();
|
.run();
|
||||||
|
|
||||||
let found_files = cwd_filenames();
|
let found_files = cwd_filenames();
|
||||||
|
|
@ -1356,7 +1355,7 @@ fn main() {
|
||||||
// NOTE: these combinations are not exhaustive, because while porting to rmake.rs initially I
|
// NOTE: these combinations are not exhaustive, because while porting to rmake.rs initially I
|
||||||
// tried to preserve the existing test behavior closely. Notably, no attempt was made to
|
// tried to preserve the existing test behavior closely. Notably, no attempt was made to
|
||||||
// exhaustively cover all cases in the 6-fold Cartesian product of `{,-Csplit=debuginfo=...}` x
|
// exhaustively cover all cases in the 6-fold Cartesian product of `{,-Csplit=debuginfo=...}` x
|
||||||
// `{,-Cdebuginfo=...}` x `{,--remap-path-prefix}` x `{,-Zremap-path-scope=...}` x
|
// `{,-Cdebuginfo=...}` x `{,--remap-path-prefix}` x `{,--remap-path-scope=...}` x
|
||||||
// `{,-Zsplit-dwarf-kind=...}` x `{,-Clinker-plugin-lto}`. If you really want to, you can
|
// `{,-Zsplit-dwarf-kind=...}` x `{,-Clinker-plugin-lto}`. If you really want to, you can
|
||||||
// identify which combination isn't exercised with a 6-layers nested for loop iterating through
|
// identify which combination isn't exercised with a 6-layers nested for loop iterating through
|
||||||
// each of the cli flag enum variants.
|
// each of the cli flag enum variants.
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
//@ compile-flags: --extern-html-root-url=empty=https://empty.example/
|
//@ compile-flags: --extern-html-root-url=empty=https://empty.example/
|
||||||
// This one is to ensure that we don't link to any item we see which has
|
// This one is to ensure that we don't link to any item we see which has
|
||||||
// an external html root URL unless it actually exists.
|
// an external html root URL unless it actually exists.
|
||||||
//@ compile-flags: --extern-html-root-url=non_existant=https://non-existant.example/
|
//@ compile-flags: --extern-html-root-url=non_existent=https://non-existent.example/
|
||||||
//@ aux-build: empty.rs
|
//@ aux-build: empty.rs
|
||||||
|
|
||||||
#![crate_name = "foo"]
|
#![crate_name = "foo"]
|
||||||
|
|
@ -14,10 +14,10 @@
|
||||||
|
|
||||||
//@ has 'foo/index.html'
|
//@ has 'foo/index.html'
|
||||||
//@ has - '//a[@href="https://empty.example/empty/index.html"]' 'empty'
|
//@ has - '//a[@href="https://empty.example/empty/index.html"]' 'empty'
|
||||||
// There should only be one intra doc links, we should not link `non_existant`.
|
// There should only be one intra doc links, we should not link `non_existent`.
|
||||||
//@ count - '//*[@class="docblock"]//a' 1
|
//@ count - '//*[@class="docblock"]//a' 1
|
||||||
//! [`empty`]
|
//! [`empty`]
|
||||||
//!
|
//!
|
||||||
//! [`non_existant`]
|
//! [`non_existent`]
|
||||||
|
|
||||||
extern crate empty;
|
extern crate empty;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
|
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
|
||||||
//@ compile-flags: -Zremap-path-scope=debuginfo
|
//@ compile-flags: --remap-path-scope=debuginfo
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! my_file {
|
macro_rules! my_file {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
|
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
|
||||||
//@ compile-flags: -Zremap-path-scope=diagnostics
|
//@ compile-flags: --remap-path-scope=diagnostics
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! my_file {
|
macro_rules! my_file {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
|
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
|
||||||
//@ compile-flags: -Zremap-path-scope=macro
|
//@ compile-flags: --remap-path-scope=macro
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! my_file {
|
macro_rules! my_file {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
|
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
|
||||||
//@ compile-flags: -Zremap-path-scope=debuginfo
|
//@ compile-flags: --remap-path-scope=debuginfo
|
||||||
|
|
||||||
pub trait Trait: std::fmt::Display {}
|
pub trait Trait: std::fmt::Display {}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
|
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
|
||||||
//@ compile-flags: -Zremap-path-scope=diagnostics
|
//@ compile-flags: --remap-path-scope=diagnostics
|
||||||
|
|
||||||
pub trait Trait: std::fmt::Display {}
|
pub trait Trait: std::fmt::Display {}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
|
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
|
||||||
//@ compile-flags: -Zremap-path-scope=macro
|
//@ compile-flags: --remap-path-scope=macro
|
||||||
|
|
||||||
pub trait Trait: std::fmt::Display {}
|
pub trait Trait: std::fmt::Display {}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// This test exercises `-Zremap-path-scope`, diagnostics printing paths and dependency.
|
// This test exercises `--remap-path-scope`, diagnostics printing paths and dependency.
|
||||||
//
|
//
|
||||||
// We test different combinations with/without remap in deps, with/without remap in this
|
// We test different combinations with/without remap in deps, with/without remap in this
|
||||||
// crate but always in deps and always here but never in deps.
|
// crate but always in deps and always here but never in deps.
|
||||||
|
|
@ -12,10 +12,10 @@
|
||||||
//@[with-debuginfo-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
|
//@[with-debuginfo-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
|
||||||
//@[not-diag-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
|
//@[not-diag-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
|
||||||
|
|
||||||
//@[with-diag-in-deps] compile-flags: -Zremap-path-scope=diagnostics
|
//@[with-diag-in-deps] compile-flags: --remap-path-scope=diagnostics
|
||||||
//@[with-macro-in-deps] compile-flags: -Zremap-path-scope=macro
|
//@[with-macro-in-deps] compile-flags: --remap-path-scope=macro
|
||||||
//@[with-debuginfo-in-deps] compile-flags: -Zremap-path-scope=debuginfo
|
//@[with-debuginfo-in-deps] compile-flags: --remap-path-scope=debuginfo
|
||||||
//@[not-diag-in-deps] compile-flags: -Zremap-path-scope=diagnostics
|
//@[not-diag-in-deps] compile-flags: --remap-path-scope=diagnostics
|
||||||
|
|
||||||
//@[with-diag-in-deps] aux-build:trait-diag.rs
|
//@[with-diag-in-deps] aux-build:trait-diag.rs
|
||||||
//@[with-macro-in-deps] aux-build:trait-macro.rs
|
//@[with-macro-in-deps] aux-build:trait-macro.rs
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// This test exercises `-Zremap-path-scope`, macros (like file!()) and dependency.
|
// This test exercises `--remap-path-scope`, macros (like file!()) and dependency.
|
||||||
//
|
//
|
||||||
// We test different combinations with/without remap in deps, with/without remap in
|
// We test different combinations with/without remap in deps, with/without remap in
|
||||||
// this crate but always in deps and always here but never in deps.
|
// this crate but always in deps and always here but never in deps.
|
||||||
|
|
@ -15,10 +15,10 @@
|
||||||
//@[with-debuginfo-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
|
//@[with-debuginfo-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
|
||||||
//@[not-macro-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
|
//@[not-macro-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
|
||||||
|
|
||||||
//@[with-diag-in-deps] compile-flags: -Zremap-path-scope=diagnostics
|
//@[with-diag-in-deps] compile-flags: --remap-path-scope=diagnostics
|
||||||
//@[with-macro-in-deps] compile-flags: -Zremap-path-scope=macro
|
//@[with-macro-in-deps] compile-flags: --remap-path-scope=macro
|
||||||
//@[with-debuginfo-in-deps] compile-flags: -Zremap-path-scope=debuginfo
|
//@[with-debuginfo-in-deps] compile-flags: --remap-path-scope=debuginfo
|
||||||
//@[not-macro-in-deps] compile-flags: -Zremap-path-scope=macro
|
//@[not-macro-in-deps] compile-flags: --remap-path-scope=macro
|
||||||
|
|
||||||
//@[with-diag-in-deps] aux-build:file-diag.rs
|
//@[with-diag-in-deps] aux-build:file-diag.rs
|
||||||
//@[with-macro-in-deps] aux-build:file-macro.rs
|
//@[with-macro-in-deps] aux-build:file-macro.rs
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
//@ revisions: normal with-diagnostic-scope without-diagnostic-scope
|
//@ revisions: normal with-diagnostic-scope without-diagnostic-scope
|
||||||
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
|
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
|
||||||
//@ [with-diagnostic-scope]compile-flags: -Zremap-path-scope=diagnostics
|
//@ [with-diagnostic-scope]compile-flags: --remap-path-scope=diagnostics
|
||||||
//@ [without-diagnostic-scope]compile-flags: -Zremap-path-scope=object
|
//@ [without-diagnostic-scope]compile-flags: --remap-path-scope=object
|
||||||
// Manually remap, so the remapped path remains in .stderr file.
|
// Manually remap, so the remapped path remains in .stderr file.
|
||||||
|
|
||||||
// The remapped paths are not normalized by compiletest.
|
// The remapped paths are not normalized by compiletest.
|
||||||
|
|
|
||||||
84
tests/ui/imports/ambiguous-trait-in-scope.rs
Normal file
84
tests/ui/imports/ambiguous-trait-in-scope.rs
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
//@ edition:2018
|
||||||
|
//@ aux-crate:external=ambiguous-trait-reexport.rs
|
||||||
|
|
||||||
|
mod m1 {
|
||||||
|
pub trait Trait {
|
||||||
|
fn method1(&self) {}
|
||||||
|
}
|
||||||
|
impl Trait for u8 {}
|
||||||
|
}
|
||||||
|
mod m2 {
|
||||||
|
pub trait Trait {
|
||||||
|
fn method2(&self) {}
|
||||||
|
}
|
||||||
|
impl Trait for u8 {}
|
||||||
|
}
|
||||||
|
mod m1_reexport {
|
||||||
|
pub use crate::m1::Trait;
|
||||||
|
}
|
||||||
|
mod m2_reexport {
|
||||||
|
pub use crate::m2::Trait;
|
||||||
|
}
|
||||||
|
|
||||||
|
mod ambig_reexport {
|
||||||
|
pub use crate::m1::*;
|
||||||
|
pub use crate::m2::*;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test1() {
|
||||||
|
// Create an ambiguous import for `Trait` in one order
|
||||||
|
use m1::*;
|
||||||
|
use m2::*;
|
||||||
|
0u8.method1(); //~ WARNING Use of ambiguously glob imported trait `Trait` [ambiguous_glob_imported_traits]
|
||||||
|
//~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
0u8.method2(); //~ ERROR: no method named `method2` found for type `u8` in the current scope
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test2() {
|
||||||
|
// Create an ambiguous import for `Trait` in another order
|
||||||
|
use m2::*;
|
||||||
|
use m1::*;
|
||||||
|
0u8.method1(); //~ ERROR: no method named `method1` found for type `u8` in the current scope
|
||||||
|
0u8.method2(); //~ WARNING Use of ambiguously glob imported trait `Trait` [ambiguous_glob_imported_traits]
|
||||||
|
//~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_indirect_reexport() {
|
||||||
|
use m1_reexport::*;
|
||||||
|
use m2_reexport::*;
|
||||||
|
0u8.method1(); //~ WARNING Use of ambiguously glob imported trait `Trait` [ambiguous_glob_imported_traits]
|
||||||
|
//~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
0u8.method2(); //~ ERROR: no method named `method2` found for type `u8` in the current scope
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_ambig_reexport() {
|
||||||
|
use ambig_reexport::*;
|
||||||
|
0u8.method1(); //~ WARNING Use of ambiguously glob imported trait `Trait` [ambiguous_glob_imported_traits]
|
||||||
|
//~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
0u8.method2(); //~ ERROR: no method named `method2` found for type `u8` in the current scope
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_external() {
|
||||||
|
use external::m1::*;
|
||||||
|
use external::m2::*;
|
||||||
|
0u8.method1(); //~ WARNING Use of ambiguously glob imported trait `Trait` [ambiguous_glob_imported_traits]
|
||||||
|
//~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
0u8.method2(); //~ ERROR: no method named `method2` found for type `u8` in the current scope
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_external_indirect_reexport() {
|
||||||
|
use external::m1_reexport::*;
|
||||||
|
use external::m2_reexport::*;
|
||||||
|
0u8.method1(); //~ WARNING Use of ambiguously glob imported trait `Trait` [ambiguous_glob_imported_traits]
|
||||||
|
//~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
0u8.method2(); //~ ERROR: no method named `method2` found for type `u8` in the current scope
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_external_ambig_reexport() {
|
||||||
|
use external::ambig_reexport::*;
|
||||||
|
0u8.method1(); //~ WARNING Use of ambiguously glob imported trait `Trait` [ambiguous_glob_imported_traits]
|
||||||
|
//~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
0u8.method2(); //~ ERROR: no method named `method2` found for type `u8` in the current scope
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
191
tests/ui/imports/ambiguous-trait-in-scope.stderr
Normal file
191
tests/ui/imports/ambiguous-trait-in-scope.stderr
Normal file
|
|
@ -0,0 +1,191 @@
|
||||||
|
warning: Use of ambiguously glob imported trait `Trait`
|
||||||
|
--> $DIR/ambiguous-trait-in-scope.rs:32:9
|
||||||
|
|
|
||||||
|
LL | use m1::*;
|
||||||
|
| -- `Trait` imported ambiguously here
|
||||||
|
LL | use m2::*;
|
||||||
|
LL | 0u8.method1();
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #147992 <https://github.com/rust-lang/rust/issues/147992>
|
||||||
|
= help: Import `Trait` explicitly
|
||||||
|
= note: `#[warn(ambiguous_glob_imported_traits)]` (part of `#[warn(future_incompatible)]`) on by default
|
||||||
|
|
||||||
|
error[E0599]: no method named `method2` found for type `u8` in the current scope
|
||||||
|
--> $DIR/ambiguous-trait-in-scope.rs:34:9
|
||||||
|
|
|
||||||
|
LL | 0u8.method2();
|
||||||
|
| ^^^^^^^ method not found in `u8`
|
||||||
|
|
|
||||||
|
= help: items from traits can only be used if the trait is in scope
|
||||||
|
help: the following traits which provide `method2` are implemented but not in scope; perhaps you want to import one of them
|
||||||
|
|
|
||||||
|
LL + use ambiguous_trait_reexport::m2::Trait;
|
||||||
|
|
|
||||||
|
LL + use crate::m2::Trait;
|
||||||
|
|
|
||||||
|
|
||||||
|
error[E0599]: no method named `method1` found for type `u8` in the current scope
|
||||||
|
--> $DIR/ambiguous-trait-in-scope.rs:41:9
|
||||||
|
|
|
||||||
|
LL | 0u8.method1();
|
||||||
|
| ^^^^^^^ method not found in `u8`
|
||||||
|
|
|
||||||
|
= help: items from traits can only be used if the trait is in scope
|
||||||
|
help: the following traits which provide `method1` are implemented but not in scope; perhaps you want to import one of them
|
||||||
|
|
|
||||||
|
LL + use ambiguous_trait_reexport::m1::Trait;
|
||||||
|
|
|
||||||
|
LL + use crate::m1::Trait;
|
||||||
|
|
|
||||||
|
|
||||||
|
warning: Use of ambiguously glob imported trait `Trait`
|
||||||
|
--> $DIR/ambiguous-trait-in-scope.rs:42:9
|
||||||
|
|
|
||||||
|
LL | use m2::*;
|
||||||
|
| -- `Trait` imported ambiguously here
|
||||||
|
...
|
||||||
|
LL | 0u8.method2();
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #147992 <https://github.com/rust-lang/rust/issues/147992>
|
||||||
|
= help: Import `Trait` explicitly
|
||||||
|
|
||||||
|
warning: Use of ambiguously glob imported trait `Trait`
|
||||||
|
--> $DIR/ambiguous-trait-in-scope.rs:49:9
|
||||||
|
|
|
||||||
|
LL | use m1_reexport::*;
|
||||||
|
| ----------- `Trait` imported ambiguously here
|
||||||
|
LL | use m2_reexport::*;
|
||||||
|
LL | 0u8.method1();
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #147992 <https://github.com/rust-lang/rust/issues/147992>
|
||||||
|
= help: Import `Trait` explicitly
|
||||||
|
|
||||||
|
error[E0599]: no method named `method2` found for type `u8` in the current scope
|
||||||
|
--> $DIR/ambiguous-trait-in-scope.rs:51:9
|
||||||
|
|
|
||||||
|
LL | 0u8.method2();
|
||||||
|
| ^^^^^^^ method not found in `u8`
|
||||||
|
|
|
||||||
|
= help: items from traits can only be used if the trait is in scope
|
||||||
|
help: the following traits which provide `method2` are implemented but not in scope; perhaps you want to import one of them
|
||||||
|
|
|
||||||
|
LL + use ambiguous_trait_reexport::m2::Trait;
|
||||||
|
|
|
||||||
|
LL + use crate::m2::Trait;
|
||||||
|
|
|
||||||
|
|
||||||
|
warning: Use of ambiguously glob imported trait `Trait`
|
||||||
|
--> $DIR/ambiguous-trait-in-scope.rs:56:9
|
||||||
|
|
|
||||||
|
LL | use ambig_reexport::*;
|
||||||
|
| -------------- `Trait` imported ambiguously here
|
||||||
|
LL | 0u8.method1();
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #147992 <https://github.com/rust-lang/rust/issues/147992>
|
||||||
|
= help: Import `Trait` explicitly
|
||||||
|
|
||||||
|
error[E0599]: no method named `method2` found for type `u8` in the current scope
|
||||||
|
--> $DIR/ambiguous-trait-in-scope.rs:58:9
|
||||||
|
|
|
||||||
|
LL | 0u8.method2();
|
||||||
|
| ^^^^^^^ method not found in `u8`
|
||||||
|
|
|
||||||
|
= help: items from traits can only be used if the trait is in scope
|
||||||
|
help: the following traits which provide `method2` are implemented but not in scope; perhaps you want to import one of them
|
||||||
|
|
|
||||||
|
LL + use ambiguous_trait_reexport::m2::Trait;
|
||||||
|
|
|
||||||
|
LL + use crate::m2::Trait;
|
||||||
|
|
|
||||||
|
|
||||||
|
warning: Use of ambiguously glob imported trait `Trait`
|
||||||
|
--> $DIR/ambiguous-trait-in-scope.rs:64:9
|
||||||
|
|
|
||||||
|
LL | use external::m1::*;
|
||||||
|
| ------------ `Trait` imported ambiguously here
|
||||||
|
LL | use external::m2::*;
|
||||||
|
LL | 0u8.method1();
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #147992 <https://github.com/rust-lang/rust/issues/147992>
|
||||||
|
= help: Import `Trait` explicitly
|
||||||
|
|
||||||
|
error[E0599]: no method named `method2` found for type `u8` in the current scope
|
||||||
|
--> $DIR/ambiguous-trait-in-scope.rs:66:9
|
||||||
|
|
|
||||||
|
LL | 0u8.method2();
|
||||||
|
| ^^^^^^^ method not found in `u8`
|
||||||
|
|
|
||||||
|
= help: items from traits can only be used if the trait is in scope
|
||||||
|
help: the following traits which provide `method2` are implemented but not in scope; perhaps you want to import one of them
|
||||||
|
|
|
||||||
|
LL + use ambiguous_trait_reexport::m2::Trait;
|
||||||
|
|
|
||||||
|
LL + use crate::m2::Trait;
|
||||||
|
|
|
||||||
|
|
||||||
|
warning: Use of ambiguously glob imported trait `Trait`
|
||||||
|
--> $DIR/ambiguous-trait-in-scope.rs:72:9
|
||||||
|
|
|
||||||
|
LL | use external::m1_reexport::*;
|
||||||
|
| --------------------- `Trait` imported ambiguously here
|
||||||
|
LL | use external::m2_reexport::*;
|
||||||
|
LL | 0u8.method1();
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #147992 <https://github.com/rust-lang/rust/issues/147992>
|
||||||
|
= help: Import `Trait` explicitly
|
||||||
|
|
||||||
|
error[E0599]: no method named `method2` found for type `u8` in the current scope
|
||||||
|
--> $DIR/ambiguous-trait-in-scope.rs:74:9
|
||||||
|
|
|
||||||
|
LL | 0u8.method2();
|
||||||
|
| ^^^^^^^ method not found in `u8`
|
||||||
|
|
|
||||||
|
= help: items from traits can only be used if the trait is in scope
|
||||||
|
help: the following traits which provide `method2` are implemented but not in scope; perhaps you want to import one of them
|
||||||
|
|
|
||||||
|
LL + use ambiguous_trait_reexport::m2::Trait;
|
||||||
|
|
|
||||||
|
LL + use crate::m2::Trait;
|
||||||
|
|
|
||||||
|
|
||||||
|
warning: Use of ambiguously glob imported trait `Trait`
|
||||||
|
--> $DIR/ambiguous-trait-in-scope.rs:79:9
|
||||||
|
|
|
||||||
|
LL | use external::ambig_reexport::*;
|
||||||
|
| ------------------------ `Trait` imported ambiguously here
|
||||||
|
LL | 0u8.method1();
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #147992 <https://github.com/rust-lang/rust/issues/147992>
|
||||||
|
= help: Import `Trait` explicitly
|
||||||
|
|
||||||
|
error[E0599]: no method named `method2` found for type `u8` in the current scope
|
||||||
|
--> $DIR/ambiguous-trait-in-scope.rs:81:9
|
||||||
|
|
|
||||||
|
LL | 0u8.method2();
|
||||||
|
| ^^^^^^^ method not found in `u8`
|
||||||
|
|
|
||||||
|
= help: items from traits can only be used if the trait is in scope
|
||||||
|
help: the following traits which provide `method2` are implemented but not in scope; perhaps you want to import one of them
|
||||||
|
|
|
||||||
|
LL + use ambiguous_trait_reexport::m2::Trait;
|
||||||
|
|
|
||||||
|
LL + use crate::m2::Trait;
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 7 previous errors; 7 warnings emitted
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0599`.
|
||||||
23
tests/ui/imports/auxiliary/ambiguous-trait-reexport.rs
Normal file
23
tests/ui/imports/auxiliary/ambiguous-trait-reexport.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
pub mod m1 {
|
||||||
|
pub trait Trait {
|
||||||
|
fn method1(&self) {}
|
||||||
|
}
|
||||||
|
impl Trait for u8 {}
|
||||||
|
}
|
||||||
|
pub mod m2 {
|
||||||
|
pub trait Trait {
|
||||||
|
fn method2(&self) {}
|
||||||
|
}
|
||||||
|
impl Trait for u8 {}
|
||||||
|
}
|
||||||
|
pub mod m1_reexport {
|
||||||
|
pub use crate::m1::Trait;
|
||||||
|
}
|
||||||
|
pub mod m2_reexport {
|
||||||
|
pub use crate::m2::Trait;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod ambig_reexport {
|
||||||
|
pub use crate::m1::*;
|
||||||
|
pub use crate::m2::*;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
//@ check-pass
|
||||||
|
// The AMBIGUOUS_GLOB_IMPORTED_TRAITS lint is reported on uses of traits that are
|
||||||
|
// ambiguously glob imported. This test checks that we don't report this lint
|
||||||
|
// when the same trait is glob imported multiple times.
|
||||||
|
|
||||||
|
mod t {
|
||||||
|
pub trait Trait {
|
||||||
|
fn method(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait for i8 {}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod m1 {
|
||||||
|
pub use t::Trait;
|
||||||
|
}
|
||||||
|
|
||||||
|
mod m2 {
|
||||||
|
pub use t::Trait;
|
||||||
|
}
|
||||||
|
|
||||||
|
use m1::*;
|
||||||
|
use m2::*;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
0i8.method();
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue