Auto merge of #139657 - Zalathar:rollup-6oh6f9q, r=Zalathar

Rollup of 12 pull requests

Successful merges:

 - #137447 (add `core::intrinsics::simd::{simd_extract_dyn, simd_insert_dyn}`)
 - #138182 (rustc_target: update x86_win64 to match the documented calling convention for f128)
 - #138682 (Allow drivers to supply a list of extra symbols to intern)
 - #138904 (Test linking and running `no_std` binaries)
 - #138998 (Don't suggest the use of  `impl Trait` in closure parameter)
 - #139447 (doc changes: debug assertions -> overflow checks)
 - #139469 (Introduce a `//@ needs-crate-type` compiletest directive)
 - #139564 (Deeply normalize obligations in `BestObligation` folder)
 - #139574 (bootstrap: improve `channel` handling)
 - #139600 (Update `compiler-builtins` to 0.1.153)
 - #139641 (Allow parenthesis around inferred array lengths)
 - #139654 (Improve `AssocItem::descr`.)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-04-11 04:24:47 +00:00
commit 18a029cfe8
91 changed files with 900 additions and 314 deletions

View File

@ -2034,7 +2034,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
fn lower_array_length_to_const_arg(&mut self, c: &AnonConst) -> &'hir hir::ConstArg<'hir> {
match c.value.kind {
// We cannot just match on `ExprKind::Underscore` as `(_)` is represented as
// `ExprKind::Paren(ExprKind::Underscore)` and should also be lowered to `GenericArg::Infer`
match c.value.peel_parens().kind {
ExprKind::Underscore => {
if !self.tcx.features().generic_arg_infer() {
feature_err(

View File

@ -1421,7 +1421,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
return Ok(bx.shuffle_vector(args[0].immediate(), args[1].immediate(), indices));
}
if name == sym::simd_insert {
if name == sym::simd_insert || name == sym::simd_insert_dyn {
require!(
in_elem == arg_tys[2],
InvalidMonomorphization::InsertedType {
@ -1432,40 +1432,49 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
out_ty: arg_tys[2]
}
);
let idx = bx
.const_to_opt_u128(args[1].immediate(), false)
.expect("typeck should have ensure that this is a const");
if idx >= in_len.into() {
return_error!(InvalidMonomorphization::SimdIndexOutOfBounds {
span,
name,
arg_idx: 1,
total_len: in_len.into(),
});
}
return Ok(bx.insert_element(
args[0].immediate(),
args[2].immediate(),
bx.const_i32(idx as i32),
));
let index_imm = if name == sym::simd_insert {
let idx = bx
.const_to_opt_u128(args[1].immediate(), false)
.expect("typeck should have ensure that this is a const");
if idx >= in_len.into() {
return_error!(InvalidMonomorphization::SimdIndexOutOfBounds {
span,
name,
arg_idx: 1,
total_len: in_len.into(),
});
}
bx.const_i32(idx as i32)
} else {
args[1].immediate()
};
return Ok(bx.insert_element(args[0].immediate(), args[2].immediate(), index_imm));
}
if name == sym::simd_extract {
if name == sym::simd_extract || name == sym::simd_extract_dyn {
require!(
ret_ty == in_elem,
InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
);
let idx = bx
.const_to_opt_u128(args[1].immediate(), false)
.expect("typeck should have ensure that this is a const");
if idx >= in_len.into() {
return_error!(InvalidMonomorphization::SimdIndexOutOfBounds {
span,
name,
arg_idx: 1,
total_len: in_len.into(),
});
}
return Ok(bx.extract_element(args[0].immediate(), bx.const_i32(idx as i32)));
let index_imm = if name == sym::simd_extract {
let idx = bx
.const_to_opt_u128(args[1].immediate(), false)
.expect("typeck should have ensure that this is a const");
if idx >= in_len.into() {
return_error!(InvalidMonomorphization::SimdIndexOutOfBounds {
span,
name,
arg_idx: 1,
total_len: in_len.into(),
});
}
bx.const_i32(idx as i32)
} else {
args[1].immediate()
};
return Ok(bx.extract_element(args[0].immediate(), index_imm));
}
if name == sym::simd_select {

View File

@ -264,6 +264,7 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
hash_untracked_state: None,
register_lints: None,
override_queries: None,
extra_symbols: Vec::new(),
make_codegen_backend: None,
registry: diagnostics_registry(),
using_internal_features: &USING_INTERNAL_FEATURES,

View File

@ -17,7 +17,7 @@ fn def_path_hash_depends_on_crate_id() {
// the crate by changing the crate disambiguator (e.g. via bumping the
// crate's version number).
create_session_globals_then(Edition::Edition2024, None, || {
create_session_globals_then(Edition::Edition2024, &[], None, || {
let id0 = StableCrateId::new(Symbol::intern("foo"), false, vec!["1".to_string()], "");
let id1 = StableCrateId::new(Symbol::intern("foo"), false, vec!["2".to_string()], "");

View File

@ -659,8 +659,12 @@ pub(crate) fn check_intrinsic_type(
sym::simd_masked_load => (3, 0, vec![param(0), param(1), param(2)], param(2)),
sym::simd_masked_store => (3, 0, vec![param(0), param(1), param(2)], tcx.types.unit),
sym::simd_scatter => (3, 0, vec![param(0), param(1), param(2)], tcx.types.unit),
sym::simd_insert => (2, 0, vec![param(0), tcx.types.u32, param(1)], param(0)),
sym::simd_extract => (2, 0, vec![param(0), tcx.types.u32], param(1)),
sym::simd_insert | sym::simd_insert_dyn => {
(2, 0, vec![param(0), tcx.types.u32, param(1)], param(0))
}
sym::simd_extract | sym::simd_extract_dyn => {
(2, 0, vec![param(0), tcx.types.u32], param(1))
}
sym::simd_cast
| sym::simd_as
| sym::simd_cast_ptr

View File

@ -348,6 +348,10 @@ pub struct Config {
/// the list of queries.
pub override_queries: Option<fn(&Session, &mut Providers)>,
/// An extra set of symbols to add to the symbol interner, the symbol indices
/// will start at [`PREDEFINED_SYMBOLS_COUNT`](rustc_span::symbol::PREDEFINED_SYMBOLS_COUNT)
pub extra_symbols: Vec<&'static str>,
/// This is a callback from the driver that is called to create a codegen backend.
///
/// Has no uses within this repository, but is used by bjorn3 for "the
@ -409,6 +413,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
&early_dcx,
config.opts.edition,
config.opts.unstable_opts.threads,
&config.extra_symbols,
SourceMapInputs { file_loader, path_mapping, hash_kind, checksum_hash_kind },
|current_gcx| {
// The previous `early_dcx` can't be reused here because it doesn't

View File

@ -53,7 +53,7 @@ where
checksum_hash_kind,
});
rustc_span::create_session_globals_then(DEFAULT_EDITION, sm_inputs, || {
rustc_span::create_session_globals_then(DEFAULT_EDITION, &[], sm_inputs, || {
let temps_dir = sessopts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
let io = CompilerIO {
input: Input::Str { name: FileName::Custom(String::new()), input: String::new() },

View File

@ -117,6 +117,7 @@ fn run_in_thread_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>(
thread_stack_size: usize,
edition: Edition,
sm_inputs: SourceMapInputs,
extra_symbols: &[&'static str],
f: F,
) -> R {
// The "thread pool" is a single spawned thread in the non-parallel
@ -134,9 +135,12 @@ fn run_in_thread_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>(
// name contains null bytes.
let r = builder
.spawn_scoped(s, move || {
rustc_span::create_session_globals_then(edition, Some(sm_inputs), || {
f(CurrentGcx::new())
})
rustc_span::create_session_globals_then(
edition,
extra_symbols,
Some(sm_inputs),
|| f(CurrentGcx::new()),
)
})
.unwrap()
.join();
@ -152,6 +156,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send,
thread_builder_diag: &EarlyDiagCtxt,
edition: Edition,
threads: usize,
extra_symbols: &[&'static str],
sm_inputs: SourceMapInputs,
f: F,
) -> R {
@ -168,12 +173,18 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send,
let registry = sync::Registry::new(std::num::NonZero::new(threads).unwrap());
if !sync::is_dyn_thread_safe() {
return run_in_thread_with_globals(thread_stack_size, edition, sm_inputs, |current_gcx| {
// Register the thread for use with the `WorkerLocal` type.
registry.register();
return run_in_thread_with_globals(
thread_stack_size,
edition,
sm_inputs,
extra_symbols,
|current_gcx| {
// Register the thread for use with the `WorkerLocal` type.
registry.register();
f(current_gcx)
});
f(current_gcx)
},
);
}
let current_gcx = FromDyn::from(CurrentGcx::new());
@ -230,7 +241,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send,
// pool. Upon creation, each worker thread created gets a copy of the
// session globals in TLS. This is possible because `SessionGlobals` impls
// `Send` in the parallel compiler.
rustc_span::create_session_globals_then(edition, Some(sm_inputs), || {
rustc_span::create_session_globals_then(edition, extra_symbols, Some(sm_inputs), || {
rustc_span::with_session_globals(|session_globals| {
let session_globals = FromDyn::from(session_globals);
builder

View File

@ -142,13 +142,13 @@ pub(super) fn symbols(input: TokenStream) -> TokenStream {
output
}
struct Preinterned {
struct Predefined {
idx: u32,
span_of_name: Span,
}
struct Entries {
map: HashMap<String, Preinterned>,
map: HashMap<String, Predefined>,
}
impl Entries {
@ -163,7 +163,7 @@ impl Entries {
prev.idx
} else {
let idx = self.len();
self.map.insert(s.to_string(), Preinterned { idx, span_of_name: span });
self.map.insert(s.to_string(), Predefined { idx, span_of_name: span });
idx
}
}
@ -295,10 +295,14 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
}
let symbol_digits_base = entries.map["0"].idx;
let preinterned_symbols_count = entries.len();
let predefined_symbols_count = entries.len();
let output = quote! {
const SYMBOL_DIGITS_BASE: u32 = #symbol_digits_base;
const PREINTERNED_SYMBOLS_COUNT: u32 = #preinterned_symbols_count;
/// The number of predefined symbols; this is the the first index for
/// extra pre-interned symbols in an Interner created via
/// [`Interner::with_extra_symbols`].
pub const PREDEFINED_SYMBOLS_COUNT: u32 = #predefined_symbols_count;
#[doc(hidden)]
#[allow(non_upper_case_globals)]
@ -315,10 +319,13 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
}
impl Interner {
pub(crate) fn fresh() -> Self {
Interner::prefill(&[
#prefill_stream
])
/// Creates an `Interner` with the predefined symbols from the `symbols!` macro and
/// any extra symbols provided by external drivers such as Clippy
pub(crate) fn with_extra_symbols(extra_symbols: &[&'static str]) -> Self {
Interner::prefill(
&[#prefill_stream],
extra_symbols,
)
}
}
};

View File

@ -562,9 +562,9 @@ impl<'a, 'tcx> SpanDecoder for DecodeContext<'a, 'tcx> {
Symbol::intern(s)
})
}
SYMBOL_PREINTERNED => {
SYMBOL_PREDEFINED => {
let symbol_index = self.read_u32();
Symbol::new_from_decoded(symbol_index)
Symbol::new(symbol_index)
}
_ => unreachable!(),
}

View File

@ -201,9 +201,9 @@ impl<'a, 'tcx> SpanEncoder for EncodeContext<'a, 'tcx> {
}
fn encode_symbol(&mut self, symbol: Symbol) {
// if symbol preinterned, emit tag and symbol index
if symbol.is_preinterned() {
self.opaque.emit_u8(SYMBOL_PREINTERNED);
// if symbol predefined, emit tag and symbol index
if symbol.is_predefined() {
self.opaque.emit_u8(SYMBOL_PREDEFINED);
self.opaque.emit_u32(symbol.as_u32());
} else {
// otherwise write it as string or as offset to it

View File

@ -586,7 +586,7 @@ impl SpanTag {
// Tags for encoding Symbol's
const SYMBOL_STR: u8 = 0;
const SYMBOL_OFFSET: u8 = 1;
const SYMBOL_PREINTERNED: u8 = 2;
const SYMBOL_PREDEFINED: u8 = 2;
pub fn provide(providers: &mut Providers) {
encoder::provide(providers);

View File

@ -46,7 +46,7 @@ const TAG_EXPN_DATA: u8 = 1;
// Tags for encoding Symbol's
const SYMBOL_STR: u8 = 0;
const SYMBOL_OFFSET: u8 = 1;
const SYMBOL_PREINTERNED: u8 = 2;
const SYMBOL_PREDEFINED: u8 = 2;
/// Provides an interface to incremental compilation data cached from the
/// previous compilation session. This data will eventually include the results
@ -674,9 +674,9 @@ impl<'a, 'tcx> SpanDecoder for CacheDecoder<'a, 'tcx> {
Symbol::intern(s)
})
}
SYMBOL_PREINTERNED => {
SYMBOL_PREDEFINED => {
let symbol_index = self.read_u32();
Symbol::new_from_decoded(symbol_index)
Symbol::new(symbol_index)
}
_ => unreachable!(),
}
@ -892,9 +892,9 @@ impl<'a, 'tcx> SpanEncoder for CacheEncoder<'a, 'tcx> {
// copy&paste impl from rustc_metadata
fn encode_symbol(&mut self, symbol: Symbol) {
// if symbol preinterned, emit tag and symbol index
if symbol.is_preinterned() {
self.encoder.emit_u8(SYMBOL_PREINTERNED);
// if symbol predefined, emit tag and symbol index
if symbol.is_predefined() {
self.encoder.emit_u8(SYMBOL_PREDEFINED);
self.encoder.emit_u32(symbol.as_u32());
} else {
// otherwise write it as string or as offset to it

View File

@ -98,10 +98,10 @@ impl AssocItem {
pub fn descr(&self) -> &'static str {
match self.kind {
ty::AssocKind::Const => "const",
ty::AssocKind::Const => "associated const",
ty::AssocKind::Fn if self.fn_has_self_parameter => "method",
ty::AssocKind::Fn => "associated function",
ty::AssocKind::Type => "type",
ty::AssocKind::Type => "associated type",
}
}
@ -155,6 +155,8 @@ impl AssocKind {
impl std::fmt::Display for AssocKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
// FIXME: fails to distinguish between "associated function" and
// "method" because `has_self` isn't known here.
AssocKind::Fn => write!(f, "method"),
AssocKind::Const => write!(f, "associated const"),
AssocKind::Type => write!(f, "associated type"),

View File

@ -116,9 +116,13 @@ pub struct SessionGlobals {
}
impl SessionGlobals {
pub fn new(edition: Edition, sm_inputs: Option<SourceMapInputs>) -> SessionGlobals {
pub fn new(
edition: Edition,
extra_symbols: &[&'static str],
sm_inputs: Option<SourceMapInputs>,
) -> SessionGlobals {
SessionGlobals {
symbol_interner: symbol::Interner::fresh(),
symbol_interner: symbol::Interner::with_extra_symbols(extra_symbols),
span_interner: Lock::new(span_encoding::SpanInterner::default()),
metavar_spans: Default::default(),
hygiene_data: Lock::new(hygiene::HygieneData::new(edition)),
@ -129,6 +133,7 @@ impl SessionGlobals {
pub fn create_session_globals_then<R>(
edition: Edition,
extra_symbols: &[&'static str],
sm_inputs: Option<SourceMapInputs>,
f: impl FnOnce() -> R,
) -> R {
@ -137,7 +142,7 @@ pub fn create_session_globals_then<R>(
"SESSION_GLOBALS should never be overwritten! \
Use another thread if you need another SessionGlobals"
);
let session_globals = SessionGlobals::new(edition, sm_inputs);
let session_globals = SessionGlobals::new(edition, extra_symbols, sm_inputs);
SESSION_GLOBALS.set(&session_globals, f)
}
@ -156,7 +161,7 @@ where
F: FnOnce(&SessionGlobals) -> R,
{
if !SESSION_GLOBALS.is_set() {
let session_globals = SessionGlobals::new(edition, None);
let session_globals = SessionGlobals::new(edition, &[], None);
SESSION_GLOBALS.set(&session_globals, || SESSION_GLOBALS.with(f))
} else {
SESSION_GLOBALS.with(f)
@ -172,7 +177,7 @@ where
/// Default edition, no source map.
pub fn create_default_session_globals_then<R>(f: impl FnOnce() -> R) -> R {
create_session_globals_then(edition::DEFAULT_EDITION, None, f)
create_session_globals_then(edition::DEFAULT_EDITION, &[], None, f)
}
// If this ever becomes non thread-local, `decode_syntax_context`

View File

@ -1913,6 +1913,7 @@ symbols! {
simd_eq,
simd_expose_provenance,
simd_extract,
simd_extract_dyn,
simd_fabs,
simd_fcos,
simd_fexp,
@ -1931,6 +1932,7 @@ symbols! {
simd_ge,
simd_gt,
simd_insert,
simd_insert_dyn,
simd_le,
simd_lt,
simd_masked_load,
@ -2538,15 +2540,10 @@ rustc_index::newtype_index! {
}
impl Symbol {
const fn new(n: u32) -> Self {
pub const fn new(n: u32) -> Self {
Symbol(SymbolIndex::from_u32(n))
}
/// for use in Decoder only
pub fn new_from_decoded(n: u32) -> Self {
Self::new(n)
}
/// Maps a string to its interned representation.
#[rustc_diagnostic_item = "SymbolIntern"]
pub fn intern(string: &str) -> Self {
@ -2632,11 +2629,14 @@ struct InternerInner {
}
impl Interner {
fn prefill(init: &[&'static str]) -> Self {
Interner(Lock::new(InternerInner {
arena: Default::default(),
strings: init.iter().copied().collect(),
}))
fn prefill(init: &[&'static str], extra: &[&'static str]) -> Self {
let strings = FxIndexSet::from_iter(init.iter().copied().chain(extra.iter().copied()));
assert_eq!(
strings.len(),
init.len() + extra.len(),
"`init` or `extra` contain duplicate symbols",
);
Interner(Lock::new(InternerInner { arena: Default::default(), strings }))
}
#[inline]
@ -2760,9 +2760,9 @@ impl Symbol {
self != kw::Empty && self != kw::Underscore && !self.is_path_segment_keyword()
}
/// Is this symbol was interned in compiler's `symbols!` macro
pub fn is_preinterned(self) -> bool {
self.as_u32() < PREINTERNED_SYMBOLS_COUNT
/// Was this symbol predefined in the compiler's `symbols!` macro
pub fn is_predefined(self) -> bool {
self.as_u32() < PREDEFINED_SYMBOLS_COUNT
}
}

View File

@ -3,7 +3,7 @@ use crate::create_default_session_globals_then;
#[test]
fn interner_tests() {
let i = Interner::prefill(&[]);
let i = Interner::prefill(&[], &[]);
// first one is zero:
assert_eq!(i.intern("dog"), Symbol::new(0));
// re-use gets the same entry:

View File

@ -3018,12 +3018,23 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
[] => span_bug!(ty.span, "trait object with no traits: {ty:?}"),
};
let needs_parens = traits.len() != 1;
err.span_suggestion_verbose(
span,
"you can use `impl Trait` as the argument type",
"impl ",
Applicability::MaybeIncorrect,
);
// Don't recommend impl Trait as a closure argument
if let Some(hir_id) = hir_id
&& matches!(
self.tcx.parent_hir_node(hir_id),
hir::Node::Item(hir::Item {
kind: hir::ItemKind::Fn { .. },
..
})
)
{
err.span_suggestion_verbose(
span,
"you can use `impl Trait` as the argument type",
"impl ",
Applicability::MaybeIncorrect,
);
}
let sugg = if !needs_parens {
vec![(span.shrink_to_lo(), format!("&{kw}"))]
} else {

View File

@ -13,9 +13,9 @@ use rustc_next_trait_solver::solve::{GenerateProofTree, SolverDelegateEvalExt as
use rustc_type_ir::solve::NoSolution;
use tracing::{instrument, trace};
use crate::solve::Certainty;
use crate::solve::delegate::SolverDelegate;
use crate::solve::inspect::{self, ProofTreeInferCtxtExt, ProofTreeVisitor};
use crate::solve::{Certainty, deeply_normalize_for_diagnostics};
use crate::traits::{FulfillmentError, FulfillmentErrorCode, wf};
pub(super) fn fulfillment_error_for_no_solution<'tcx>(
@ -151,7 +151,7 @@ fn find_best_leaf_obligation<'tcx>(
//
// We should probably fix the visitor to not do so instead, as this also
// means the leaf obligation may be incorrect.
infcx
let obligation = infcx
.fudge_inference_if_ok(|| {
infcx
.visit_proof_tree(
@ -161,7 +161,8 @@ fn find_best_leaf_obligation<'tcx>(
.break_value()
.ok_or(())
})
.unwrap_or(obligation)
.unwrap_or(obligation);
deeply_normalize_for_diagnostics(infcx, obligation.param_env, obligation)
}
struct BestObligation<'tcx> {
@ -298,7 +299,7 @@ impl<'tcx> BestObligation<'tcx> {
/// `NormalizesTo` goal, so we don't fall back to the rigid projection check
/// that should catch when a projection goal fails due to an unsatisfied trait
/// goal.
fn detect_error_in_higher_ranked_projection(
fn detect_trait_error_in_higher_ranked_projection(
&mut self,
goal: &inspect::InspectGoal<'_, 'tcx>,
) -> ControlFlow<PredicateObligation<'tcx>> {
@ -307,7 +308,13 @@ impl<'tcx> BestObligation<'tcx> {
&& !projection_clause.bound_vars().is_empty()
{
let pred = projection_clause.map_bound(|proj| proj.projection_term.trait_ref(tcx));
self.with_derived_obligation(self.obligation.with(tcx, pred), |this| {
let obligation = Obligation::new(
tcx,
self.obligation.cause.clone(),
goal.goal().param_env,
deeply_normalize_for_diagnostics(goal.infcx(), goal.goal().param_env, pred),
);
self.with_derived_obligation(obligation, |this| {
goal.infcx().visit_proof_tree_at_depth(
goal.goal().with(tcx, pred),
goal.depth() + 1,
@ -388,7 +395,8 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
(true, Ok(Certainty::Maybe(MaybeCause::Ambiguity))) | (false, Err(_)) => {}
_ => return ControlFlow::Continue(()),
}
let pred_kind = goal.goal().predicate.kind();
let pred = goal.goal().predicate;
let candidates = self.non_trivial_candidates(goal);
let candidate = match candidates.as_slice() {
@ -410,12 +418,12 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
// FIXME: Also, what about considering >1 layer up the stack? May be necessary
// for normalizes-to.
let child_mode = match pred_kind.skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
ChildMode::Trait(pred_kind.rebind(pred))
let child_mode = match pred.kind().skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) => {
ChildMode::Trait(pred.kind().rebind(trait_pred))
}
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(pred)) => {
ChildMode::Host(pred_kind.rebind(pred))
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(host_pred)) => {
ChildMode::Host(pred.kind().rebind(host_pred))
}
ty::PredicateKind::NormalizesTo(normalizes_to)
if matches!(
@ -423,7 +431,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst
) =>
{
ChildMode::Trait(pred_kind.rebind(ty::TraitPredicate {
ChildMode::Trait(pred.kind().rebind(ty::TraitPredicate {
trait_ref: normalizes_to.alias.trait_ref(tcx),
polarity: ty::PredicatePolarity::Positive,
}))
@ -457,10 +465,12 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
for nested_goal in nested_goals {
trace!(nested_goal = ?(nested_goal.goal(), nested_goal.source(), nested_goal.result()));
let nested_pred = nested_goal.goal().predicate;
let make_obligation = |cause| Obligation {
cause,
param_env: nested_goal.goal().param_env,
predicate: nested_goal.goal().predicate,
predicate: nested_pred,
recursion_depth: self.obligation.recursion_depth + 1,
};
@ -510,31 +520,20 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
// alias-relate may fail because the lhs or rhs can't be normalized,
// and therefore is treated as rigid.
if let Some(ty::PredicateKind::AliasRelate(lhs, rhs, _)) = pred_kind.no_bound_vars() {
if let Some(obligation) = goal
.infcx()
.visit_proof_tree_at_depth(
goal.goal().with(tcx, ty::ClauseKind::WellFormed(lhs.into())),
goal.depth() + 1,
self,
)
.break_value()
{
return ControlFlow::Break(obligation);
} else if let Some(obligation) = goal
.infcx()
.visit_proof_tree_at_depth(
goal.goal().with(tcx, ty::ClauseKind::WellFormed(rhs.into())),
goal.depth() + 1,
self,
)
.break_value()
{
return ControlFlow::Break(obligation);
}
if let Some(ty::PredicateKind::AliasRelate(lhs, rhs, _)) = pred.kind().no_bound_vars() {
goal.infcx().visit_proof_tree_at_depth(
goal.goal().with(tcx, ty::ClauseKind::WellFormed(lhs.into())),
goal.depth() + 1,
self,
)?;
goal.infcx().visit_proof_tree_at_depth(
goal.goal().with(tcx, ty::ClauseKind::WellFormed(rhs.into())),
goal.depth() + 1,
self,
)?;
}
self.detect_error_in_higher_ranked_projection(goal)?;
self.detect_trait_error_in_higher_ranked_projection(goal)?;
ControlFlow::Break(self.obligation.clone())
}

View File

@ -253,20 +253,28 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for DeeplyNormalizeForDiagnosticsFolder<'_,
}
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
deeply_normalize_with_skipped_universes(
self.at,
ty,
vec![None; ty.outer_exclusive_binder().as_usize()],
)
.unwrap_or_else(|_: Vec<ScrubbedTraitError<'tcx>>| ty.super_fold_with(self))
let infcx = self.at.infcx;
infcx
.commit_if_ok(|_| {
deeply_normalize_with_skipped_universes(
self.at,
ty,
vec![None; ty.outer_exclusive_binder().as_usize()],
)
})
.unwrap_or_else(|_: Vec<ScrubbedTraitError<'tcx>>| ty.super_fold_with(self))
}
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
deeply_normalize_with_skipped_universes(
self.at,
ct,
vec![None; ct.outer_exclusive_binder().as_usize()],
)
.unwrap_or_else(|_: Vec<ScrubbedTraitError<'tcx>>| ct.super_fold_with(self))
let infcx = self.at.infcx;
infcx
.commit_if_ok(|_| {
deeply_normalize_with_skipped_universes(
self.at,
ct,
vec![None; ct.outer_exclusive_binder().as_usize()],
)
})
.unwrap_or_else(|_: Vec<ScrubbedTraitError<'tcx>>| ct.super_fold_with(self))
}
}

View File

@ -67,9 +67,9 @@ dependencies = [
[[package]]
name = "compiler_builtins"
version = "0.1.152"
version = "0.1.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2153cf213eb259361567720ce55f6446f17acd0ccca87fb6dc05360578228a58"
checksum = "926ef6a360c15a911023352fd6969c51605d70495406f735beb1ca0257448e59"
dependencies = [
"cc",
"rustc-std-workspace-core",

View File

@ -16,7 +16,7 @@ bench = false
[dependencies]
core = { path = "../core", public = true }
compiler_builtins = { version = "=0.1.152", features = ['rustc-dep-of-std'] }
compiler_builtins = { version = "=0.1.153", features = ['rustc-dep-of-std'] }
[features]
compiler-builtins-mem = ['compiler_builtins/mem']

View File

@ -4,7 +4,7 @@
/// Inserts an element into a vector, returning the updated vector.
///
/// `T` must be a vector with element type `U`.
/// `T` must be a vector with element type `U`, and `idx` must be `const`.
///
/// # Safety
///
@ -15,14 +15,47 @@ pub const unsafe fn simd_insert<T, U>(x: T, idx: u32, val: U) -> T;
/// Extracts an element from a vector.
///
/// `T` must be a vector with element type `U`, and `idx` must be `const`.
///
/// # Safety
///
/// `idx` must be const and in-bounds of the vector.
#[rustc_intrinsic]
#[rustc_nounwind]
pub const unsafe fn simd_extract<T, U>(x: T, idx: u32) -> U;
/// Inserts an element into a vector, returning the updated vector.
///
/// `T` must be a vector with element type `U`.
///
/// If the index is `const`, [`simd_insert`] may emit better assembly.
///
/// # Safety
///
/// `idx` must be in-bounds of the vector.
#[rustc_intrinsic]
#[rustc_nounwind]
pub const unsafe fn simd_extract<T, U>(x: T, idx: u32) -> U;
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
pub unsafe fn simd_insert_dyn<T, U>(mut x: T, idx: u32, val: U) -> T {
// SAFETY: `idx` must be in-bounds
unsafe { (&raw mut x).cast::<U>().add(idx as usize).write(val) }
x
}
/// Extracts an element from a vector.
///
/// `T` must be a vector with element type `U`.
///
/// If the index is `const`, [`simd_extract`] may emit better assembly.
///
/// # Safety
///
/// `idx` must be in-bounds of the vector.
#[rustc_nounwind]
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
pub unsafe fn simd_extract_dyn<T, U>(x: T, idx: u32) -> U {
// SAFETY: `idx` must be in-bounds
unsafe { (&raw const x).cast::<U>().add(idx as usize).read() }
}
/// Adds two simd vectors elementwise.
///

View File

@ -36,7 +36,7 @@ where
///
/// The method does no guarding against overflows, so enumerating more than
/// `usize::MAX` elements either produces the wrong result or panics. If
/// debug assertions are enabled, a panic is guaranteed.
/// overflow checks are enabled, a panic is guaranteed.
///
/// # Panics
///

View File

@ -199,7 +199,7 @@ pub trait Iterator {
///
/// The method does no guarding against overflows, so counting elements of
/// an iterator with more than [`usize::MAX`] elements either produces the
/// wrong result or panics. If debug assertions are enabled, a panic is
/// wrong result or panics. If overflow checks are enabled, a panic is
/// guaranteed.
///
/// # Panics
@ -931,7 +931,7 @@ pub trait Iterator {
///
/// The method does no guarding against overflows, so enumerating more than
/// [`usize::MAX`] elements either produces the wrong result or panics. If
/// debug assertions are enabled, a panic is guaranteed.
/// overflow checks are enabled, a panic is guaranteed.
///
/// # Panics
///
@ -2964,7 +2964,7 @@ pub trait Iterator {
///
/// The method does no guarding against overflows, so if there are more
/// than [`usize::MAX`] non-matching elements, it either produces the wrong
/// result or panics. If debug assertions are enabled, a panic is
/// result or panics. If overflow checks are enabled, a panic is
/// guaranteed.
///
/// # Panics
@ -3516,7 +3516,7 @@ pub trait Iterator {
/// # Panics
///
/// When calling `sum()` and a primitive integer type is being returned, this
/// method will panic if the computation overflows and debug assertions are
/// method will panic if the computation overflows and overflow checks are
/// enabled.
///
/// # Examples
@ -3550,7 +3550,7 @@ pub trait Iterator {
/// # Panics
///
/// When calling `product()` and a primitive integer type is being returned,
/// method will panic if the computation overflows and debug assertions are
/// method will panic if the computation overflows and overflow checks are
/// enabled.
///
/// # Examples

View File

@ -18,7 +18,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
panic_unwind = { path = "../panic_unwind", optional = true }
panic_abort = { path = "../panic_abort" }
core = { path = "../core", public = true }
compiler_builtins = { version = "=0.1.152" }
compiler_builtins = { version = "=0.1.153" }
unwind = { path = "../unwind" }
hashbrown = { version = "0.15", default-features = false, features = [
'rustc-dep-of-std',

View File

@ -17,7 +17,7 @@ download-ci-llvm = false
[rust]
# We have several defaults in bootstrap that depend on whether the channel is `dev` (e.g. `omit-git-hash` and `download-ci-llvm`).
# Make sure they don't get set when installing from source.
channel = "nightly"
channel = "auto-detect"
# Never download a rustc, distributions must build a fresh compiler.
download-rustc = false
lld = true

View File

@ -1544,9 +1544,6 @@ impl Config {
}
}
let file_content = t!(fs::read_to_string(config.src.join("src/ci/channel")));
let ci_channel = file_content.trim_end();
// Give a hard error if `--config` or `RUST_BOOTSTRAP_CONFIG` are set to a missing path,
// but not if `bootstrap.toml` hasn't been created.
let mut toml = if !using_default_path || toml_path.exists() {
@ -1852,17 +1849,21 @@ impl Config {
let mut lld_enabled = None;
let mut std_features = None;
let is_user_configured_rust_channel =
if let Some(channel) = toml.rust.as_ref().and_then(|r| r.channel.clone()) {
if channel == "auto-detect" {
config.channel = ci_channel.into();
} else {
config.channel = channel;
}
let file_content = t!(fs::read_to_string(config.src.join("src/ci/channel")));
let ci_channel = file_content.trim_end();
let toml_channel = toml.rust.as_ref().and_then(|r| r.channel.clone());
let is_user_configured_rust_channel = match toml_channel {
Some(channel) if channel == "auto-detect" => {
config.channel = ci_channel.into();
true
} else {
false
};
}
Some(channel) => {
config.channel = channel;
true
}
None => false,
};
let default = config.channel == "dev";
config.omit_git_hash = toml.rust.as_ref().and_then(|r| r.omit_git_hash).unwrap_or(default);
@ -1887,6 +1888,10 @@ impl Config {
&& config.src.join(".cargo/config.toml").exists(),
);
if !is_user_configured_rust_channel && config.rust_info.is_from_tarball() {
config.channel = ci_channel.into();
}
if let Some(rust) = toml.rust {
let Rust {
optimize: optimize_toml,
@ -2090,8 +2095,6 @@ impl Config {
config.channel = channel;
}
} else if config.rust_info.is_from_tarball() && !is_user_configured_rust_channel {
ci_channel.clone_into(&mut config.channel);
}
if let Some(llvm) = toml.llvm {

View File

@ -191,8 +191,13 @@ settings:
specified atomic widths, e.g. the test with `//@ needs-target-has-atomic: 8,
16, ptr` will only run if it supports the comma-separated list of atomic
widths.
- `needs-dynamic-linking` - ignores if target does not support dynamic linking
- `needs-dynamic-linking` ignores if target does not support dynamic linking
(which is orthogonal to it being unable to create `dylib` and `cdylib` crate types)
- `needs-crate-type` — ignores if target platform does not support one or more
of the comma-delimited list of specified crate types. For example,
`//@ needs-crate-type: cdylib, proc-macro` will cause the test to be ignored
on `wasm32-unknown-unknown` target because the target does not support the
`proc-macro` crate type.
The following directives will check LLVM support:

View File

@ -321,6 +321,7 @@ pub(crate) fn create_config(
(rustc_interface::DEFAULT_QUERY_PROVIDERS.typeck)(tcx, def_id)
};
}),
extra_symbols: Vec::new(),
make_codegen_backend: None,
registry: rustc_driver::diagnostics_registry(),
ice_file: None,

View File

@ -191,6 +191,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions
hash_untracked_state: None,
register_lints: Some(Box::new(crate::lint::register_lints)),
override_queries: None,
extra_symbols: Vec::new(),
make_codegen_backend: None,
registry: rustc_driver::diagnostics_registry(),
ice_file: None,

View File

@ -25,6 +25,7 @@ path = "src/driver.rs"
[dependencies]
clippy_config = { path = "clippy_config" }
clippy_lints = { path = "clippy_lints" }
clippy_utils = { path = "clippy_utils" }
rustc_tools_util = { path = "rustc_tools_util", version = "0.4.2" }
tempfile = { version = "3.3", optional = true }
termize = "0.1"

View File

@ -1,10 +1,10 @@
use super::{Attribute, DEPRECATED_CFG_ATTR, DEPRECATED_CLIPPY_CFG_ATTR, unnecessary_clippy_cfg};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, MsrvStack};
use clippy_utils::sym;
use rustc_ast::AttrStyle;
use rustc_errors::Applicability;
use rustc_lint::EarlyContext;
use rustc_span::sym;
pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &MsrvStack) {
// check cfg_attr
@ -18,7 +18,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &MsrvStack) {
&& msrv.meets(msrvs::TOOL_ATTRIBUTES)
// check for `rustfmt_skip` and `rustfmt::skip`
&& let Some(skip_item) = &items[1].meta_item()
&& (skip_item.has_name(sym!(rustfmt_skip))
&& (skip_item.has_name(sym::rustfmt_skip)
|| skip_item
.path
.segments

View File

@ -2,10 +2,10 @@ use super::USELESS_ATTRIBUTE;
use super::utils::{is_lint_level, is_word, namespace_and_lint};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::{SpanRangeExt, first_line_of_span};
use clippy_utils::sym;
use rustc_ast::{Attribute, Item, ItemKind};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, LintContext};
use rustc_span::sym;
pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
let skip_unused_imports = attrs.iter().any(|attr| attr.has_name(sym::macro_use));
@ -61,7 +61,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
if is_word(lint, sym::unused_imports) && skip_unused_imports {
return;
}
if is_word(lint, sym!(unused_extern_crates)) {
if is_word(lint, sym::unused_extern_crates) {
return;
}
},

View File

@ -38,7 +38,7 @@ pub fn check(
// of all `#[test]` attributes in not ignored code examples
fn check_code_sample(code: String, edition: Edition, ignore: bool) -> (bool, Vec<Range<usize>>) {
rustc_driver::catch_fatal_errors(|| {
rustc_span::create_session_globals_then(edition, None, || {
rustc_span::create_session_globals_then(edition, &[], None, || {
let mut test_attr_spans = vec![];
let filename = FileName::anon_source_code(&code);

View File

@ -3,6 +3,7 @@
#![feature(f128)]
#![feature(f16)]
#![feature(if_let_guard)]
#![feature(macro_metavar_expr)]
#![feature(macro_metavar_expr_concat)]
#![feature(let_chains)]
#![feature(never_type)]
@ -74,6 +75,7 @@ pub mod qualify_min_const_fn;
pub mod source;
pub mod str_utils;
pub mod sugg;
pub mod sym;
pub mod ty;
pub mod usage;
pub mod visitors;
@ -126,7 +128,7 @@ use rustc_middle::ty::{
use rustc_span::hygiene::{ExpnKind, MacroKind};
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{Ident, Symbol, kw};
use rustc_span::{InnerSpan, Span, sym};
use rustc_span::{InnerSpan, Span};
use visitors::{Visitable, for_each_unconsumed_temporary};
use crate::consts::{ConstEvalCtxt, Constant, mir_to_const};

View File

@ -0,0 +1,23 @@
#![allow(non_upper_case_globals)]
use rustc_span::symbol::{Symbol, PREDEFINED_SYMBOLS_COUNT};
pub use rustc_span::sym::*;
macro_rules! generate {
($($sym:ident,)*) => {
/// To be supplied to `rustc_interface::Config`
pub const EXTRA_SYMBOLS: &[&str] = &[
$(stringify!($sym),)*
];
$(
pub const $sym: Symbol = Symbol::new(PREDEFINED_SYMBOLS_COUNT + ${index()});
)*
};
}
generate! {
rustfmt_skip,
unused_extern_crates,
}

View File

@ -160,6 +160,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
clippy_lints::register_lints(lint_store, conf);
clippy_lints::register_pre_expansion_lints(lint_store, conf);
}));
config.extra_symbols = clippy_utils::sym::EXTRA_SYMBOLS.into();
// FIXME: #4825; This is required, because Clippy lints that are based on MIR have to be
// run on the unoptimized MIR. On the other hand this results in some false negatives. If

View File

@ -395,6 +395,7 @@ pub struct Config {
pub target_cfgs: OnceLock<TargetCfgs>,
pub builtin_cfg_names: OnceLock<HashSet<String>>,
pub supported_crate_types: OnceLock<HashSet<String>>,
pub nocapture: bool,
@ -472,6 +473,11 @@ impl Config {
self.builtin_cfg_names.get_or_init(|| builtin_cfg_names(self))
}
/// Get the list of crate types that the target platform supports.
pub fn supported_crate_types(&self) -> &HashSet<String> {
self.supported_crate_types.get_or_init(|| supported_crate_types(self))
}
pub fn has_threads(&self) -> bool {
// Wasm targets don't have threads unless `-threads` is in the target
// name, such as `wasm32-wasip1-threads`.
@ -745,6 +751,31 @@ fn builtin_cfg_names(config: &Config) -> HashSet<String> {
.collect()
}
pub const KNOWN_CRATE_TYPES: &[&str] =
&["bin", "cdylib", "dylib", "lib", "proc-macro", "rlib", "staticlib"];
fn supported_crate_types(config: &Config) -> HashSet<String> {
let crate_types: HashSet<_> = rustc_output(
config,
&["--target", &config.target, "--print=supported-crate-types", "-Zunstable-options"],
Default::default(),
)
.lines()
.map(|l| l.to_string())
.collect();
for crate_type in crate_types.iter() {
assert!(
KNOWN_CRATE_TYPES.contains(&crate_type.as_str()),
"unexpected crate type `{}`: known crate types are {:?}",
crate_type,
KNOWN_CRATE_TYPES
);
}
crate_types
}
fn rustc_output(config: &Config, args: &[&str], envs: HashMap<String, String>) -> String {
let mut command = Command::new(&config.rustc_path);
add_dylib_path(&mut command, iter::once(&config.compile_lib_path));

View File

@ -133,6 +133,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
"min-llvm-version",
"min-system-llvm-version",
"needs-asm-support",
"needs-crate-type",
"needs-deterministic-layouts",
"needs-dlltool",
"needs-dynamic-linking",

View File

@ -1,4 +1,4 @@
use crate::common::{Config, KNOWN_TARGET_HAS_ATOMIC_WIDTHS, Sanitizer};
use crate::common::{Config, KNOWN_CRATE_TYPES, KNOWN_TARGET_HAS_ATOMIC_WIDTHS, Sanitizer};
use crate::header::{IgnoreDecision, llvm_has_libzstd};
pub(super) fn handle_needs(
@ -6,7 +6,7 @@ pub(super) fn handle_needs(
config: &Config,
ln: &str,
) -> IgnoreDecision {
// Note thet we intentionally still put the needs- prefix here to make the file show up when
// Note that we intentionally still put the needs- prefix here to make the file show up when
// grepping for a directive name, even though we could technically strip that.
let needs = &[
Need {
@ -224,6 +224,50 @@ pub(super) fn handle_needs(
}
}
// FIXME(jieyouxu): share multi-value directive logic with `needs-target-has-atomic` above.
if name == "needs-crate-type" {
let Some(rest) = rest else {
return IgnoreDecision::Error {
message:
"expected `needs-crate-type` to have a comma-separated list of crate types"
.to_string(),
};
};
// Expect directive value to be a list of comma-separated crate-types.
let specified_crate_types = rest
.split(',')
.map(|crate_type| crate_type.trim())
.map(ToString::to_string)
.collect::<Vec<String>>();
for crate_type in &specified_crate_types {
if !KNOWN_CRATE_TYPES.contains(&crate_type.as_str()) {
return IgnoreDecision::Error {
message: format!(
"unknown crate type specified in `needs-crate-type`: `{crate_type}` is not \
a known crate type, known values are `{:?}`",
KNOWN_CRATE_TYPES
),
};
}
}
let satisfies_all_crate_types = specified_crate_types
.iter()
.all(|specified| config.supported_crate_types().contains(specified));
if satisfies_all_crate_types {
return IgnoreDecision::Continue;
} else {
return IgnoreDecision::Ignore {
reason: format!(
"skipping test as target does not support all of the crate types `{:?}`",
specified_crate_types
),
};
}
}
if !name.starts_with("needs-") {
return IgnoreDecision::Continue;
}

View File

@ -902,3 +902,41 @@ fn test_rustc_abi() {
assert!(!check_ignore(&config, "//@ ignore-rustc_abi-x86-sse2"));
assert!(check_ignore(&config, "//@ only-rustc_abi-x86-sse2"));
}
#[test]
fn test_supported_crate_types() {
// Basic assumptions check on under-test compiler's `--print=supported-crate-types` output based
// on knowledge about the cherry-picked `x86_64-unknown-linux-gnu` and `wasm32-unknown-unknown`
// targets. Also smoke tests the `needs-crate-type` directive itself.
use std::collections::HashSet;
let config = cfg().target("x86_64-unknown-linux-gnu").build();
assert_eq!(
config.supported_crate_types().iter().map(String::as_str).collect::<HashSet<_>>(),
HashSet::from(["bin", "cdylib", "dylib", "lib", "proc-macro", "rlib", "staticlib"]),
);
assert!(!check_ignore(&config, "//@ needs-crate-type: rlib"));
assert!(!check_ignore(&config, "//@ needs-crate-type: dylib"));
assert!(!check_ignore(
&config,
"//@ needs-crate-type: bin, cdylib, dylib, lib, proc-macro, rlib, staticlib"
));
let config = cfg().target("wasm32-unknown-unknown").build();
assert_eq!(
config.supported_crate_types().iter().map(String::as_str).collect::<HashSet<_>>(),
HashSet::from(["bin", "cdylib", "lib", "rlib", "staticlib"]),
);
// rlib is supported
assert!(!check_ignore(&config, "//@ needs-crate-type: rlib"));
// dylib is not
assert!(check_ignore(&config, "//@ needs-crate-type: dylib"));
// If multiple crate types are specified, then all specified crate types need to be supported.
assert!(check_ignore(&config, "//@ needs-crate-type: cdylib, dylib"));
assert!(check_ignore(
&config,
"//@ needs-crate-type: bin, cdylib, dylib, lib, proc-macro, rlib, staticlib"
));
}

View File

@ -431,6 +431,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
target_cfgs: OnceLock::new(),
builtin_cfg_names: OnceLock::new(),
supported_crate_types: OnceLock::new(),
nocapture: matches.opt_present("no-capture"),

View File

@ -37,7 +37,8 @@ pub extern "C" fn second_f64(_: f64, x: f64) -> f64 {
}
// CHECK-LABEL: second_f128
// CHECK: movaps %xmm1, %xmm0
// FIXME(llvm21): this can be just %rdx instead of the regex once we don't test on LLVM 20
// CHECK: movaps {{(%xmm1|\(%rdx\))}}, %xmm0
// CHECK-NEXT: retq
#[no_mangle]
pub extern "C" fn second_f128(_: f128, x: f128) -> f128 {

View File

@ -0,0 +1,75 @@
//@compile-flags: -C opt-level=3 -C no-prepopulate-passes
#![feature(core_intrinsics, repr_simd)]
#![no_std]
#![crate_type = "lib"]
#![allow(non_camel_case_types)]
// Test that `core::intrinsics::simd::{simd_extract_dyn, simd_insert_dyn}`
// lower to an LLVM extractelement or insertelement operation.
use core::intrinsics::simd::{simd_extract, simd_extract_dyn, simd_insert, simd_insert_dyn};
#[repr(simd)]
#[derive(Clone, Copy)]
pub struct u32x16([u32; 16]);
#[repr(simd)]
#[derive(Clone, Copy)]
pub struct i8x16([i8; 16]);
// CHECK-LABEL: dyn_simd_extract
// CHECK: extractelement <16 x i8> %x, i32 %idx
#[no_mangle]
unsafe extern "C" fn dyn_simd_extract(x: i8x16, idx: u32) -> i8 {
simd_extract_dyn(x, idx)
}
// CHECK-LABEL: literal_dyn_simd_extract
// CHECK: extractelement <16 x i8> %x, i32 7
#[no_mangle]
unsafe extern "C" fn literal_dyn_simd_extract(x: i8x16) -> i8 {
simd_extract_dyn(x, 7)
}
// CHECK-LABEL: const_dyn_simd_extract
// CHECK: extractelement <16 x i8> %x, i32 7
#[no_mangle]
unsafe extern "C" fn const_dyn_simd_extract(x: i8x16) -> i8 {
simd_extract_dyn(x, const { 3 + 4 })
}
// CHECK-LABEL: const_simd_extract
// CHECK: extractelement <16 x i8> %x, i32 7
#[no_mangle]
unsafe extern "C" fn const_simd_extract(x: i8x16) -> i8 {
simd_extract(x, const { 3 + 4 })
}
// CHECK-LABEL: dyn_simd_insert
// CHECK: insertelement <16 x i8> %x, i8 %e, i32 %idx
#[no_mangle]
unsafe extern "C" fn dyn_simd_insert(x: i8x16, e: i8, idx: u32) -> i8x16 {
simd_insert_dyn(x, idx, e)
}
// CHECK-LABEL: literal_dyn_simd_insert
// CHECK: insertelement <16 x i8> %x, i8 %e, i32 7
#[no_mangle]
unsafe extern "C" fn literal_dyn_simd_insert(x: i8x16, e: i8) -> i8x16 {
simd_insert_dyn(x, 7, e)
}
// CHECK-LABEL: const_dyn_simd_insert
// CHECK: insertelement <16 x i8> %x, i8 %e, i32 7
#[no_mangle]
unsafe extern "C" fn const_dyn_simd_insert(x: i8x16, e: i8) -> i8x16 {
simd_insert_dyn(x, const { 3 + 4 }, e)
}
// CHECK-LABEL: const_simd_insert
// CHECK: insertelement <16 x i8> %x, i8 %e, i32 7
#[no_mangle]
unsafe extern "C" fn const_simd_insert(x: i8x16, e: i8) -> i8x16 {
simd_insert(x, const { 3 + 4 }, e)
}

View File

@ -70,6 +70,7 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf, linker: Option<&Path
hash_untracked_state: None,
register_lints: None,
override_queries: None,
extra_symbols: Vec::new(),
make_codegen_backend: None,
registry: rustc_driver::diagnostics_registry(),
using_internal_features: &rustc_driver::USING_INTERNAL_FEATURES,

View File

@ -0,0 +1,53 @@
error[E0658]: const arguments cannot yet be inferred with `_`
--> $DIR/parend_infer.rs:24:16
|
LL | let c: Foo<_> = Foo::<1>;
| ^
|
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: const arguments cannot yet be inferred with `_`
--> $DIR/parend_infer.rs:26:16
|
LL | let c: Foo<(_)> = Foo::<1>;
| ^^^
|
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: const arguments cannot yet be inferred with `_`
--> $DIR/parend_infer.rs:28:16
|
LL | let c: Foo<(((_)))> = Foo::<1>;
| ^^^^^^^
|
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: using `_` for array lengths is unstable
--> $DIR/parend_infer.rs:17:17
|
LL | let b: [u8; (_)] = [1; (((((_)))))];
| ^^^
|
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: using `_` for array lengths is unstable
--> $DIR/parend_infer.rs:17:28
|
LL | let b: [u8; (_)] = [1; (((((_)))))];
| ^^^^^^^^^^^
|
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@ -1,7 +1,9 @@
//@ check-pass
//@[gate] check-pass
//@ revisions: gate nogate
#![cfg_attr(gate, feature(generic_arg_infer))]
struct Foo<const N: usize>;
fn main() {
// AST Types preserve parens for pretty printing reasons. This means
// that this is parsed as a `TyKind::Paren(TyKind::Infer)`. Generic
@ -9,4 +11,20 @@ fn main() {
// but `TyKind::Infer` wrapped in arbitrarily many `TyKind::Paren`.
let a: Vec<(_)> = vec![1_u8];
let a: Vec<(((((_)))))> = vec![1_u8];
// AST Exprs similarly preserve parens for pretty printing reasons.
#[rustfmt::skip]
let b: [u8; (_)] = [1; (((((_)))))];
//[nogate]~^ error: using `_` for array lengths is unstable
//[nogate]~| error: using `_` for array lengths is unstable
let b: [u8; 2] = b;
// This is the same case as AST types as the parser doesn't distinguish between const
// and type args when they share syntax
let c: Foo<_> = Foo::<1>;
//[nogate]~^ error: const arguments cannot yet be inferred with `_`
let c: Foo<(_)> = Foo::<1>;
//[nogate]~^ error: const arguments cannot yet be inferred with `_`
let c: Foo<(((_)))> = Foo::<1>;
//[nogate]~^ error: const arguments cannot yet be inferred with `_`
}

View File

@ -16,7 +16,7 @@ impl Bar for Foo<'_> {
const STATIC: &str = "";
//~^ ERROR `&` without an explicit lifetime name cannot be used here
//~| WARN this was previously accepted by the compiler but is being phased out
//~| ERROR lifetime parameters or bounds on const `STATIC` do not match the trait declaration
//~| ERROR lifetime parameters or bounds on associated const `STATIC` do not match the trait declaration
}
fn main() {}

View File

@ -39,14 +39,14 @@ help: use the `'static` lifetime
LL | const STATIC: &'static str = "";
| +++++++
error[E0195]: lifetime parameters or bounds on const `STATIC` do not match the trait declaration
error[E0195]: lifetime parameters or bounds on associated const `STATIC` do not match the trait declaration
--> $DIR/elided-lifetime.rs:16:17
|
LL | const STATIC: &str;
| - lifetimes in impl do not match this const in trait
| - lifetimes in impl do not match this associated const in trait
...
LL | const STATIC: &str = "";
| ^ lifetimes do not match const in trait
| ^ lifetimes do not match associated const in trait
error: aborting due to 3 previous errors

View File

@ -9,7 +9,7 @@ impl Bar<'_> for A {
const STATIC: &str = "";
//~^ ERROR `&` without an explicit lifetime name cannot be used here
//~| WARN this was previously accepted by the compiler but is being phased out
//~| ERROR lifetime parameters or bounds on const `STATIC` do not match the trait declaration
//~| ERROR lifetime parameters or bounds on associated const `STATIC` do not match the trait declaration
}
struct B;

View File

@ -21,14 +21,14 @@ help: use the `'static` lifetime
LL | const STATIC: &'static str = "";
| +++++++
error[E0195]: lifetime parameters or bounds on const `STATIC` do not match the trait declaration
error[E0195]: lifetime parameters or bounds on associated const `STATIC` do not match the trait declaration
--> $DIR/static-trait-impl.rs:9:17
|
LL | const STATIC: &'a str;
| - lifetimes in impl do not match this const in trait
| - lifetimes in impl do not match this associated const in trait
...
LL | const STATIC: &str = "";
| ^ lifetimes do not match const in trait
| ^ lifetimes do not match associated const in trait
error: aborting due to 2 previous errors

View File

@ -1,12 +1,14 @@
error[E0277]: the trait bound `&str: AsExpression<<SelectInt as Expression>::SqlType>` is not satisfied
error[E0277]: the trait bound `&str: AsExpression<Integer>` is not satisfied
--> $DIR/as_expression.rs:56:21
|
LL | SelectInt.check("bar");
| ----- ^^^^^ the trait `AsExpression<<SelectInt as Expression>::SqlType>` is not implemented for `&str`
| ----- ^^^^^ the trait `AsExpression<Integer>` is not implemented for `&str`
| |
| required by a bound introduced by this call
|
= help: the trait `AsExpression<Text>` is implemented for `&str`
= help: the trait `AsExpression<Integer>` is not implemented for `&str`
but trait `AsExpression<Text>` is implemented for it
= help: for that trait implementation, expected `Text`, found `Integer`
note: required by a bound in `Foo::check`
--> $DIR/as_expression.rs:47:12
|
@ -16,11 +18,11 @@ LL | where
LL | T: AsExpression<Self::SqlType>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::check`
error[E0271]: type mismatch resolving `<SelectInt as Expression>::SqlType == Text`
error[E0271]: type mismatch resolving `Integer == Text`
--> $DIR/as_expression.rs:56:5
|
LL | SelectInt.check("bar");
| ^^^^^^^^^^^^^^^^^^^^^^ expected `Text`, found `Integer`
| ^^^^^^^^^^^^^^^^^^^^^^ types differ
error: aborting due to 2 previous errors

View File

@ -54,7 +54,6 @@ impl<T> Foo for T where T: Expression {}
fn main() {
SelectInt.check("bar");
//[current]~^ ERROR the trait bound `&str: AsExpression<Integer>` is not satisfied
//[next]~^^ ERROR the trait bound `&str: AsExpression<<SelectInt as Expression>::SqlType>` is not satisfied
//~^ ERROR the trait bound `&str: AsExpression<Integer>` is not satisfied
//[next]~| ERROR type mismatch
}

View File

@ -1,4 +1,4 @@
error[E0053]: type `Foo` has an incompatible generic parameter for trait `Trait`
error[E0053]: associated type `Foo` has an incompatible generic parameter for trait `Trait`
--> $DIR/const_params_have_right_type.rs:6:14
|
LL | trait Trait {

View File

@ -1,4 +1,4 @@
error[E0049]: type `B` has 1 type parameter but its trait declaration has 0 type parameters
error[E0049]: associated type `B` has 1 type parameter but its trait declaration has 0 type parameters
--> $DIR/issue-102114.rs:15:12
|
LL | type B<'b>;

View File

@ -1,4 +1,4 @@
error[E0049]: type `B` has 1 type parameter but its trait declaration has 0 type parameters
error[E0049]: associated type `B` has 1 type parameter but its trait declaration has 0 type parameters
--> $DIR/issue-102114.rs:15:12
|
LL | type B<'b>;

View File

@ -12,11 +12,11 @@ struct Fooy;
impl Foo for Fooy {
type A = u32;
//~^ ERROR lifetime parameters or bounds on type `A` do not match the trait declaration
//~^ ERROR lifetime parameters or bounds on associated type `A` do not match the trait declaration
type B<'a, T> = Vec<T>;
//~^ ERROR type `B` has 1 type parameter but its trait declaration has 0 type parameters
type C<'a> = u32;
//~^ ERROR lifetime parameters or bounds on type `C` do not match the trait declaration
//~^ ERROR lifetime parameters or bounds on associated type `C` do not match the trait declaration
}
struct Fooer;
@ -25,7 +25,7 @@ impl Foo for Fooer {
type A<T> = u32;
//~^ ERROR type `A` has 1 type parameter but its trait declaration has 0 type parameters
type B<'a> = u32;
//~^ ERROR lifetime parameters or bounds on type `B` do not match the trait declaration
//~^ ERROR lifetime parameters or bounds on associated type `B` do not match the trait declaration
type C<T> = T;
//~^ ERROR type `C` has 1 type parameter but its trait declaration has 0 type parameters
}

View File

@ -1,13 +1,13 @@
error[E0195]: lifetime parameters or bounds on type `A` do not match the trait declaration
error[E0195]: lifetime parameters or bounds on associated type `A` do not match the trait declaration
--> $DIR/parameter_number_and_kind_impl.rs:14:11
|
LL | type A<'a>;
| ---- lifetimes in impl do not match this type in trait
| ---- lifetimes in impl do not match this associated type in trait
...
LL | type A = u32;
| ^ lifetimes do not match type in trait
| ^ lifetimes do not match associated type in trait
error[E0049]: type `B` has 1 type parameter but its trait declaration has 0 type parameters
error[E0049]: associated type `B` has 1 type parameter but its trait declaration has 0 type parameters
--> $DIR/parameter_number_and_kind_impl.rs:16:12
|
LL | type B<'a, 'b>;
@ -20,16 +20,16 @@ LL | type B<'a, T> = Vec<T>;
| |
| found 1 type parameter
error[E0195]: lifetime parameters or bounds on type `C` do not match the trait declaration
error[E0195]: lifetime parameters or bounds on associated type `C` do not match the trait declaration
--> $DIR/parameter_number_and_kind_impl.rs:18:11
|
LL | type C;
| - lifetimes in impl do not match this type in trait
| - lifetimes in impl do not match this associated type in trait
...
LL | type C<'a> = u32;
| ^^^^ lifetimes do not match type in trait
| ^^^^ lifetimes do not match associated type in trait
error[E0049]: type `A` has 1 type parameter but its trait declaration has 0 type parameters
error[E0049]: associated type `A` has 1 type parameter but its trait declaration has 0 type parameters
--> $DIR/parameter_number_and_kind_impl.rs:25:12
|
LL | type A<'a>;
@ -38,16 +38,16 @@ LL | type A<'a>;
LL | type A<T> = u32;
| ^ found 1 type parameter
error[E0195]: lifetime parameters or bounds on type `B` do not match the trait declaration
error[E0195]: lifetime parameters or bounds on associated type `B` do not match the trait declaration
--> $DIR/parameter_number_and_kind_impl.rs:27:11
|
LL | type B<'a, 'b>;
| -------- lifetimes in impl do not match this type in trait
| -------- lifetimes in impl do not match this associated type in trait
...
LL | type B<'a> = u32;
| ^^^^ lifetimes do not match type in trait
| ^^^^ lifetimes do not match associated type in trait
error[E0049]: type `C` has 1 type parameter but its trait declaration has 0 type parameters
error[E0049]: associated type `C` has 1 type parameter but its trait declaration has 0 type parameters
--> $DIR/parameter_number_and_kind_impl.rs:29:12
|
LL | type C;

View File

@ -14,7 +14,7 @@ impl Trait for () {
//~| ERROR mismatched types
const Q = "";
//~^ ERROR missing type for `const` item
//~| ERROR lifetime parameters or bounds on const `Q` do not match the trait declaration
//~| ERROR lifetime parameters or bounds on associated const `Q` do not match the trait declaration
}
fn main() {}

View File

@ -15,14 +15,14 @@ error: missing type for `const` item
LL | const K<T> = ();
| ^ help: provide a type for the associated constant: `()`
error[E0195]: lifetime parameters or bounds on const `Q` do not match the trait declaration
error[E0195]: lifetime parameters or bounds on associated const `Q` do not match the trait declaration
--> $DIR/assoc-const-missing-type.rs:15:12
|
LL | const Q<'a>: &'a str;
| ---- lifetimes in impl do not match this const in trait
| ---- lifetimes in impl do not match this associated const in trait
...
LL | const Q = "";
| ^ lifetimes do not match const in trait
| ^ lifetimes do not match associated const in trait
error: missing type for `const` item
--> $DIR/assoc-const-missing-type.rs:15:12

View File

@ -22,7 +22,7 @@ impl<P> Trait<P> for () {
const D<const N: u16>: u16 = N;
//~^ ERROR const `D` has an incompatible generic parameter for trait `Trait`
const E: &'static () = &();
//~^ ERROR lifetime parameters or bounds on const `E` do not match the trait declaration
//~^ ERROR lifetime parameters or bounds on associated const `E` do not match the trait declaration
const F: usize = 1024
where

View File

@ -1,4 +1,4 @@
error[E0049]: const `A` has 1 type parameter but its trait declaration has 0 type parameters
error[E0049]: associated const `A` has 1 type parameter but its trait declaration has 0 type parameters
--> $DIR/compare-impl-item.rs:16:13
|
LL | const A: ();
@ -7,7 +7,7 @@ LL | const A: ();
LL | const A<T>: () = ();
| ^ found 1 type parameter
error[E0049]: const `B` has 1 const parameter but its trait declaration has 2 const parameters
error[E0049]: associated const `B` has 1 const parameter but its trait declaration has 2 const parameters
--> $DIR/compare-impl-item.rs:18:13
|
LL | const B<const K: u64, const Q: u64>: u64;
@ -18,7 +18,7 @@ LL | const B<const K: u64, const Q: u64>: u64;
LL | const B<const K: u64>: u64 = 0;
| ^^^^^^^^^^^^ found 1 const parameter
error[E0049]: const `C` has 0 type parameters but its trait declaration has 1 type parameter
error[E0049]: associated const `C` has 0 type parameters but its trait declaration has 1 type parameter
--> $DIR/compare-impl-item.rs:20:13
|
LL | const C<T>: T;
@ -27,7 +27,7 @@ LL | const C<T>: T;
LL | const C<'a>: &'a str = "";
| ^^ found 0 type parameters
error[E0053]: const `D` has an incompatible generic parameter for trait `Trait`
error[E0053]: associated const `D` has an incompatible generic parameter for trait `Trait`
--> $DIR/compare-impl-item.rs:22:13
|
LL | trait Trait<P> {
@ -42,14 +42,14 @@ LL | impl<P> Trait<P> for () {
LL | const D<const N: u16>: u16 = N;
| ^^^^^^^^^^^^ found const parameter of type `u16`
error[E0195]: lifetime parameters or bounds on const `E` do not match the trait declaration
error[E0195]: lifetime parameters or bounds on associated const `E` do not match the trait declaration
--> $DIR/compare-impl-item.rs:24:12
|
LL | const E<'a>: &'a ();
| ---- lifetimes in impl do not match this const in trait
| ---- lifetimes in impl do not match this associated const in trait
...
LL | const E: &'static () = &();
| ^ lifetimes do not match const in trait
| ^ lifetimes do not match associated const in trait
error[E0276]: impl has stricter requirements than trait
--> $DIR/compare-impl-item.rs:29:12

View File

@ -4,7 +4,7 @@ error[E0407]: method `line_stream` is not a member of trait `X`
LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `X`
error[E0049]: type `LineStream` has 0 type parameters but its trait declaration has 1 type parameter
error[E0049]: associated type `LineStream` has 0 type parameters but its trait declaration has 1 type parameter
--> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:25:21
|
LL | type LineStream<'a, Repr>

View File

@ -4,7 +4,7 @@ error[E0407]: method `line_stream` is not a member of trait `X`
LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `X`
error[E0049]: type `LineStream` has 0 type parameters but its trait declaration has 1 type parameter
error[E0049]: associated type `LineStream` has 0 type parameters but its trait declaration has 1 type parameter
--> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:25:21
|
LL | type LineStream<'a, Repr>

View File

@ -8,7 +8,7 @@ pub trait Iterable {
impl<'a, I: 'a + Iterable> Iterable for &'a I {
type Item = u32;
//~^ ERROR lifetime parameters or bounds on type `Item` do not match the trait declaration
//~^ ERROR lifetime parameters or bounds on associated type `Item` do not match the trait declaration
fn iter(&self) -> impl for<'missing> Iterator<Item = Self::Item<'missing>> {}
//~^ ERROR binding for associated type `Item` references lifetime `'missing`

View File

@ -12,17 +12,17 @@ LL | fn iter(&self) -> impl for<'missing> Iterator<Item = Self::Item<'missin
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0195]: lifetime parameters or bounds on type `Item` do not match the trait declaration
error[E0195]: lifetime parameters or bounds on associated type `Item` do not match the trait declaration
--> $DIR/span-bug-issue-121457.rs:10:14
|
LL | type Item<'a>
| ---- lifetimes in impl do not match this type in trait
| ---- lifetimes in impl do not match this associated type in trait
LL | where
LL | Self: 'a;
| -- this bound might be missing in the impl
...
LL | type Item = u32;
| ^ lifetimes do not match type in trait
| ^ lifetimes do not match associated type in trait
error[E0277]: `()` is not an iterator
--> $DIR/span-bug-issue-121457.rs:13:23

View File

@ -3,8 +3,6 @@
//!
//! This test does not try to check if the output artifacts are valid.
// FIXME(#132309): add a proper `supports-crate-type` directive.
// Single valid crate types should pass
//@ revisions: lib rlib staticlib dylib cdylib bin proc_dash_macro
@ -17,19 +15,18 @@
//@[staticlib] compile-flags: --crate-type=staticlib
//@[staticlib] check-pass
//@[dylib] ignore-musl (dylib is supported, but musl libc is statically linked by default)
//@[dylib] ignore-wasm (dylib is not supported)
//@[dylib] needs-crate-type: dylib
//@[dylib] compile-flags: --crate-type=dylib
//@[dylib] check-pass
//@[cdylib] ignore-musl (cdylib is supported, but musl libc is statically linked by default)
//@[cdylib] needs-crate-type: cdylib
//@[cdylib] compile-flags: --crate-type=cdylib
//@[cdylib] check-pass
//@[bin] compile-flags: --crate-type=bin
//@[bin] check-pass
//@[proc_dash_macro] ignore-wasm (proc-macro is not supported)
//@[proc_dash_macro] needs-crate-type: proc-macro
//@[proc_dash_macro] needs-unwind (panic=abort causes warning to be emitted)
//@[proc_dash_macro] compile-flags: --crate-type=proc-macro
//@[proc_dash_macro] check-pass

View File

@ -25,7 +25,7 @@ impl Bar for usize {
impl Bar for isize {
type Item<'a> = &'a isize;
//~^ ERROR 27:14: 27:18: lifetime parameters or bounds on type `Item` do not match the trait declaration [E0195]
//~^ ERROR 27:14: 27:18: lifetime parameters or bounds on associated type `Item` do not match the trait declaration [E0195]
fn poke(&mut self, item: Self::Item) {
self += *item;

View File

@ -16,14 +16,14 @@ error: in the trait associated type is declared without lifetime parameters, so
LL | type Item = &usize;
| ^ this lifetime must come from the implemented type
error[E0195]: lifetime parameters or bounds on type `Item` do not match the trait declaration
error[E0195]: lifetime parameters or bounds on associated type `Item` do not match the trait declaration
--> $DIR/no_lending_iterators.rs:27:14
|
LL | type Item;
| - lifetimes in impl do not match this type in trait
| - lifetimes in impl do not match this associated type in trait
...
LL | type Item<'a> = &'a isize;
| ^^^^ lifetimes do not match type in trait
| ^^^^ lifetimes do not match associated type in trait
error: aborting due to 3 previous errors

View File

@ -2,8 +2,7 @@
//@ aux-build:issue-12133-rlib.rs
//@ aux-build:issue-12133-dylib.rs
//@ aux-build:issue-12133-dylib2.rs
//@ ignore-wasm32 no dylib support
//@ ignore-musl
//@ needs-crate-type: dylib
//@ needs-dynamic-linking

View File

@ -1,11 +1,11 @@
error: crate `NonSnakeCase` should have a snake case name
--> $DIR/lint-non-snake-case-crate.rs:36:18
--> $DIR/lint-non-snake-case-crate.rs:35:18
|
LL | #![crate_name = "NonSnakeCase"]
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
|
note: the lint level is defined here
--> $DIR/lint-non-snake-case-crate.rs:38:9
--> $DIR/lint-non-snake-case-crate.rs:37:9
|
LL | #![deny(non_snake_case)]
| ^^^^^^^^^^^^^^

View File

@ -1,11 +1,11 @@
error: crate `NonSnakeCase` should have a snake case name
--> $DIR/lint-non-snake-case-crate.rs:36:18
--> $DIR/lint-non-snake-case-crate.rs:35:18
|
LL | #![crate_name = "NonSnakeCase"]
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
|
note: the lint level is defined here
--> $DIR/lint-non-snake-case-crate.rs:38:9
--> $DIR/lint-non-snake-case-crate.rs:37:9
|
LL | #![deny(non_snake_case)]
| ^^^^^^^^^^^^^^

View File

@ -1,11 +1,11 @@
error: crate `NonSnakeCase` should have a snake case name
--> $DIR/lint-non-snake-case-crate.rs:36:18
--> $DIR/lint-non-snake-case-crate.rs:35:18
|
LL | #![crate_name = "NonSnakeCase"]
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
|
note: the lint level is defined here
--> $DIR/lint-non-snake-case-crate.rs:38:9
--> $DIR/lint-non-snake-case-crate.rs:37:9
|
LL | #![deny(non_snake_case)]
| ^^^^^^^^^^^^^^

View File

@ -1,11 +1,11 @@
error: crate `NonSnakeCase` should have a snake case name
--> $DIR/lint-non-snake-case-crate.rs:36:18
--> $DIR/lint-non-snake-case-crate.rs:35:18
|
LL | #![crate_name = "NonSnakeCase"]
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
|
note: the lint level is defined here
--> $DIR/lint-non-snake-case-crate.rs:38:9
--> $DIR/lint-non-snake-case-crate.rs:37:9
|
LL | #![deny(non_snake_case)]
| ^^^^^^^^^^^^^^

View File

@ -1,11 +1,11 @@
error: crate `NonSnakeCase` should have a snake case name
--> $DIR/lint-non-snake-case-crate.rs:36:18
--> $DIR/lint-non-snake-case-crate.rs:35:18
|
LL | #![crate_name = "NonSnakeCase"]
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
|
note: the lint level is defined here
--> $DIR/lint-non-snake-case-crate.rs:38:9
--> $DIR/lint-non-snake-case-crate.rs:37:9
|
LL | #![deny(non_snake_case)]
| ^^^^^^^^^^^^^^

View File

@ -10,28 +10,27 @@
// But should fire on non-binary crates.
// FIXME(#132309): dylib crate type is not supported on wasm; we need a proper
// supports-crate-type directive. Also, needs-dynamic-linking should rule out
// musl since it supports neither dylibs nor cdylibs.
//@[dylib_] ignore-wasm
//@[dylib_] ignore-musl
//@[cdylib_] ignore-musl
//@[dylib_] needs-dynamic-linking
//@[cdylib_] compile-flags: --crate-type=cdylib
//@[cdylib_] needs-dynamic-linking
//@[cdylib_] needs-crate-type: cdylib
//@[dylib_] compile-flags: --crate-type=dylib
//@[dylib_] needs-dynamic-linking
//@[dylib_] needs-crate-type: dylib
//@[lib_] compile-flags: --crate-type=lib
//@[proc_macro_] force-host
//@[proc_macro_] no-prefer-dynamic
//@[cdylib_] compile-flags: --crate-type=cdylib
//@[dylib_] compile-flags: --crate-type=dylib
//@[lib_] compile-flags: --crate-type=lib
//@[proc_macro_] compile-flags: --crate-type=proc-macro
//@[rlib_] compile-flags: --crate-type=rlib
//@[staticlib_] compile-flags: --crate-type=staticlib
// The compiler may emit a warning that causes stderr output
// that contains a warning this test does not wish to check.
// The compiler may emit a warning that causes stderr output that contains a warning this test does
// not wish to check.
//@[proc_macro_] needs-unwind
//@[proc_macro_] needs-crate-type: proc-macro
//@[rlib_] compile-flags: --crate-type=rlib
//@[staticlib_] compile-flags: --crate-type=staticlib
#![crate_name = "NonSnakeCase"]
//[cdylib_,dylib_,lib_,proc_macro_,rlib_,staticlib_]~^ ERROR crate `NonSnakeCase` should have a snake case name

View File

@ -1,11 +1,11 @@
error: crate `NonSnakeCase` should have a snake case name
--> $DIR/lint-non-snake-case-crate.rs:36:18
--> $DIR/lint-non-snake-case-crate.rs:35:18
|
LL | #![crate_name = "NonSnakeCase"]
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
|
note: the lint level is defined here
--> $DIR/lint-non-snake-case-crate.rs:38:9
--> $DIR/lint-non-snake-case-crate.rs:37:9
|
LL | #![deny(non_snake_case)]
| ^^^^^^^^^^^^^^

View File

@ -0,0 +1,41 @@
//! Check that `no_std` binaries can link and run without depending on `libstd`.
//@ run-pass
//@ compile-flags: -Cpanic=abort
//@ ignore-wasm different `main` convention
#![no_std]
#![no_main]
use core::ffi::{c_char, c_int};
use core::panic::PanicInfo;
// # Linux
//
// Linking `libc` is required by crt1.o, otherwise the linker fails with:
// > /usr/bin/ld: in function `_start': undefined reference to `__libc_start_main'
//
// # Apple
//
// Linking `libSystem` is required, otherwise the linker fails with:
// > ld: dynamic executables or dylibs must link with libSystem.dylib
//
// With the new linker introduced in Xcode 15, the error is instead:
// > Undefined symbols: "dyld_stub_binder", referenced from: <initial-undefines>
//
// This _can_ be worked around by raising the deployment target with
// MACOSX_DEPLOYMENT_TARGET=13.0, though it's a bit hard to test that while
// still allowing the test suite to support running with older Xcode versions.
#[cfg_attr(all(not(target_vendor = "apple"), unix), link(name = "c"))]
#[cfg_attr(target_vendor = "apple", link(name = "System"))]
extern "C" {}
#[panic_handler]
fn panic_handler(_info: &PanicInfo<'_>) -> ! {
loop {}
}
#[no_mangle]
extern "C" fn main(_argc: c_int, _argv: *const *const c_char) -> c_int {
0
}

View File

@ -1,9 +1,7 @@
//@ build-fail
//@ compile-flags:-C panic=abort -C prefer-dynamic
//@ needs-unwind
//@ ignore-musl - no dylibs here
//@ ignore-emscripten
//@ ignore-sgx no dynamic lib support
//@ needs-crate-type: dylib
// This is a test where the local crate, compiled with `panic=abort`, links to
// the standard library **dynamically** which is already linked against

View File

@ -1,8 +1,10 @@
//@ run-pass
#![feature(repr_simd, core_intrinsics)]
#![feature(repr_simd, intrinsics, core_intrinsics)]
use std::intrinsics::simd::{simd_extract, simd_insert, simd_shuffle};
use std::intrinsics::simd::{
simd_extract, simd_extract_dyn, simd_insert, simd_insert_dyn, simd_shuffle,
};
#[repr(simd)]
#[derive(Copy, Clone, Debug, PartialEq)]
@ -70,6 +72,41 @@ fn main() {
all_eq!(simd_extract(x8, 6), 86);
all_eq!(simd_extract(x8, 7), 87);
}
unsafe {
all_eq!(simd_insert_dyn(x2, 0, 100), i32x2([100, 21]));
all_eq!(simd_insert_dyn(x2, 1, 100), i32x2([20, 100]));
all_eq!(simd_insert_dyn(x4, 0, 100), i32x4([100, 41, 42, 43]));
all_eq!(simd_insert_dyn(x4, 1, 100), i32x4([40, 100, 42, 43]));
all_eq!(simd_insert_dyn(x4, 2, 100), i32x4([40, 41, 100, 43]));
all_eq!(simd_insert_dyn(x4, 3, 100), i32x4([40, 41, 42, 100]));
all_eq!(simd_insert_dyn(x8, 0, 100), i32x8([100, 81, 82, 83, 84, 85, 86, 87]));
all_eq!(simd_insert_dyn(x8, 1, 100), i32x8([80, 100, 82, 83, 84, 85, 86, 87]));
all_eq!(simd_insert_dyn(x8, 2, 100), i32x8([80, 81, 100, 83, 84, 85, 86, 87]));
all_eq!(simd_insert_dyn(x8, 3, 100), i32x8([80, 81, 82, 100, 84, 85, 86, 87]));
all_eq!(simd_insert_dyn(x8, 4, 100), i32x8([80, 81, 82, 83, 100, 85, 86, 87]));
all_eq!(simd_insert_dyn(x8, 5, 100), i32x8([80, 81, 82, 83, 84, 100, 86, 87]));
all_eq!(simd_insert_dyn(x8, 6, 100), i32x8([80, 81, 82, 83, 84, 85, 100, 87]));
all_eq!(simd_insert_dyn(x8, 7, 100), i32x8([80, 81, 82, 83, 84, 85, 86, 100]));
all_eq!(simd_extract_dyn(x2, 0), 20);
all_eq!(simd_extract_dyn(x2, 1), 21);
all_eq!(simd_extract_dyn(x4, 0), 40);
all_eq!(simd_extract_dyn(x4, 1), 41);
all_eq!(simd_extract_dyn(x4, 2), 42);
all_eq!(simd_extract_dyn(x4, 3), 43);
all_eq!(simd_extract_dyn(x8, 0), 80);
all_eq!(simd_extract_dyn(x8, 1), 81);
all_eq!(simd_extract_dyn(x8, 2), 82);
all_eq!(simd_extract_dyn(x8, 3), 83);
all_eq!(simd_extract_dyn(x8, 4), 84);
all_eq!(simd_extract_dyn(x8, 5), 85);
all_eq!(simd_extract_dyn(x8, 6), 86);
all_eq!(simd_extract_dyn(x8, 7), 87);
}
let y2 = i32x2([120, 121]);
let y4 = i32x4([140, 141, 142, 143]);

View File

@ -6,30 +6,134 @@ LL | #![feature(const_trait_impl, generic_const_exprs)]
|
= help: remove one of these features
error[E0277]: the trait bound `T: const Trait` is not satisfied
--> $DIR/unsatisfied-const-trait-bound.rs:29:37
error[E0391]: cycle detected when evaluating type-level constant
--> $DIR/unsatisfied-const-trait-bound.rs:29:35
|
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
| ^
| ^^^^^^^^^^^^^
|
note: ...which requires const-evaluating + checking `accept0::{constant#0}`...
--> $DIR/unsatisfied-const-trait-bound.rs:29:35
|
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^
note: ...which requires caching mir of `accept0::{constant#0}` for CTFE...
--> $DIR/unsatisfied-const-trait-bound.rs:29:35
|
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^
note: ...which requires elaborating drops for `accept0::{constant#0}`...
--> $DIR/unsatisfied-const-trait-bound.rs:29:35
|
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^
note: ...which requires borrow-checking `accept0::{constant#0}`...
--> $DIR/unsatisfied-const-trait-bound.rs:29:35
|
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^
note: ...which requires promoting constants in MIR for `accept0::{constant#0}`...
--> $DIR/unsatisfied-const-trait-bound.rs:29:35
|
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^
note: ...which requires const checking `accept0::{constant#0}`...
--> $DIR/unsatisfied-const-trait-bound.rs:29:35
|
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^
note: ...which requires building MIR for `accept0::{constant#0}`...
--> $DIR/unsatisfied-const-trait-bound.rs:29:35
|
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^
note: ...which requires building an abstract representation for `accept0::{constant#0}`...
--> $DIR/unsatisfied-const-trait-bound.rs:29:35
|
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^
note: ...which requires building THIR for `accept0::{constant#0}`...
--> $DIR/unsatisfied-const-trait-bound.rs:29:35
|
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^
note: ...which requires type-checking `accept0::{constant#0}`...
--> $DIR/unsatisfied-const-trait-bound.rs:29:35
|
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^
= note: ...which again requires evaluating type-level constant, completing the cycle
note: cycle used when checking that `accept0` is well-formed
--> $DIR/unsatisfied-const-trait-bound.rs:29:1
|
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
error[E0277]: the trait bound `T: const Trait` is not satisfied
--> $DIR/unsatisfied-const-trait-bound.rs:33:50
error[E0391]: cycle detected when caching mir of `accept1::{constant#0}` for CTFE
--> $DIR/unsatisfied-const-trait-bound.rs:33:48
|
LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
| ^
error[E0277]: the trait bound `Ty: const Trait` is not satisfied
--> $DIR/unsatisfied-const-trait-bound.rs:22:15
| ^^^^^^^^^^^^^
|
LL | require::<Ty>();
| ^^
note: ...which requires elaborating drops for `accept1::{constant#0}`...
--> $DIR/unsatisfied-const-trait-bound.rs:33:48
|
note: required by a bound in `require`
--> $DIR/unsatisfied-const-trait-bound.rs:8:15
LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^
note: ...which requires borrow-checking `accept1::{constant#0}`...
--> $DIR/unsatisfied-const-trait-bound.rs:33:48
|
LL | fn require<T: const Trait>() {}
| ^^^^^^^^^^^ required by this bound in `require`
LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^
note: ...which requires promoting constants in MIR for `accept1::{constant#0}`...
--> $DIR/unsatisfied-const-trait-bound.rs:33:48
|
LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^
note: ...which requires const checking `accept1::{constant#0}`...
--> $DIR/unsatisfied-const-trait-bound.rs:33:48
|
LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^
note: ...which requires building MIR for `accept1::{constant#0}`...
--> $DIR/unsatisfied-const-trait-bound.rs:33:48
|
LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^
note: ...which requires building an abstract representation for `accept1::{constant#0}`...
--> $DIR/unsatisfied-const-trait-bound.rs:33:48
|
LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^
note: ...which requires building THIR for `accept1::{constant#0}`...
--> $DIR/unsatisfied-const-trait-bound.rs:33:48
|
LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^
note: ...which requires type-checking `accept1::{constant#0}`...
--> $DIR/unsatisfied-const-trait-bound.rs:33:48
|
LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^
note: ...which requires evaluating type-level constant...
--> $DIR/unsatisfied-const-trait-bound.rs:33:48
|
LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^
note: ...which requires const-evaluating + checking `accept1::{constant#0}`...
--> $DIR/unsatisfied-const-trait-bound.rs:33:48
|
LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^
= note: ...which again requires caching mir of `accept1::{constant#0}` for CTFE, completing the cycle
note: cycle used when const-evaluating + checking `accept1::{constant#0}`
--> $DIR/unsatisfied-const-trait-bound.rs:33:48
|
LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
error: aborting due to 4 previous errors
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`.
For more information about this error, try `rustc --explain E0391`.

View File

@ -0,0 +1,5 @@
// Suggestion to use impl trait in closure parameter is invalid, see issue 138932
fn main() {
let c = |f: dyn Fn()| f();
//~^ ERROR: the size for values of type `(dyn Fn() + 'static)` cannot be known at compilation time
}

View File

@ -0,0 +1,16 @@
error[E0277]: the size for values of type `(dyn Fn() + 'static)` cannot be known at compilation time
--> $DIR/dont-suggest-impl-as-closure-arg.rs:3:17
|
LL | let c = |f: dyn Fn()| f();
| ^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `(dyn Fn() + 'static)`
= help: unsized fn params are gated as an unstable feature
help: function arguments must have a statically known size, borrowed types always have a known size
|
LL | let c = |f: &dyn Fn()| f();
| +
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View File

@ -1,8 +1,8 @@
error[E0271]: expected `{async block@$DIR/async.rs:12:17: 12:22}` to be a future that resolves to `i32`, but it resolves to `()`
error[E0271]: type mismatch resolving `() == i32`
--> $DIR/async.rs:12:17
|
LL | needs_async(async {});
| ----------- ^^^^^^^^ expected `i32`, found `()`
| ----------- ^^^^^^^^ types differ
| |
| required by a bound introduced by this call
|

View File

@ -10,7 +10,7 @@ fn needs_async(_: impl Future<Output = i32>) {}
#[cfg(fail)]
fn main() {
needs_async(async {});
//[fail]~^ ERROR expected `{async block@$DIR/async.rs:12:17: 12:22}` to be a future that resolves to `i32`, but it resolves to `()`
//[fail]~^ ERROR type mismatch resolving `() == i32`
}
#[cfg(pass)]

View File

@ -10,7 +10,7 @@ trait Trait: SuperTrait<A = <Self as SuperTrait>::B> {}
fn transmute<A, B>(x: A) -> B {
foo::<A, B, dyn Trait<A = A, B = B>>(x)
//~^ ERROR type mismatch resolving `<dyn Trait<A = A, B = B> as SuperTrait>::A == B`
//~^ ERROR type mismatch resolving `A == B`
}
fn foo<A, B, T: ?Sized>(x: T::A) -> B

View File

@ -1,17 +1,9 @@
error[E0271]: type mismatch resolving `<dyn Trait<A = A, B = B> as SuperTrait>::A == B`
error[E0271]: type mismatch resolving `A == B`
--> $DIR/more-object-bound.rs:12:5
|
LL | fn transmute<A, B>(x: A) -> B {
| - - expected type parameter
| |
| found type parameter
LL | foo::<A, B, dyn Trait<A = A, B = B>>(x)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `B`, found type parameter `A`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
|
= note: expected type parameter `B`
found type parameter `A`
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
= note: required because it appears within the type `dyn Trait<A = A, B = B>`
note: required by a bound in `foo`
--> $DIR/more-object-bound.rs:18:8

View File

@ -13,7 +13,7 @@ fn needs_bar<S: Bar>() {}
fn test<T: Foo1<Assoc1 = <T as Foo2>::Assoc2> + Foo2<Assoc2 = <T as Foo1>::Assoc1>>() {
needs_bar::<T::Assoc1>();
//~^ ERROR the trait bound `<T as Foo1>::Assoc1: Bar` is not satisfied
//~^ ERROR the trait bound `<T as Foo2>::Assoc2: Bar` is not satisfied
}
fn main() {}

View File

@ -1,8 +1,8 @@
error[E0277]: the trait bound `<T as Foo1>::Assoc1: Bar` is not satisfied
error[E0277]: the trait bound `<T as Foo2>::Assoc2: Bar` is not satisfied
--> $DIR/recursive-self-normalization-2.rs:15:17
|
LL | needs_bar::<T::Assoc1>();
| ^^^^^^^^^ the trait `Bar` is not implemented for `<T as Foo1>::Assoc1`
| ^^^^^^^^^ the trait `Bar` is not implemented for `<T as Foo2>::Assoc2`
|
note: required by a bound in `needs_bar`
--> $DIR/recursive-self-normalization-2.rs:12:17
@ -11,7 +11,7 @@ LL | fn needs_bar<S: Bar>() {}
| ^^^ required by this bound in `needs_bar`
help: consider further restricting the associated type
|
LL | fn test<T: Foo1<Assoc1 = <T as Foo2>::Assoc2> + Foo2<Assoc2 = <T as Foo1>::Assoc1>>() where <T as Foo1>::Assoc1: Bar {
LL | fn test<T: Foo1<Assoc1 = <T as Foo2>::Assoc2> + Foo2<Assoc2 = <T as Foo1>::Assoc1>>() where <T as Foo2>::Assoc2: Bar {
| ++++++++++++++++++++++++++++++
error: aborting due to 1 previous error

View File

@ -1,4 +1,4 @@
error[E0049]: type `Baz` has 1 type parameter but its trait declaration has 0 type parameters
error[E0049]: associated type `Baz` has 1 type parameter but its trait declaration has 0 type parameters
--> $DIR/impl-trait-in-type-alias-with-bad-substs.rs:19:14
|
LL | type Baz<'a>;