Auto merge of #139940 - matthiaskrgr:rollup-rd4d3fn, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #135340 (Add `explicit_extern_abis` Feature and Enforce Explicit ABIs) - #139440 (rustc_target: RISC-V: feature addition batch 2) - #139667 (cfi: Remove #[no_sanitize(cfi)] for extern weak functions) - #139828 (Don't require rigid alias's trait to hold) - #139854 (Improve parse errors for stray lifetimes in type position) - #139889 (Clean UI tests 3 of n) - #139894 (Fix `opt-dist` CLI flag and make it work without LLD) - #139900 (stepping into impls for normalization is unproductive) - #139915 (replace some #[rustc_intrinsic] usage with use of the libcore declarations) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
15c4ccef03
79 changed files with 939 additions and 231 deletions
|
@ -79,6 +79,10 @@ ast_passes_extern_types_cannot = `type`s inside `extern` blocks cannot have {$de
|
||||||
.suggestion = remove the {$remove_descr}
|
.suggestion = remove the {$remove_descr}
|
||||||
.label = `extern` block begins here
|
.label = `extern` block begins here
|
||||||
|
|
||||||
|
ast_passes_extern_without_abi = `extern` declarations without an explicit ABI are disallowed
|
||||||
|
.suggestion = specify an ABI
|
||||||
|
.help = prior to Rust 2024, a default ABI was inferred
|
||||||
|
|
||||||
ast_passes_feature_on_non_nightly = `#![feature]` may not be used on the {$channel} release channel
|
ast_passes_feature_on_non_nightly = `#![feature]` may not be used on the {$channel} release channel
|
||||||
.suggestion = remove the attribute
|
.suggestion = remove the attribute
|
||||||
.stable_since = the feature `{$name}` has been stable since `{$since}` and no longer requires an attribute to enable
|
.stable_since = the feature `{$name}` has been stable since `{$since}` and no longer requires an attribute to enable
|
||||||
|
|
|
@ -684,7 +684,7 @@ impl<'a> AstValidator<'a> {
|
||||||
self.dcx().emit_err(errors::PatternFnPointer { span });
|
self.dcx().emit_err(errors::PatternFnPointer { span });
|
||||||
});
|
});
|
||||||
if let Extern::Implicit(extern_span) = bfty.ext {
|
if let Extern::Implicit(extern_span) = bfty.ext {
|
||||||
self.maybe_lint_missing_abi(extern_span, ty.id);
|
self.handle_missing_abi(extern_span, ty.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TyKind::TraitObject(bounds, ..) => {
|
TyKind::TraitObject(bounds, ..) => {
|
||||||
|
@ -717,10 +717,12 @@ impl<'a> AstValidator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn maybe_lint_missing_abi(&mut self, span: Span, id: NodeId) {
|
fn handle_missing_abi(&mut self, span: Span, id: NodeId) {
|
||||||
// FIXME(davidtwco): This is a hack to detect macros which produce spans of the
|
// FIXME(davidtwco): This is a hack to detect macros which produce spans of the
|
||||||
// call site which do not have a macro backtrace. See #61963.
|
// call site which do not have a macro backtrace. See #61963.
|
||||||
if self
|
if span.edition().at_least_edition_future() && self.features.explicit_extern_abis() {
|
||||||
|
self.dcx().emit_err(errors::MissingAbi { span });
|
||||||
|
} else if self
|
||||||
.sess
|
.sess
|
||||||
.source_map()
|
.source_map()
|
||||||
.span_to_snippet(span)
|
.span_to_snippet(span)
|
||||||
|
@ -996,7 +998,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if abi.is_none() {
|
if abi.is_none() {
|
||||||
self.maybe_lint_missing_abi(*extern_span, item.id);
|
self.handle_missing_abi(*extern_span, item.id);
|
||||||
}
|
}
|
||||||
self.with_in_extern_mod(*safety, |this| {
|
self.with_in_extern_mod(*safety, |this| {
|
||||||
visit::walk_item(this, item);
|
visit::walk_item(this, item);
|
||||||
|
@ -1370,7 +1372,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
},
|
},
|
||||||
) = fk
|
) = fk
|
||||||
{
|
{
|
||||||
self.maybe_lint_missing_abi(*extern_span, id);
|
self.handle_missing_abi(*extern_span, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Functions without bodies cannot have patterns.
|
// Functions without bodies cannot have patterns.
|
||||||
|
|
|
@ -823,3 +823,12 @@ pub(crate) struct DuplicatePreciseCapturing {
|
||||||
#[label]
|
#[label]
|
||||||
pub bound2: Span,
|
pub bound2: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(ast_passes_extern_without_abi)]
|
||||||
|
#[help]
|
||||||
|
pub(crate) struct MissingAbi {
|
||||||
|
#[primary_span]
|
||||||
|
#[suggestion(code = "extern \"<abi>\"", applicability = "has-placeholders")]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
|
@ -477,6 +477,8 @@ declare_features! (
|
||||||
(incomplete, ergonomic_clones, "1.87.0", Some(132290)),
|
(incomplete, ergonomic_clones, "1.87.0", Some(132290)),
|
||||||
/// Allows exhaustive pattern matching on types that contain uninhabited types.
|
/// Allows exhaustive pattern matching on types that contain uninhabited types.
|
||||||
(unstable, exhaustive_patterns, "1.13.0", Some(51085)),
|
(unstable, exhaustive_patterns, "1.13.0", Some(51085)),
|
||||||
|
/// Disallows `extern` without an explicit ABI.
|
||||||
|
(unstable, explicit_extern_abis, "CURRENT_RUSTC_VERSION", Some(134986)),
|
||||||
/// Allows explicit tail calls via `become` expression.
|
/// Allows explicit tail calls via `become` expression.
|
||||||
(incomplete, explicit_tail_calls, "1.72.0", Some(112788)),
|
(incomplete, explicit_tail_calls, "1.72.0", Some(112788)),
|
||||||
/// Allows using `aapcs`, `efiapi`, `sysv64` and `win64` as calling conventions
|
/// Allows using `aapcs`, `efiapi`, `sysv64` and `win64` as calling conventions
|
||||||
|
|
|
@ -271,7 +271,7 @@ lint_expectation = this lint expectation is unfulfilled
|
||||||
lint_extern_crate_not_idiomatic = `extern crate` is not idiomatic in the new edition
|
lint_extern_crate_not_idiomatic = `extern crate` is not idiomatic in the new edition
|
||||||
.suggestion = convert it to a `use`
|
.suggestion = convert it to a `use`
|
||||||
|
|
||||||
lint_extern_without_abi = extern declarations without an explicit ABI are deprecated
|
lint_extern_without_abi = `extern` declarations without an explicit ABI are deprecated
|
||||||
.label = ABI should be specified here
|
.label = ABI should be specified here
|
||||||
.suggestion = explicitly specify the {$default_abi} ABI
|
.suggestion = explicitly specify the {$default_abi} ABI
|
||||||
|
|
||||||
|
|
|
@ -286,18 +286,23 @@ where
|
||||||
// fixing it may cause inference breakage or introduce ambiguity.
|
// fixing it may cause inference breakage or introduce ambiguity.
|
||||||
GoalSource::Misc => PathKind::Unknown,
|
GoalSource::Misc => PathKind::Unknown,
|
||||||
GoalSource::NormalizeGoal(path_kind) => path_kind,
|
GoalSource::NormalizeGoal(path_kind) => path_kind,
|
||||||
GoalSource::ImplWhereBound => {
|
GoalSource::ImplWhereBound => match self.current_goal_kind {
|
||||||
// We currently only consider a cycle coinductive if it steps
|
// We currently only consider a cycle coinductive if it steps
|
||||||
// into a where-clause of a coinductive trait.
|
// into a where-clause of a coinductive trait.
|
||||||
|
CurrentGoalKind::CoinductiveTrait => PathKind::Coinductive,
|
||||||
|
// While normalizing via an impl does step into a where-clause of
|
||||||
|
// an impl, accessing the associated item immediately steps out of
|
||||||
|
// it again. This means cycles/recursive calls are not guarded
|
||||||
|
// by impls used for normalization.
|
||||||
//
|
//
|
||||||
|
// See tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.rs
|
||||||
|
// for how this can go wrong.
|
||||||
|
CurrentGoalKind::NormalizesTo => PathKind::Inductive,
|
||||||
// We probably want to make all traits coinductive in the future,
|
// We probably want to make all traits coinductive in the future,
|
||||||
// so we treat cycles involving their where-clauses as ambiguous.
|
// so we treat cycles involving where-clauses of not-yet coinductive
|
||||||
if let CurrentGoalKind::CoinductiveTrait = self.current_goal_kind {
|
// traits as ambiguous for now.
|
||||||
PathKind::Coinductive
|
CurrentGoalKind::Misc => PathKind::Unknown,
|
||||||
} else {
|
},
|
||||||
PathKind::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Relating types is always unproductive. If we were to map proof trees to
|
// Relating types is always unproductive. If we were to map proof trees to
|
||||||
// corecursive functions as explained in #136824, relating types never
|
// corecursive functions as explained in #136824, relating types never
|
||||||
// introduces a constructor which could cause the recursion to be guarded.
|
// introduces a constructor which could cause the recursion to be guarded.
|
||||||
|
|
|
@ -45,7 +45,6 @@ where
|
||||||
goal,
|
goal,
|
||||||
goal.predicate.alias,
|
goal.predicate.alias,
|
||||||
);
|
);
|
||||||
this.add_goal(GoalSource::AliasWellFormed, goal.with(cx, trait_ref));
|
|
||||||
this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -543,7 +543,7 @@ parse_maybe_recover_from_bad_qpath_stage_2 =
|
||||||
.suggestion = types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
|
.suggestion = types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
|
||||||
|
|
||||||
parse_maybe_recover_from_bad_type_plus =
|
parse_maybe_recover_from_bad_type_plus =
|
||||||
expected a path on the left-hand side of `+`, not `{$ty}`
|
expected a path on the left-hand side of `+`
|
||||||
|
|
||||||
parse_maybe_report_ambiguous_plus =
|
parse_maybe_report_ambiguous_plus =
|
||||||
ambiguous `+` in a type
|
ambiguous `+` in a type
|
||||||
|
@ -642,7 +642,9 @@ parse_mut_on_nested_ident_pattern = `mut` must be attached to each individual bi
|
||||||
.suggestion = add `mut` to each binding
|
.suggestion = add `mut` to each binding
|
||||||
parse_mut_on_non_ident_pattern = `mut` must be followed by a named binding
|
parse_mut_on_non_ident_pattern = `mut` must be followed by a named binding
|
||||||
.suggestion = remove the `mut` prefix
|
.suggestion = remove the `mut` prefix
|
||||||
parse_need_plus_after_trait_object_lifetime = lifetime in trait object type must be followed by `+`
|
|
||||||
|
parse_need_plus_after_trait_object_lifetime = lifetimes must be followed by `+` to form a trait object type
|
||||||
|
.suggestion = consider adding a trait bound after the potential lifetime bound
|
||||||
|
|
||||||
parse_nested_adt = `{$kw_str}` definition cannot be nested inside `{$keyword}`
|
parse_nested_adt = `{$kw_str}` definition cannot be nested inside `{$keyword}`
|
||||||
.suggestion = consider creating a new `{$kw_str}` definition instead of nesting
|
.suggestion = consider creating a new `{$kw_str}` definition instead of nesting
|
||||||
|
|
|
@ -30,7 +30,6 @@ pub(crate) struct AmbiguousPlus {
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(parse_maybe_recover_from_bad_type_plus, code = E0178)]
|
#[diag(parse_maybe_recover_from_bad_type_plus, code = E0178)]
|
||||||
pub(crate) struct BadTypePlus {
|
pub(crate) struct BadTypePlus {
|
||||||
pub ty: String,
|
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[subdiagnostic]
|
#[subdiagnostic]
|
||||||
|
@ -2800,6 +2799,8 @@ pub(crate) struct ReturnTypesUseThinArrow {
|
||||||
pub(crate) struct NeedPlusAfterTraitObjectLifetime {
|
pub(crate) struct NeedPlusAfterTraitObjectLifetime {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
#[suggestion(code = " + /* Trait */", applicability = "has-placeholders")]
|
||||||
|
pub suggestion: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
|
|
|
@ -1657,19 +1657,19 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
self.bump(); // `+`
|
self.bump(); // `+`
|
||||||
let _bounds = self.parse_generic_bounds()?;
|
let _bounds = self.parse_generic_bounds()?;
|
||||||
let sum_span = ty.span.to(self.prev_token.span);
|
|
||||||
|
|
||||||
let sub = match &ty.kind {
|
let sub = match &ty.kind {
|
||||||
TyKind::Ref(_lifetime, mut_ty) => {
|
TyKind::Ref(_lifetime, mut_ty) => {
|
||||||
let lo = mut_ty.ty.span.shrink_to_lo();
|
let lo = mut_ty.ty.span.shrink_to_lo();
|
||||||
let hi = self.prev_token.span.shrink_to_hi();
|
let hi = self.prev_token.span.shrink_to_hi();
|
||||||
BadTypePlusSub::AddParen { suggestion: AddParen { lo, hi } }
|
BadTypePlusSub::AddParen { suggestion: AddParen { lo, hi } }
|
||||||
}
|
}
|
||||||
TyKind::Ptr(..) | TyKind::BareFn(..) => BadTypePlusSub::ForgotParen { span: sum_span },
|
TyKind::Ptr(..) | TyKind::BareFn(..) => {
|
||||||
_ => BadTypePlusSub::ExpectPath { span: sum_span },
|
BadTypePlusSub::ForgotParen { span: ty.span.to(self.prev_token.span) }
|
||||||
|
}
|
||||||
|
_ => BadTypePlusSub::ExpectPath { span: ty.span },
|
||||||
};
|
};
|
||||||
|
|
||||||
self.dcx().emit_err(BadTypePlus { ty: pprust::ty_to_string(ty), span: sum_span, sub });
|
self.dcx().emit_err(BadTypePlus { span: ty.span, sub });
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use rustc_ast::{
|
||||||
Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty,
|
Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty,
|
||||||
TyKind, UnsafeBinderTy,
|
TyKind, UnsafeBinderTy,
|
||||||
};
|
};
|
||||||
use rustc_errors::{Applicability, PResult};
|
use rustc_errors::{Applicability, Diag, PResult};
|
||||||
use rustc_span::{ErrorGuaranteed, Ident, Span, kw, sym};
|
use rustc_span::{ErrorGuaranteed, Ident, Span, kw, sym};
|
||||||
use thin_vec::{ThinVec, thin_vec};
|
use thin_vec::{ThinVec, thin_vec};
|
||||||
|
|
||||||
|
@ -411,6 +411,9 @@ impl<'a> Parser<'a> {
|
||||||
TyKind::Path(None, path) if maybe_bounds => {
|
TyKind::Path(None, path) if maybe_bounds => {
|
||||||
self.parse_remaining_bounds_path(ThinVec::new(), path, lo, true)
|
self.parse_remaining_bounds_path(ThinVec::new(), path, lo, true)
|
||||||
}
|
}
|
||||||
|
// For `('a) + …`, we know that `'a` in type position already lead to an error being
|
||||||
|
// emitted. To reduce output, let's indirectly suppress E0178 (bad `+` in type) and
|
||||||
|
// other irrelevant consequential errors.
|
||||||
TyKind::TraitObject(bounds, TraitObjectSyntax::None)
|
TyKind::TraitObject(bounds, TraitObjectSyntax::None)
|
||||||
if maybe_bounds && bounds.len() == 1 && !trailing_plus =>
|
if maybe_bounds && bounds.len() == 1 && !trailing_plus =>
|
||||||
{
|
{
|
||||||
|
@ -425,12 +428,60 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_bare_trait_object(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> {
|
fn parse_bare_trait_object(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> {
|
||||||
let lt_no_plus = self.check_lifetime() && !self.look_ahead(1, |t| t.is_like_plus());
|
// A lifetime only begins a bare trait object type if it is followed by `+`!
|
||||||
let bounds = self.parse_generic_bounds_common(allow_plus)?;
|
if self.token.is_lifetime() && !self.look_ahead(1, |t| t.is_like_plus()) {
|
||||||
if lt_no_plus {
|
// In Rust 2021 and beyond, we assume that the user didn't intend to write a bare trait
|
||||||
self.dcx().emit_err(NeedPlusAfterTraitObjectLifetime { span: lo });
|
// object type with a leading lifetime bound since that seems very unlikely given the
|
||||||
|
// fact that `dyn`-less trait objects are *semantically* invalid.
|
||||||
|
if self.psess.edition.at_least_rust_2021() {
|
||||||
|
let lt = self.expect_lifetime();
|
||||||
|
let mut err = self.dcx().struct_span_err(lo, "expected type, found lifetime");
|
||||||
|
err.span_label(lo, "expected type");
|
||||||
|
return Ok(match self.maybe_recover_ref_ty_no_leading_ampersand(lt, lo, err) {
|
||||||
|
Ok(ref_ty) => ref_ty,
|
||||||
|
Err(err) => TyKind::Err(err.emit()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.dcx().emit_err(NeedPlusAfterTraitObjectLifetime {
|
||||||
|
span: lo,
|
||||||
|
suggestion: lo.shrink_to_hi(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Ok(TyKind::TraitObject(
|
||||||
|
self.parse_generic_bounds_common(allow_plus)?,
|
||||||
|
TraitObjectSyntax::None,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn maybe_recover_ref_ty_no_leading_ampersand<'cx>(
|
||||||
|
&mut self,
|
||||||
|
lt: Lifetime,
|
||||||
|
lo: Span,
|
||||||
|
mut err: Diag<'cx>,
|
||||||
|
) -> Result<TyKind, Diag<'cx>> {
|
||||||
|
if !self.may_recover() {
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
|
let snapshot = self.create_snapshot_for_diagnostic();
|
||||||
|
let mutbl = self.parse_mutability();
|
||||||
|
match self.parse_ty_no_plus() {
|
||||||
|
Ok(ty) => {
|
||||||
|
err.span_suggestion_verbose(
|
||||||
|
lo.shrink_to_lo(),
|
||||||
|
"you might have meant to write a reference type here",
|
||||||
|
"&",
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
err.emit();
|
||||||
|
Ok(TyKind::Ref(Some(lt), MutTy { ty, mutbl }))
|
||||||
|
}
|
||||||
|
Err(diag) => {
|
||||||
|
diag.cancel();
|
||||||
|
self.restore_snapshot(snapshot);
|
||||||
|
Err(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_remaining_bounds_path(
|
fn parse_remaining_bounds_path(
|
||||||
|
|
|
@ -916,6 +916,7 @@ symbols! {
|
||||||
expf16,
|
expf16,
|
||||||
expf32,
|
expf32,
|
||||||
expf64,
|
expf64,
|
||||||
|
explicit_extern_abis,
|
||||||
explicit_generic_args_with_impl_trait,
|
explicit_generic_args_with_impl_trait,
|
||||||
explicit_tail_calls,
|
explicit_tail_calls,
|
||||||
export_name,
|
export_name,
|
||||||
|
|
|
@ -19,7 +19,7 @@ pub(crate) fn target() -> Target {
|
||||||
options: TargetOptions {
|
options: TargetOptions {
|
||||||
code_model: Some(CodeModel::Medium),
|
code_model: Some(CodeModel::Medium),
|
||||||
cpu: "generic-rv64".into(),
|
cpu: "generic-rv64".into(),
|
||||||
features: "+m,+a,+f,+d,+c,+zicsr,+zifencei,+zba,+zbb,+zbs,+v".into(),
|
features: "+m,+a,+f,+d,+c,+b,+v,+zicsr,+zifencei".into(),
|
||||||
llvm_abiname: "lp64d".into(),
|
llvm_abiname: "lp64d".into(),
|
||||||
supported_sanitizers: SanitizerSet::ADDRESS,
|
supported_sanitizers: SanitizerSet::ADDRESS,
|
||||||
max_atomic_width: Some(64),
|
max_atomic_width: Some(64),
|
||||||
|
|
|
@ -491,7 +491,8 @@ const MIPS_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
|
||||||
static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
|
static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
|
||||||
// tidy-alphabetical-start
|
// tidy-alphabetical-start
|
||||||
("a", Stable, &["zaamo", "zalrsc"]),
|
("a", Stable, &["zaamo", "zalrsc"]),
|
||||||
("c", Stable, &[]),
|
("b", Unstable(sym::riscv_target_feature), &["zba", "zbb", "zbs"]),
|
||||||
|
("c", Stable, &["zca"]),
|
||||||
("d", Unstable(sym::riscv_target_feature), &["f"]),
|
("d", Unstable(sym::riscv_target_feature), &["f"]),
|
||||||
("e", Unstable(sym::riscv_target_feature), &[]),
|
("e", Unstable(sym::riscv_target_feature), &[]),
|
||||||
("f", Unstable(sym::riscv_target_feature), &["zicsr"]),
|
("f", Unstable(sym::riscv_target_feature), &["zicsr"]),
|
||||||
|
@ -520,17 +521,25 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
|
||||||
("zbkc", Stable, &[]),
|
("zbkc", Stable, &[]),
|
||||||
("zbkx", Stable, &[]),
|
("zbkx", Stable, &[]),
|
||||||
("zbs", Stable, &[]),
|
("zbs", Stable, &[]),
|
||||||
|
("zca", Unstable(sym::riscv_target_feature), &[]),
|
||||||
|
("zcb", Unstable(sym::riscv_target_feature), &["zca"]),
|
||||||
|
("zcmop", Unstable(sym::riscv_target_feature), &["zca"]),
|
||||||
("zdinx", Unstable(sym::riscv_target_feature), &["zfinx"]),
|
("zdinx", Unstable(sym::riscv_target_feature), &["zfinx"]),
|
||||||
|
("zfa", Unstable(sym::riscv_target_feature), &["f"]),
|
||||||
("zfh", Unstable(sym::riscv_target_feature), &["zfhmin"]),
|
("zfh", Unstable(sym::riscv_target_feature), &["zfhmin"]),
|
||||||
("zfhmin", Unstable(sym::riscv_target_feature), &["f"]),
|
("zfhmin", Unstable(sym::riscv_target_feature), &["f"]),
|
||||||
("zfinx", Unstable(sym::riscv_target_feature), &["zicsr"]),
|
("zfinx", Unstable(sym::riscv_target_feature), &["zicsr"]),
|
||||||
("zhinx", Unstable(sym::riscv_target_feature), &["zhinxmin"]),
|
("zhinx", Unstable(sym::riscv_target_feature), &["zhinxmin"]),
|
||||||
("zhinxmin", Unstable(sym::riscv_target_feature), &["zfinx"]),
|
("zhinxmin", Unstable(sym::riscv_target_feature), &["zfinx"]),
|
||||||
|
("zicboz", Unstable(sym::riscv_target_feature), &[]),
|
||||||
("zicntr", Unstable(sym::riscv_target_feature), &["zicsr"]),
|
("zicntr", Unstable(sym::riscv_target_feature), &["zicsr"]),
|
||||||
|
("zicond", Unstable(sym::riscv_target_feature), &[]),
|
||||||
("zicsr", Unstable(sym::riscv_target_feature), &[]),
|
("zicsr", Unstable(sym::riscv_target_feature), &[]),
|
||||||
("zifencei", Unstable(sym::riscv_target_feature), &[]),
|
("zifencei", Unstable(sym::riscv_target_feature), &[]),
|
||||||
|
("zihintntl", Unstable(sym::riscv_target_feature), &[]),
|
||||||
("zihintpause", Unstable(sym::riscv_target_feature), &[]),
|
("zihintpause", Unstable(sym::riscv_target_feature), &[]),
|
||||||
("zihpm", Unstable(sym::riscv_target_feature), &["zicsr"]),
|
("zihpm", Unstable(sym::riscv_target_feature), &["zicsr"]),
|
||||||
|
("zimop", Unstable(sym::riscv_target_feature), &[]),
|
||||||
("zk", Stable, &["zkn", "zkr", "zkt"]),
|
("zk", Stable, &["zkn", "zkr", "zkt"]),
|
||||||
("zkn", Stable, &["zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"]),
|
("zkn", Stable, &["zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"]),
|
||||||
("zknd", Stable, &[]),
|
("zknd", Stable, &[]),
|
||||||
|
@ -541,6 +550,7 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
|
||||||
("zksed", Stable, &[]),
|
("zksed", Stable, &[]),
|
||||||
("zksh", Stable, &[]),
|
("zksh", Stable, &[]),
|
||||||
("zkt", Stable, &[]),
|
("zkt", Stable, &[]),
|
||||||
|
("ztso", Unstable(sym::riscv_target_feature), &[]),
|
||||||
("zvbb", Unstable(sym::riscv_target_feature), &["zvkb"]),
|
("zvbb", Unstable(sym::riscv_target_feature), &["zvkb"]),
|
||||||
("zvbc", Unstable(sym::riscv_target_feature), &["zve64x"]),
|
("zvbc", Unstable(sym::riscv_target_feature), &["zve64x"]),
|
||||||
("zve32f", Unstable(sym::riscv_target_feature), &["zve32x", "f"]),
|
("zve32f", Unstable(sym::riscv_target_feature), &["zve32x", "f"]),
|
||||||
|
|
|
@ -312,7 +312,6 @@
|
||||||
#![feature(needs_panic_runtime)]
|
#![feature(needs_panic_runtime)]
|
||||||
#![feature(negative_impls)]
|
#![feature(negative_impls)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(no_sanitize)]
|
|
||||||
#![feature(optimize_attribute)]
|
#![feature(optimize_attribute)]
|
||||||
#![feature(prelude_import)]
|
#![feature(prelude_import)]
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
|
@ -259,9 +259,6 @@ impl FileDesc {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(target_os = "android", target_pointer_width = "32"))]
|
#[cfg(all(target_os = "android", target_pointer_width = "32"))]
|
||||||
// FIXME(#115199): Rust currently omits weak function definitions
|
|
||||||
// and its metadata from LLVM IR.
|
|
||||||
#[no_sanitize(cfi)]
|
|
||||||
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
|
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
|
||||||
weak!(
|
weak!(
|
||||||
fn preadv64(
|
fn preadv64(
|
||||||
|
|
|
@ -1463,20 +1463,6 @@ impl File {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(#115199): Rust currently omits weak function definitions
|
|
||||||
// and its metadata from LLVM IR.
|
|
||||||
#[cfg_attr(
|
|
||||||
any(
|
|
||||||
target_os = "android",
|
|
||||||
all(
|
|
||||||
target_os = "linux",
|
|
||||||
target_env = "gnu",
|
|
||||||
target_pointer_width = "32",
|
|
||||||
not(target_arch = "riscv32")
|
|
||||||
)
|
|
||||||
),
|
|
||||||
no_sanitize(cfi)
|
|
||||||
)]
|
|
||||||
pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
|
pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
|
||||||
#[cfg(not(any(
|
#[cfg(not(any(
|
||||||
target_os = "redox",
|
target_os = "redox",
|
||||||
|
|
|
@ -194,9 +194,6 @@ impl Thread {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "nto"))]
|
#[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "nto"))]
|
||||||
// FIXME(#115199): Rust currently omits weak function definitions
|
|
||||||
// and its metadata from LLVM IR.
|
|
||||||
#[no_sanitize(cfi)]
|
|
||||||
pub fn set_name(name: &CStr) {
|
pub fn set_name(name: &CStr) {
|
||||||
weak!(
|
weak!(
|
||||||
fn pthread_setname_np(
|
fn pthread_setname_np(
|
||||||
|
|
|
@ -96,17 +96,6 @@ impl Timespec {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(#115199): Rust currently omits weak function definitions
|
|
||||||
// and its metadata from LLVM IR.
|
|
||||||
#[cfg_attr(
|
|
||||||
all(
|
|
||||||
target_os = "linux",
|
|
||||||
target_env = "gnu",
|
|
||||||
target_pointer_width = "32",
|
|
||||||
not(target_arch = "riscv32")
|
|
||||||
),
|
|
||||||
no_sanitize(cfi)
|
|
||||||
)]
|
|
||||||
pub fn now(clock: libc::clockid_t) -> Timespec {
|
pub fn now(clock: libc::clockid_t) -> Timespec {
|
||||||
use crate::mem::MaybeUninit;
|
use crate::mem::MaybeUninit;
|
||||||
use crate::sys::cvt;
|
use crate::sys::cvt;
|
||||||
|
|
|
@ -155,9 +155,6 @@ unsafe fn fetch(name: &str) -> *mut libc::c_void {
|
||||||
#[cfg(not(any(target_os = "linux", target_os = "android")))]
|
#[cfg(not(any(target_os = "linux", target_os = "android")))]
|
||||||
pub(crate) macro syscall {
|
pub(crate) macro syscall {
|
||||||
(fn $name:ident($($param:ident : $t:ty),* $(,)?) -> $ret:ty;) => (
|
(fn $name:ident($($param:ident : $t:ty),* $(,)?) -> $ret:ty;) => (
|
||||||
// FIXME(#115199): Rust currently omits weak function definitions
|
|
||||||
// and its metadata from LLVM IR.
|
|
||||||
#[no_sanitize(cfi)]
|
|
||||||
unsafe fn $name($($param: $t),*) -> $ret {
|
unsafe fn $name($($param: $t),*) -> $ret {
|
||||||
weak!(fn $name($($param: $t),*) -> $ret;);
|
weak!(fn $name($($param: $t),*) -> $ret;);
|
||||||
|
|
||||||
|
|
|
@ -434,9 +434,6 @@ impl Command {
|
||||||
target_os = "nto",
|
target_os = "nto",
|
||||||
target_vendor = "apple",
|
target_vendor = "apple",
|
||||||
))]
|
))]
|
||||||
// FIXME(#115199): Rust currently omits weak function definitions
|
|
||||||
// and its metadata from LLVM IR.
|
|
||||||
#[cfg_attr(target_os = "linux", no_sanitize(cfi))]
|
|
||||||
fn posix_spawn(
|
fn posix_spawn(
|
||||||
&mut self,
|
&mut self,
|
||||||
stdio: &ChildPipes,
|
stdio: &ChildPipes,
|
||||||
|
|
|
@ -12,9 +12,6 @@
|
||||||
|
|
||||||
use crate::mem::transmute;
|
use crate::mem::transmute;
|
||||||
|
|
||||||
// FIXME: The Rust compiler currently omits weakly function definitions (i.e.,
|
|
||||||
// __cxa_thread_atexit_impl) and its metadata from LLVM IR.
|
|
||||||
#[no_sanitize(cfi, kcfi)]
|
|
||||||
pub unsafe fn register(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
|
pub unsafe fn register(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
|
||||||
/// This is necessary because the __cxa_thread_atexit_impl implementation
|
/// This is necessary because the __cxa_thread_atexit_impl implementation
|
||||||
/// std links to by default may be a C or C++ implementation that was not
|
/// std links to by default may be a C or C++ implementation that was not
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# `explicit_extern_abis`
|
||||||
|
|
||||||
|
The tracking issue for this feature is: #134986
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
Disallow `extern` without an explicit ABI. We should write `extern "C"`
|
||||||
|
(or another ABI) instead of just `extern`.
|
||||||
|
|
||||||
|
By making the ABI explicit, it becomes much clearer that "C" is just one of the
|
||||||
|
possible choices, rather than the "standard" way for external functions.
|
||||||
|
Removing the default makes it easier to add a new ABI on equal footing as "C".
|
||||||
|
|
||||||
|
```rust,editionfuture,compile_fail
|
||||||
|
#![feature(explicit_extern_abis)]
|
||||||
|
|
||||||
|
extern fn function1() {} // ERROR `extern` declarations without an explicit ABI
|
||||||
|
// are disallowed
|
||||||
|
|
||||||
|
extern "C" fn function2() {} // compiles
|
||||||
|
|
||||||
|
extern "aapcs" fn function3() {} // compiles
|
||||||
|
```
|
|
@ -76,7 +76,7 @@ enum EnvironmentCmd {
|
||||||
rustc_perf_checkout_dir: Option<Utf8PathBuf>,
|
rustc_perf_checkout_dir: Option<Utf8PathBuf>,
|
||||||
|
|
||||||
/// Is LLVM for `rustc` built in shared library mode?
|
/// Is LLVM for `rustc` built in shared library mode?
|
||||||
#[arg(long, default_value_t = true)]
|
#[arg(long, default_value_t = true, action(clap::ArgAction::Set))]
|
||||||
llvm_shared: bool,
|
llvm_shared: bool,
|
||||||
|
|
||||||
/// Should BOLT optimization be used? If yes, host LLVM must have BOLT binaries
|
/// Should BOLT optimization be used? If yes, host LLVM must have BOLT binaries
|
||||||
|
|
|
@ -36,7 +36,9 @@ pub fn clear_llvm_files(env: &Environment) -> anyhow::Result<()> {
|
||||||
// directories ourselves.
|
// directories ourselves.
|
||||||
log::info!("Clearing LLVM build files");
|
log::info!("Clearing LLVM build files");
|
||||||
delete_directory(&env.build_artifacts().join("llvm"))?;
|
delete_directory(&env.build_artifacts().join("llvm"))?;
|
||||||
|
if env.build_artifacts().join("lld").is_dir() {
|
||||||
delete_directory(&env.build_artifacts().join("lld"))?;
|
delete_directory(&env.build_artifacts().join("lld"))?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
//@ compile-flags: -C no-prepopulate-passes
|
//@ compile-flags: -C no-prepopulate-passes
|
||||||
|
|
||||||
#![feature(intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
|
|
||||||
#[rustc_intrinsic]
|
use std::intrinsics::sqrtf32;
|
||||||
unsafe fn sqrtf32(x: f32) -> f32;
|
|
||||||
|
|
||||||
// CHECK: @llvm.sqrt.f32(float) #{{[0-9]*}}
|
// CHECK: @llvm.sqrt.f32(float) #{{[0-9]*}}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE");
|
||||||
`avxvnni`
|
`avxvnni`
|
||||||
`avxvnniint16`
|
`avxvnniint16`
|
||||||
`avxvnniint8`
|
`avxvnniint8`
|
||||||
|
`b`
|
||||||
`backchain`
|
`backchain`
|
||||||
`bf16`
|
`bf16`
|
||||||
`bmi1`
|
`bmi1`
|
||||||
|
@ -318,17 +319,25 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE");
|
||||||
`zbkc`
|
`zbkc`
|
||||||
`zbkx`
|
`zbkx`
|
||||||
`zbs`
|
`zbs`
|
||||||
|
`zca`
|
||||||
|
`zcb`
|
||||||
|
`zcmop`
|
||||||
`zdinx`
|
`zdinx`
|
||||||
|
`zfa`
|
||||||
`zfh`
|
`zfh`
|
||||||
`zfhmin`
|
`zfhmin`
|
||||||
`zfinx`
|
`zfinx`
|
||||||
`zhinx`
|
`zhinx`
|
||||||
`zhinxmin`
|
`zhinxmin`
|
||||||
|
`zicboz`
|
||||||
`zicntr`
|
`zicntr`
|
||||||
|
`zicond`
|
||||||
`zicsr`
|
`zicsr`
|
||||||
`zifencei`
|
`zifencei`
|
||||||
|
`zihintntl`
|
||||||
`zihintpause`
|
`zihintpause`
|
||||||
`zihpm`
|
`zihpm`
|
||||||
|
`zimop`
|
||||||
`zk`
|
`zk`
|
||||||
`zkn`
|
`zkn`
|
||||||
`zknd`
|
`zknd`
|
||||||
|
@ -339,6 +348,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE");
|
||||||
`zksed`
|
`zksed`
|
||||||
`zksh`
|
`zksh`
|
||||||
`zkt`
|
`zkt`
|
||||||
|
`ztso`
|
||||||
`zvbb`
|
`zvbb`
|
||||||
`zvbc`
|
`zvbc`
|
||||||
`zve32f`
|
`zve32f`
|
||||||
|
|
41
tests/ui/coroutine/higher-ranked-rigid.rs
Normal file
41
tests/ui/coroutine/higher-ranked-rigid.rs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
//@ edition: 2024
|
||||||
|
//@ revisions: current next
|
||||||
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/177>.
|
||||||
|
// Coroutines erase all free lifetimes from their interior types, replacing them with higher-
|
||||||
|
// ranked regions which act as universals, to properly represent the fact that we don't know what
|
||||||
|
// the value of the region is within the coroutine.
|
||||||
|
//
|
||||||
|
// In the future in `from_request`, that means that the `'r` lifetime is being replaced in
|
||||||
|
// `<T as FromRequest<'r>>::Assoc`, which is in present in the existential bounds of the
|
||||||
|
// `dyn Future` that it's awaiting. Normalizing this associated type, with its free lifetimes
|
||||||
|
// replaced, means proving `T: FromRequest<'!0>`, which doesn't hold without constraining the
|
||||||
|
// `'!0` lifetime, which we don't do today.
|
||||||
|
|
||||||
|
// Proving `T: Trait` holds when `<T as Trait>::Assoc` is rigid is not necessary for soundness,
|
||||||
|
// at least not *yet*, and it's not even necessary for diagnostics since we have other special
|
||||||
|
// casing for, e.g., AliasRelate goals failing in the BestObligation folder.
|
||||||
|
|
||||||
|
// The old solver unintentioanlly avoids this by never checking that `T: Trait` holds when
|
||||||
|
// `<T as Trait>::Assoc` is rigid. Introducing this additional requirement when projecting rigidly
|
||||||
|
// in the old solver causes this (and tons of production crates) to fail. See the fallout from the
|
||||||
|
// crater run at <https://github.com/rust-lang/rust/pull/139763>.
|
||||||
|
|
||||||
|
use std::future::Future;
|
||||||
|
use std::pin::Pin;
|
||||||
|
|
||||||
|
pub trait FromRequest<'r> {
|
||||||
|
type Assoc;
|
||||||
|
fn from_request() -> Pin<Box<dyn Future<Output = Self::Assoc> + Send>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test<'r, T: FromRequest<'r>>() -> Pin<Box<dyn Future<Output = ()> + Send>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
T::from_request().await;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -1,41 +1,43 @@
|
||||||
error[E0178]: expected a path on the left-hand side of `+`, not `&'a Foo`
|
error[E0178]: expected a path on the left-hand side of `+`
|
||||||
--> $DIR/E0178.rs:6:8
|
--> $DIR/E0178.rs:6:8
|
||||||
|
|
|
|
||||||
LL | w: &'a Foo + Copy,
|
LL | w: &'a Foo + Copy,
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
|
|
||||||
help: try adding parentheses
|
help: try adding parentheses
|
||||||
|
|
|
|
||||||
LL | w: &'a (Foo + Copy),
|
LL | w: &'a (Foo + Copy),
|
||||||
| + +
|
| + +
|
||||||
|
|
||||||
error[E0178]: expected a path on the left-hand side of `+`, not `&'a Foo`
|
error[E0178]: expected a path on the left-hand side of `+`
|
||||||
--> $DIR/E0178.rs:7:8
|
--> $DIR/E0178.rs:7:8
|
||||||
|
|
|
|
||||||
LL | x: &'a Foo + 'a,
|
LL | x: &'a Foo + 'a,
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
|
|
||||||
help: try adding parentheses
|
help: try adding parentheses
|
||||||
|
|
|
|
||||||
LL | x: &'a (Foo + 'a),
|
LL | x: &'a (Foo + 'a),
|
||||||
| + +
|
| + +
|
||||||
|
|
||||||
error[E0178]: expected a path on the left-hand side of `+`, not `&'a mut Foo`
|
error[E0178]: expected a path on the left-hand side of `+`
|
||||||
--> $DIR/E0178.rs:8:8
|
--> $DIR/E0178.rs:8:8
|
||||||
|
|
|
|
||||||
LL | y: &'a mut Foo + 'a,
|
LL | y: &'a mut Foo + 'a,
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
help: try adding parentheses
|
help: try adding parentheses
|
||||||
|
|
|
|
||||||
LL | y: &'a mut (Foo + 'a),
|
LL | y: &'a mut (Foo + 'a),
|
||||||
| + +
|
| + +
|
||||||
|
|
||||||
error[E0178]: expected a path on the left-hand side of `+`, not `fn() -> Foo`
|
error[E0178]: expected a path on the left-hand side of `+`
|
||||||
--> $DIR/E0178.rs:9:8
|
--> $DIR/E0178.rs:9:8
|
||||||
|
|
|
|
||||||
LL | z: fn() -> Foo + 'a,
|
LL | z: fn() -> Foo + 'a,
|
||||||
| ^^^^^^^^^^^^^^^^ perhaps you forgot parentheses?
|
| ^^^^^^^^^^^-----
|
||||||
|
| |
|
||||||
|
| perhaps you forgot parentheses?
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
error[E0178]: expected a path on the left-hand side of `+`, not `&Copy`
|
error[E0178]: expected a path on the left-hand side of `+`
|
||||||
--> $DIR/trait-object-reference-without-parens-suggestion.rs:4:12
|
--> $DIR/trait-object-reference-without-parens-suggestion.rs:4:12
|
||||||
|
|
|
|
||||||
LL | let _: &Copy + 'static;
|
LL | let _: &Copy + 'static;
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^
|
||||||
|
|
|
|
||||||
help: try adding parentheses
|
help: try adding parentheses
|
||||||
|
|
|
|
||||||
LL | let _: &(Copy + 'static);
|
LL | let _: &(Copy + 'static);
|
||||||
| + +
|
| + +
|
||||||
|
|
||||||
error[E0178]: expected a path on the left-hand side of `+`, not `&'static Copy`
|
error[E0178]: expected a path on the left-hand side of `+`
|
||||||
--> $DIR/trait-object-reference-without-parens-suggestion.rs:6:12
|
--> $DIR/trait-object-reference-without-parens-suggestion.rs:6:12
|
||||||
|
|
|
|
||||||
LL | let _: &'static Copy + 'static;
|
LL | let _: &'static Copy + 'static;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
help: try adding parentheses
|
help: try adding parentheses
|
||||||
|
|
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
// The purpose of this feature gate is to make something into a hard error in a
|
||||||
|
// future edition. Consequently, this test differs from most other feature gate
|
||||||
|
// tests. Instead of verifying that an error occurs when the feature gate is
|
||||||
|
// missing, it ensures that the hard error is only produced with the feature
|
||||||
|
// gate is present in the `future` edition -- and otherwise that only a warning
|
||||||
|
// is emitted.
|
||||||
|
|
||||||
|
//@ revisions: current current_feature future future_feature
|
||||||
|
|
||||||
|
//@ [current] run-rustfix
|
||||||
|
//@ [current] check-pass
|
||||||
|
|
||||||
|
//@ [current_feature] run-rustfix
|
||||||
|
//@ [current_feature] check-pass
|
||||||
|
|
||||||
|
//@ [future] edition: future
|
||||||
|
//@ [future] compile-flags: -Z unstable-options
|
||||||
|
//@ [future] run-rustfix
|
||||||
|
//@ [future] check-pass
|
||||||
|
|
||||||
|
//@ [future_feature] edition: future
|
||||||
|
//@ [future_feature] compile-flags: -Z unstable-options
|
||||||
|
|
||||||
|
#![cfg_attr(future_feature, feature(explicit_extern_abis))]
|
||||||
|
#![cfg_attr(current_feature, feature(explicit_extern_abis))]
|
||||||
|
|
||||||
|
extern "C" fn _foo() {}
|
||||||
|
//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed
|
||||||
|
|
||||||
|
unsafe extern "C" fn _bar() {}
|
||||||
|
//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed
|
||||||
|
|
||||||
|
unsafe extern "C" {}
|
||||||
|
//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,22 @@
|
||||||
|
warning: `extern` declarations without an explicit ABI are deprecated
|
||||||
|
--> $DIR/feature-gate-explicit-extern-abis.rs:27:1
|
||||||
|
|
|
||||||
|
LL | extern fn _foo() {}
|
||||||
|
| ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
|
||||||
|
|
|
||||||
|
= note: `#[warn(missing_abi)]` on by default
|
||||||
|
|
||||||
|
warning: `extern` declarations without an explicit ABI are deprecated
|
||||||
|
--> $DIR/feature-gate-explicit-extern-abis.rs:33:8
|
||||||
|
|
|
||||||
|
LL | unsafe extern fn _bar() {}
|
||||||
|
| ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
|
||||||
|
|
||||||
|
warning: `extern` declarations without an explicit ABI are deprecated
|
||||||
|
--> $DIR/feature-gate-explicit-extern-abis.rs:39:8
|
||||||
|
|
|
||||||
|
LL | unsafe extern {}
|
||||||
|
| ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
|
||||||
|
|
||||||
|
warning: 3 warnings emitted
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
// The purpose of this feature gate is to make something into a hard error in a
|
||||||
|
// future edition. Consequently, this test differs from most other feature gate
|
||||||
|
// tests. Instead of verifying that an error occurs when the feature gate is
|
||||||
|
// missing, it ensures that the hard error is only produced with the feature
|
||||||
|
// gate is present in the `future` edition -- and otherwise that only a warning
|
||||||
|
// is emitted.
|
||||||
|
|
||||||
|
//@ revisions: current current_feature future future_feature
|
||||||
|
|
||||||
|
//@ [current] run-rustfix
|
||||||
|
//@ [current] check-pass
|
||||||
|
|
||||||
|
//@ [current_feature] run-rustfix
|
||||||
|
//@ [current_feature] check-pass
|
||||||
|
|
||||||
|
//@ [future] edition: future
|
||||||
|
//@ [future] compile-flags: -Z unstable-options
|
||||||
|
//@ [future] run-rustfix
|
||||||
|
//@ [future] check-pass
|
||||||
|
|
||||||
|
//@ [future_feature] edition: future
|
||||||
|
//@ [future_feature] compile-flags: -Z unstable-options
|
||||||
|
|
||||||
|
#![cfg_attr(future_feature, feature(explicit_extern_abis))]
|
||||||
|
#![cfg_attr(current_feature, feature(explicit_extern_abis))]
|
||||||
|
|
||||||
|
extern "C" fn _foo() {}
|
||||||
|
//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed
|
||||||
|
|
||||||
|
unsafe extern "C" fn _bar() {}
|
||||||
|
//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed
|
||||||
|
|
||||||
|
unsafe extern "C" {}
|
||||||
|
//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,22 @@
|
||||||
|
warning: `extern` declarations without an explicit ABI are deprecated
|
||||||
|
--> $DIR/feature-gate-explicit-extern-abis.rs:27:1
|
||||||
|
|
|
||||||
|
LL | extern fn _foo() {}
|
||||||
|
| ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
|
||||||
|
|
|
||||||
|
= note: `#[warn(missing_abi)]` on by default
|
||||||
|
|
||||||
|
warning: `extern` declarations without an explicit ABI are deprecated
|
||||||
|
--> $DIR/feature-gate-explicit-extern-abis.rs:33:8
|
||||||
|
|
|
||||||
|
LL | unsafe extern fn _bar() {}
|
||||||
|
| ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
|
||||||
|
|
||||||
|
warning: `extern` declarations without an explicit ABI are deprecated
|
||||||
|
--> $DIR/feature-gate-explicit-extern-abis.rs:39:8
|
||||||
|
|
|
||||||
|
LL | unsafe extern {}
|
||||||
|
| ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
|
||||||
|
|
||||||
|
warning: 3 warnings emitted
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
// The purpose of this feature gate is to make something into a hard error in a
|
||||||
|
// future edition. Consequently, this test differs from most other feature gate
|
||||||
|
// tests. Instead of verifying that an error occurs when the feature gate is
|
||||||
|
// missing, it ensures that the hard error is only produced with the feature
|
||||||
|
// gate is present in the `future` edition -- and otherwise that only a warning
|
||||||
|
// is emitted.
|
||||||
|
|
||||||
|
//@ revisions: current current_feature future future_feature
|
||||||
|
|
||||||
|
//@ [current] run-rustfix
|
||||||
|
//@ [current] check-pass
|
||||||
|
|
||||||
|
//@ [current_feature] run-rustfix
|
||||||
|
//@ [current_feature] check-pass
|
||||||
|
|
||||||
|
//@ [future] edition: future
|
||||||
|
//@ [future] compile-flags: -Z unstable-options
|
||||||
|
//@ [future] run-rustfix
|
||||||
|
//@ [future] check-pass
|
||||||
|
|
||||||
|
//@ [future_feature] edition: future
|
||||||
|
//@ [future_feature] compile-flags: -Z unstable-options
|
||||||
|
|
||||||
|
#![cfg_attr(future_feature, feature(explicit_extern_abis))]
|
||||||
|
#![cfg_attr(current_feature, feature(explicit_extern_abis))]
|
||||||
|
|
||||||
|
extern "C" fn _foo() {}
|
||||||
|
//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed
|
||||||
|
|
||||||
|
unsafe extern "C" fn _bar() {}
|
||||||
|
//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed
|
||||||
|
|
||||||
|
unsafe extern "C" {}
|
||||||
|
//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,22 @@
|
||||||
|
warning: `extern` declarations without an explicit ABI are deprecated
|
||||||
|
--> $DIR/feature-gate-explicit-extern-abis.rs:27:1
|
||||||
|
|
|
||||||
|
LL | extern fn _foo() {}
|
||||||
|
| ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
|
||||||
|
|
|
||||||
|
= note: `#[warn(missing_abi)]` on by default
|
||||||
|
|
||||||
|
warning: `extern` declarations without an explicit ABI are deprecated
|
||||||
|
--> $DIR/feature-gate-explicit-extern-abis.rs:33:8
|
||||||
|
|
|
||||||
|
LL | unsafe extern fn _bar() {}
|
||||||
|
| ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
|
||||||
|
|
||||||
|
warning: `extern` declarations without an explicit ABI are deprecated
|
||||||
|
--> $DIR/feature-gate-explicit-extern-abis.rs:39:8
|
||||||
|
|
|
||||||
|
LL | unsafe extern {}
|
||||||
|
| ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
|
||||||
|
|
||||||
|
warning: 3 warnings emitted
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
error: `extern` declarations without an explicit ABI are disallowed
|
||||||
|
--> $DIR/feature-gate-explicit-extern-abis.rs:27:1
|
||||||
|
|
|
||||||
|
LL | extern fn _foo() {}
|
||||||
|
| ^^^^^^ help: specify an ABI: `extern "<abi>"`
|
||||||
|
|
|
||||||
|
= help: prior to Rust 2024, a default ABI was inferred
|
||||||
|
|
||||||
|
error: `extern` declarations without an explicit ABI are disallowed
|
||||||
|
--> $DIR/feature-gate-explicit-extern-abis.rs:33:8
|
||||||
|
|
|
||||||
|
LL | unsafe extern fn _bar() {}
|
||||||
|
| ^^^^^^ help: specify an ABI: `extern "<abi>"`
|
||||||
|
|
|
||||||
|
= help: prior to Rust 2024, a default ABI was inferred
|
||||||
|
|
||||||
|
error: `extern` declarations without an explicit ABI are disallowed
|
||||||
|
--> $DIR/feature-gate-explicit-extern-abis.rs:39:8
|
||||||
|
|
|
||||||
|
LL | unsafe extern {}
|
||||||
|
| ^^^^^^ help: specify an ABI: `extern "<abi>"`
|
||||||
|
|
|
||||||
|
= help: prior to Rust 2024, a default ABI was inferred
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
45
tests/ui/feature-gates/feature-gate-explicit-extern-abis.rs
Normal file
45
tests/ui/feature-gates/feature-gate-explicit-extern-abis.rs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// The purpose of this feature gate is to make something into a hard error in a
|
||||||
|
// future edition. Consequently, this test differs from most other feature gate
|
||||||
|
// tests. Instead of verifying that an error occurs when the feature gate is
|
||||||
|
// missing, it ensures that the hard error is only produced with the feature
|
||||||
|
// gate is present in the `future` edition -- and otherwise that only a warning
|
||||||
|
// is emitted.
|
||||||
|
|
||||||
|
//@ revisions: current current_feature future future_feature
|
||||||
|
|
||||||
|
//@ [current] run-rustfix
|
||||||
|
//@ [current] check-pass
|
||||||
|
|
||||||
|
//@ [current_feature] run-rustfix
|
||||||
|
//@ [current_feature] check-pass
|
||||||
|
|
||||||
|
//@ [future] edition: future
|
||||||
|
//@ [future] compile-flags: -Z unstable-options
|
||||||
|
//@ [future] run-rustfix
|
||||||
|
//@ [future] check-pass
|
||||||
|
|
||||||
|
//@ [future_feature] edition: future
|
||||||
|
//@ [future_feature] compile-flags: -Z unstable-options
|
||||||
|
|
||||||
|
#![cfg_attr(future_feature, feature(explicit_extern_abis))]
|
||||||
|
#![cfg_attr(current_feature, feature(explicit_extern_abis))]
|
||||||
|
|
||||||
|
extern fn _foo() {}
|
||||||
|
//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed
|
||||||
|
|
||||||
|
unsafe extern fn _bar() {}
|
||||||
|
//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed
|
||||||
|
|
||||||
|
unsafe extern {}
|
||||||
|
//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -3,7 +3,7 @@ trait X {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
|
fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
|
||||||
//~^ ERROR: lifetime in trait object type must be followed by `+`
|
//~^ ERROR: lifetimes must be followed by `+` to form a trait object type
|
||||||
//~| ERROR: parenthesized generic arguments cannot be used
|
//~| ERROR: parenthesized generic arguments cannot be used
|
||||||
//~| ERROR associated type takes 0 generic arguments but 1 generic argument
|
//~| ERROR associated type takes 0 generic arguments but 1 generic argument
|
||||||
//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
|
//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
error: lifetime in trait object type must be followed by `+`
|
error: lifetimes must be followed by `+` to form a trait object type
|
||||||
--> $DIR/gat-trait-path-parenthesised-args.rs:5:29
|
--> $DIR/gat-trait-path-parenthesised-args.rs:5:29
|
||||||
|
|
|
|
||||||
LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
|
LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
|
||||||
| ^^
|
| ^^
|
||||||
|
|
|
||||||
|
help: consider adding a trait bound after the potential lifetime bound
|
||||||
|
|
|
||||||
|
LL | fn foo<'a>(arg: Box<dyn X<Y('a + /* Trait */) = &'a ()>>) {}
|
||||||
|
| +++++++++++++
|
||||||
|
|
||||||
error: parenthesized generic arguments cannot be used in associated type constraints
|
error: parenthesized generic arguments cannot be used in associated type constraints
|
||||||
--> $DIR/gat-trait-path-parenthesised-args.rs:5:27
|
--> $DIR/gat-trait-path-parenthesised-args.rs:5:27
|
||||||
|
|
|
@ -27,7 +27,7 @@ type A = fn() -> impl A + B;
|
||||||
type A = fn() -> dyn A + B;
|
type A = fn() -> dyn A + B;
|
||||||
//~^ ERROR ambiguous `+` in a type
|
//~^ ERROR ambiguous `+` in a type
|
||||||
type A = fn() -> A + B;
|
type A = fn() -> A + B;
|
||||||
//~^ ERROR expected a path on the left-hand side of `+`, not `fn() -> A`
|
//~^ ERROR expected a path on the left-hand side of `+`
|
||||||
|
|
||||||
type A = Fn() -> impl A +;
|
type A = Fn() -> impl A +;
|
||||||
//~^ ERROR ambiguous `+` in a type
|
//~^ ERROR ambiguous `+` in a type
|
||||||
|
@ -44,6 +44,6 @@ type A = &impl A + B;
|
||||||
type A = &dyn A + B;
|
type A = &dyn A + B;
|
||||||
//~^ ERROR ambiguous `+` in a type
|
//~^ ERROR ambiguous `+` in a type
|
||||||
type A = &A + B;
|
type A = &A + B;
|
||||||
//~^ ERROR expected a path on the left-hand side of `+`, not `&A`
|
//~^ ERROR expected a path on the left-hand side of `+`
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -31,11 +31,13 @@ help: try adding parentheses
|
||||||
LL | type A = fn() -> (dyn A + B);
|
LL | type A = fn() -> (dyn A + B);
|
||||||
| + +
|
| + +
|
||||||
|
|
||||||
error[E0178]: expected a path on the left-hand side of `+`, not `fn() -> A`
|
error[E0178]: expected a path on the left-hand side of `+`
|
||||||
--> $DIR/impl-trait-plus-priority.rs:29:10
|
--> $DIR/impl-trait-plus-priority.rs:29:10
|
||||||
|
|
|
|
||||||
LL | type A = fn() -> A + B;
|
LL | type A = fn() -> A + B;
|
||||||
| ^^^^^^^^^^^^^ perhaps you forgot parentheses?
|
| ^^^^^^^^^----
|
||||||
|
| |
|
||||||
|
| perhaps you forgot parentheses?
|
||||||
|
|
||||||
error: ambiguous `+` in a type
|
error: ambiguous `+` in a type
|
||||||
--> $DIR/impl-trait-plus-priority.rs:32:18
|
--> $DIR/impl-trait-plus-priority.rs:32:18
|
||||||
|
@ -103,11 +105,11 @@ help: try adding parentheses
|
||||||
LL | type A = &(dyn A + B);
|
LL | type A = &(dyn A + B);
|
||||||
| + +
|
| + +
|
||||||
|
|
||||||
error[E0178]: expected a path on the left-hand side of `+`, not `&A`
|
error[E0178]: expected a path on the left-hand side of `+`
|
||||||
--> $DIR/impl-trait-plus-priority.rs:46:10
|
--> $DIR/impl-trait-plus-priority.rs:46:10
|
||||||
|
|
|
|
||||||
LL | type A = &A + B;
|
LL | type A = &A + B;
|
||||||
| ^^^^^^
|
| ^^
|
||||||
|
|
|
|
||||||
help: try adding parentheses
|
help: try adding parentheses
|
||||||
|
|
|
|
||||||
|
|
|
@ -1,53 +1,6 @@
|
||||||
//@ run-pass
|
//@ run-pass
|
||||||
#![feature(intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
|
use std::intrinsics as rusti;
|
||||||
mod rusti {
|
|
||||||
|
|
||||||
#[rustc_intrinsic]
|
|
||||||
pub unsafe fn atomic_cxchg_seqcst_seqcst<T>(dst: *mut T, old: T, src: T) -> (T, bool);
|
|
||||||
#[rustc_intrinsic]
|
|
||||||
pub unsafe fn atomic_cxchg_acquire_acquire<T>(dst: *mut T, old: T, src: T) -> (T, bool);
|
|
||||||
#[rustc_intrinsic]
|
|
||||||
pub unsafe fn atomic_cxchg_release_relaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
|
|
||||||
|
|
||||||
#[rustc_intrinsic]
|
|
||||||
pub unsafe fn atomic_cxchgweak_seqcst_seqcst<T>(dst: *mut T, old: T, src: T) -> (T, bool);
|
|
||||||
#[rustc_intrinsic]
|
|
||||||
pub unsafe fn atomic_cxchgweak_acquire_acquire<T>(dst: *mut T, old: T, src: T) -> (T, bool);
|
|
||||||
#[rustc_intrinsic]
|
|
||||||
pub unsafe fn atomic_cxchgweak_release_relaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
|
|
||||||
|
|
||||||
#[rustc_intrinsic]
|
|
||||||
pub unsafe fn atomic_load_seqcst<T>(src: *const T) -> T;
|
|
||||||
#[rustc_intrinsic]
|
|
||||||
pub unsafe fn atomic_load_acquire<T>(src: *const T) -> T;
|
|
||||||
|
|
||||||
#[rustc_intrinsic]
|
|
||||||
pub unsafe fn atomic_store_seqcst<T>(dst: *mut T, val: T);
|
|
||||||
#[rustc_intrinsic]
|
|
||||||
pub unsafe fn atomic_store_release<T>(dst: *mut T, val: T);
|
|
||||||
|
|
||||||
#[rustc_intrinsic]
|
|
||||||
pub unsafe fn atomic_xchg_seqcst<T>(dst: *mut T, src: T) -> T;
|
|
||||||
#[rustc_intrinsic]
|
|
||||||
pub unsafe fn atomic_xchg_acquire<T>(dst: *mut T, src: T) -> T;
|
|
||||||
#[rustc_intrinsic]
|
|
||||||
pub unsafe fn atomic_xchg_release<T>(dst: *mut T, src: T) -> T;
|
|
||||||
|
|
||||||
#[rustc_intrinsic]
|
|
||||||
pub unsafe fn atomic_xadd_seqcst<T>(dst: *mut T, src: T) -> T;
|
|
||||||
#[rustc_intrinsic]
|
|
||||||
pub unsafe fn atomic_xadd_acquire<T>(dst: *mut T, src: T) -> T;
|
|
||||||
#[rustc_intrinsic]
|
|
||||||
pub unsafe fn atomic_xadd_release<T>(dst: *mut T, src: T) -> T;
|
|
||||||
|
|
||||||
#[rustc_intrinsic]
|
|
||||||
pub unsafe fn atomic_xsub_seqcst<T>(dst: *mut T, src: T) -> T;
|
|
||||||
#[rustc_intrinsic]
|
|
||||||
pub unsafe fn atomic_xsub_acquire<T>(dst: *mut T, src: T) -> T;
|
|
||||||
#[rustc_intrinsic]
|
|
||||||
pub unsafe fn atomic_xsub_release<T>(dst: *mut T, src: T) -> T;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//@ compile-flags: --crate-type rlib
|
//@ compile-flags: --crate-type rlib
|
||||||
|
|
||||||
#[link(name = "libfoo.a", kind = "static")]
|
#[link(name = "libfoo.a", kind = "static")]
|
||||||
extern { } //~ WARN extern declarations without an explicit ABI are deprecated
|
extern { } //~ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
//~| HELP explicitly specify the "C" ABI
|
//~| HELP explicitly specify the "C" ABI
|
||||||
|
|
||||||
pub fn main() { }
|
pub fn main() { }
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
warning: extern declarations without an explicit ABI are deprecated
|
warning: `extern` declarations without an explicit ABI are deprecated
|
||||||
--> $DIR/suggest-libname-only-1.rs:5:1
|
--> $DIR/suggest-libname-only-1.rs:5:1
|
||||||
|
|
|
|
||||||
LL | extern { }
|
LL | extern { }
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//@ compile-flags: --crate-type rlib
|
//@ compile-flags: --crate-type rlib
|
||||||
|
|
||||||
#[link(name = "bar.lib", kind = "static")]
|
#[link(name = "bar.lib", kind = "static")]
|
||||||
extern { } //~ WARN extern declarations without an explicit ABI are deprecated
|
extern { } //~ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
//~| HELP explicitly specify the "C" ABI
|
//~| HELP explicitly specify the "C" ABI
|
||||||
|
|
||||||
pub fn main() { }
|
pub fn main() { }
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
warning: extern declarations without an explicit ABI are deprecated
|
warning: `extern` declarations without an explicit ABI are deprecated
|
||||||
--> $DIR/suggest-libname-only-2.rs:5:1
|
--> $DIR/suggest-libname-only-2.rs:5:1
|
||||||
|
|
|
|
||||||
LL | extern { }
|
LL | extern { }
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error: extern declarations without an explicit ABI are deprecated
|
error: `extern` declarations without an explicit ABI are deprecated
|
||||||
--> $DIR/cli-lint-override.rs:12:1
|
--> $DIR/cli-lint-override.rs:12:1
|
||||||
|
|
|
|
||||||
LL | extern fn foo() {}
|
LL | extern fn foo() {}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
warning: extern declarations without an explicit ABI are deprecated
|
warning: `extern` declarations without an explicit ABI are deprecated
|
||||||
--> $DIR/cli-lint-override.rs:12:1
|
--> $DIR/cli-lint-override.rs:12:1
|
||||||
|
|
|
|
||||||
LL | extern fn foo() {}
|
LL | extern fn foo() {}
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
|
|
||||||
|
|
||||||
extern fn foo() {}
|
extern fn foo() {}
|
||||||
//[warn_deny]~^ ERROR extern declarations without an explicit ABI are deprecated
|
//[warn_deny]~^ ERROR `extern` declarations without an explicit ABI are deprecated
|
||||||
//[forbid_warn]~^^ ERROR extern declarations without an explicit ABI are deprecated
|
//[forbid_warn]~^^ ERROR `extern` declarations without an explicit ABI are deprecated
|
||||||
//[force_warn_deny]~^^^ WARN extern declarations without an explicit ABI are deprecated
|
//[force_warn_deny]~^^^ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error: extern declarations without an explicit ABI are deprecated
|
error: `extern` declarations without an explicit ABI are deprecated
|
||||||
--> $DIR/cli-lint-override.rs:12:1
|
--> $DIR/cli-lint-override.rs:12:1
|
||||||
|
|
|
|
||||||
LL | extern fn foo() {}
|
LL | extern fn foo() {}
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
//@ run-pass
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub fn main() { let _x: isize = 10; }
|
|
25
tests/ui/numbers-arithmetic/isize-base.rs
Normal file
25
tests/ui/numbers-arithmetic/isize-base.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
//! Tests basic `isize` functionality
|
||||||
|
|
||||||
|
//@ run-pass
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
// Literal matches assignment type
|
||||||
|
let a: isize = 42isize;
|
||||||
|
// Literal cast
|
||||||
|
let b: isize = 42 as isize;
|
||||||
|
// Literal type inference from assignment type
|
||||||
|
let c: isize = 42;
|
||||||
|
// Assignment type inference from literal (and later comparison)
|
||||||
|
let d = 42isize;
|
||||||
|
// Function return value type inference
|
||||||
|
let e = return_val();
|
||||||
|
|
||||||
|
assert_eq!(a, b);
|
||||||
|
assert_eq!(a, c);
|
||||||
|
assert_eq!(a, d);
|
||||||
|
assert_eq!(a, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn return_val() -> isize {
|
||||||
|
42
|
||||||
|
}
|
|
@ -1,6 +0,0 @@
|
||||||
//@ run-pass
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub fn main() { let _x: usize = 10 as usize; }
|
|
25
tests/ui/numbers-arithmetic/usize-base.rs
Normal file
25
tests/ui/numbers-arithmetic/usize-base.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
//! Tests basic `usize` functionality
|
||||||
|
|
||||||
|
//@ run-pass
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
// Literal matches assignment type
|
||||||
|
let a: usize = 42usize;
|
||||||
|
// Literal cast
|
||||||
|
let b: usize = 42 as usize;
|
||||||
|
// Literal type inference from assignment type
|
||||||
|
let c: usize = 42;
|
||||||
|
// Assignment type inference from literal (and later comparison)
|
||||||
|
let d = 42usize;
|
||||||
|
// Function return value type inference
|
||||||
|
let e = return_val();
|
||||||
|
|
||||||
|
assert_eq!(a, b);
|
||||||
|
assert_eq!(a, c);
|
||||||
|
assert_eq!(a, d);
|
||||||
|
assert_eq!(a, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn return_val() -> usize {
|
||||||
|
42
|
||||||
|
}
|
|
@ -51,7 +51,7 @@ LL | #[rustc_layout_scalar_valid_range_start(0suffix)]
|
||||||
|
|
|
|
||||||
= help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
|
= help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
|
||||||
|
|
||||||
warning: extern declarations without an explicit ABI are deprecated
|
warning: `extern` declarations without an explicit ABI are deprecated
|
||||||
--> $DIR/bad-lit-suffixes.rs:3:1
|
--> $DIR/bad-lit-suffixes.rs:3:1
|
||||||
|
|
|
|
||||||
LL | extern
|
LL | extern
|
||||||
|
@ -59,7 +59,7 @@ LL | extern
|
||||||
|
|
|
|
||||||
= note: `#[warn(missing_abi)]` on by default
|
= note: `#[warn(missing_abi)]` on by default
|
||||||
|
|
||||||
warning: extern declarations without an explicit ABI are deprecated
|
warning: `extern` declarations without an explicit ABI are deprecated
|
||||||
--> $DIR/bad-lit-suffixes.rs:7:1
|
--> $DIR/bad-lit-suffixes.rs:7:1
|
||||||
|
|
|
|
||||||
LL | extern
|
LL | extern
|
||||||
|
|
|
@ -12,7 +12,7 @@ mac!('a);
|
||||||
|
|
||||||
// avoid false positives
|
// avoid false positives
|
||||||
fn y<'a>(y: &mut 'a + Send) {
|
fn y<'a>(y: &mut 'a + Send) {
|
||||||
//~^ ERROR expected a path on the left-hand side of `+`, not `&mut 'a`
|
//~^ ERROR expected a path on the left-hand side of `+`
|
||||||
//~| ERROR at least one trait is required for an object type
|
//~| ERROR at least one trait is required for an object type
|
||||||
let z = y as &mut 'a + Send;
|
let z = y as &mut 'a + Send;
|
||||||
//~^ ERROR expected value, found trait `Send`
|
//~^ ERROR expected value, found trait `Send`
|
||||||
|
|
|
@ -10,11 +10,11 @@ LL - fn x<'a>(x: &mut 'a i32){}
|
||||||
LL + fn x<'a>(x: &'a mut i32){}
|
LL + fn x<'a>(x: &'a mut i32){}
|
||||||
|
|
|
|
||||||
|
|
||||||
error[E0178]: expected a path on the left-hand side of `+`, not `&mut 'a`
|
error[E0178]: expected a path on the left-hand side of `+`
|
||||||
--> $DIR/issue-73568-lifetime-after-mut.rs:14:13
|
--> $DIR/issue-73568-lifetime-after-mut.rs:14:13
|
||||||
|
|
|
|
||||||
LL | fn y<'a>(y: &mut 'a + Send) {
|
LL | fn y<'a>(y: &mut 'a + Send) {
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
|
|
||||||
help: try adding parentheses
|
help: try adding parentheses
|
||||||
|
|
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ error: suffixes on string literals are invalid
|
||||||
LL | f!("Foo"__);
|
LL | f!("Foo"__);
|
||||||
| ^^^^^^^ invalid suffix `__`
|
| ^^^^^^^ invalid suffix `__`
|
||||||
|
|
||||||
warning: extern declarations without an explicit ABI are deprecated
|
warning: `extern` declarations without an explicit ABI are deprecated
|
||||||
--> $DIR/lit-err-in-macro.rs:3:9
|
--> $DIR/lit-err-in-macro.rs:3:9
|
||||||
|
|
|
|
||||||
LL | extern $abi fn f() {}
|
LL | extern $abi fn f() {}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
error: lifetimes must be followed by `+` to form a trait object type
|
||||||
|
--> $DIR/trait-object-macro-matcher.rs:17:8
|
||||||
|
|
|
||||||
|
LL | m!('static);
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
help: consider adding a trait bound after the potential lifetime bound
|
||||||
|
|
|
||||||
|
LL | m!('static + /* Trait */);
|
||||||
|
| +++++++++++++
|
||||||
|
|
||||||
|
error: lifetimes must be followed by `+` to form a trait object type
|
||||||
|
--> $DIR/trait-object-macro-matcher.rs:17:8
|
||||||
|
|
|
||||||
|
LL | m!('static);
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
help: consider adding a trait bound after the potential lifetime bound
|
||||||
|
|
|
||||||
|
LL | m!('static + /* Trait */);
|
||||||
|
| +++++++++++++
|
||||||
|
|
||||||
|
error[E0224]: at least one trait is required for an object type
|
||||||
|
--> $DIR/trait-object-macro-matcher.rs:17:8
|
||||||
|
|
|
||||||
|
LL | m!('static);
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0224`.
|
|
@ -0,0 +1,16 @@
|
||||||
|
error: expected type, found lifetime
|
||||||
|
--> $DIR/trait-object-macro-matcher.rs:17:8
|
||||||
|
|
|
||||||
|
LL | m!('static);
|
||||||
|
| ^^^^^^^ expected type
|
||||||
|
|
||||||
|
error: expected type, found lifetime
|
||||||
|
--> $DIR/trait-object-macro-matcher.rs:17:8
|
||||||
|
|
|
||||||
|
LL | m!('static);
|
||||||
|
| ^^^^^^^ expected type
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
// A single lifetime is not parsed as a type.
|
// A single lifetime is not parsed as a type.
|
||||||
// `ty` matcher in particular doesn't accept a single lifetime
|
// `ty` matcher in particular doesn't accept a single lifetime
|
||||||
|
|
||||||
|
//@ revisions: e2015 e2021
|
||||||
|
//@[e2015] edition: 2015
|
||||||
|
//@[e2021] edition: 2021
|
||||||
|
|
||||||
macro_rules! m {
|
macro_rules! m {
|
||||||
($t: ty) => {
|
($t: ty) => {
|
||||||
let _: $t;
|
let _: $t;
|
||||||
|
@ -8,8 +12,10 @@ macro_rules! m {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
//[e2021]~vv ERROR expected type, found lifetime
|
||||||
|
//[e2021]~v ERROR expected type, found lifetime
|
||||||
m!('static);
|
m!('static);
|
||||||
//~^ ERROR lifetime in trait object type must be followed by `+`
|
//[e2015]~^ ERROR lifetimes must be followed by `+` to form a trait object type
|
||||||
//~| ERROR lifetime in trait object type must be followed by `+`
|
//[e2015]~| ERROR lifetimes must be followed by `+` to form a trait object type
|
||||||
//~| ERROR at least one trait is required for an object type
|
//[e2015]~| ERROR at least one trait is required for an object type
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
error: lifetime in trait object type must be followed by `+`
|
|
||||||
--> $DIR/trait-object-macro-matcher.rs:11:8
|
|
||||||
|
|
|
||||||
LL | m!('static);
|
|
||||||
| ^^^^^^^
|
|
||||||
|
|
||||||
error: lifetime in trait object type must be followed by `+`
|
|
||||||
--> $DIR/trait-object-macro-matcher.rs:11:8
|
|
||||||
|
|
|
||||||
LL | m!('static);
|
|
||||||
| ^^^^^^^
|
|
||||||
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error[E0224]: at least one trait is required for an object type
|
|
||||||
--> $DIR/trait-object-macro-matcher.rs:11:8
|
|
||||||
|
|
|
||||||
LL | m!('static);
|
|
||||||
| ^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0224`.
|
|
13
tests/ui/parser/recover/recover-ampersand-less-ref-ty.rs
Normal file
13
tests/ui/parser/recover/recover-ampersand-less-ref-ty.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
//@ edition: 2021
|
||||||
|
|
||||||
|
struct Entity<'a> {
|
||||||
|
name: 'a str, //~ ERROR expected type, found lifetime
|
||||||
|
//~^ HELP you might have meant to write a reference type here
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Buffer<'buf> {
|
||||||
|
bytes: 'buf mut [u8], //~ ERROR expected type, found lifetime
|
||||||
|
//~^ HELP you might have meant to write a reference type here
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
24
tests/ui/parser/recover/recover-ampersand-less-ref-ty.stderr
Normal file
24
tests/ui/parser/recover/recover-ampersand-less-ref-ty.stderr
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
error: expected type, found lifetime
|
||||||
|
--> $DIR/recover-ampersand-less-ref-ty.rs:4:11
|
||||||
|
|
|
||||||
|
LL | name: 'a str,
|
||||||
|
| ^^ expected type
|
||||||
|
|
|
||||||
|
help: you might have meant to write a reference type here
|
||||||
|
|
|
||||||
|
LL | name: &'a str,
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: expected type, found lifetime
|
||||||
|
--> $DIR/recover-ampersand-less-ref-ty.rs:9:12
|
||||||
|
|
|
||||||
|
LL | bytes: 'buf mut [u8],
|
||||||
|
| ^^^^ expected type
|
||||||
|
|
|
||||||
|
help: you might have meant to write a reference type here
|
||||||
|
|
|
||||||
|
LL | bytes: &'buf mut [u8],
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
|
@ -5,12 +5,8 @@
|
||||||
auto trait Auto {}
|
auto trait Auto {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _: Box<((Auto)) + Auto>;
|
let _: Box<((Auto)) + Auto>; //~ ERROR expected a path on the left-hand side of `+`
|
||||||
//~^ ERROR expected a path on the left-hand side of `+`, not `((Auto))`
|
let _: Box<(Auto + Auto) + Auto>; //~ ERROR expected a path on the left-hand side of `+`
|
||||||
let _: Box<(Auto + Auto) + Auto>;
|
let _: Box<(Auto +) + Auto>; //~ ERROR expected a path on the left-hand side of `+`
|
||||||
//~^ ERROR expected a path on the left-hand side of `+`, not `(Auto + Auto)`
|
let _: Box<(dyn Auto) + Auto>; //~ ERROR expected a path on the left-hand side of `+`
|
||||||
let _: Box<(Auto +) + Auto>;
|
|
||||||
//~^ ERROR expected a path on the left-hand side of `+`, not `(Auto)`
|
|
||||||
let _: Box<(dyn Auto) + Auto>;
|
|
||||||
//~^ ERROR expected a path on the left-hand side of `+`, not `(dyn Auto)`
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
error[E0178]: expected a path on the left-hand side of `+`, not `((Auto))`
|
error[E0178]: expected a path on the left-hand side of `+`
|
||||||
--> $DIR/trait-object-bad-parens.rs:8:16
|
--> $DIR/trait-object-bad-parens.rs:8:16
|
||||||
|
|
|
|
||||||
LL | let _: Box<((Auto)) + Auto>;
|
LL | let _: Box<((Auto)) + Auto>;
|
||||||
| ^^^^^^^^^^^^^^^ expected a path
|
| ^^^^^^^^ expected a path
|
||||||
|
|
||||||
error[E0178]: expected a path on the left-hand side of `+`, not `(Auto + Auto)`
|
error[E0178]: expected a path on the left-hand side of `+`
|
||||||
--> $DIR/trait-object-bad-parens.rs:10:16
|
--> $DIR/trait-object-bad-parens.rs:9:16
|
||||||
|
|
|
|
||||||
LL | let _: Box<(Auto + Auto) + Auto>;
|
LL | let _: Box<(Auto + Auto) + Auto>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ expected a path
|
| ^^^^^^^^^^^^^ expected a path
|
||||||
|
|
||||||
error[E0178]: expected a path on the left-hand side of `+`, not `(Auto)`
|
error[E0178]: expected a path on the left-hand side of `+`
|
||||||
--> $DIR/trait-object-bad-parens.rs:12:16
|
--> $DIR/trait-object-bad-parens.rs:10:16
|
||||||
|
|
|
|
||||||
LL | let _: Box<(Auto +) + Auto>;
|
LL | let _: Box<(Auto +) + Auto>;
|
||||||
| ^^^^^^^^^^^^^^^ expected a path
|
| ^^^^^^^^ expected a path
|
||||||
|
|
||||||
error[E0178]: expected a path on the left-hand side of `+`, not `(dyn Auto)`
|
error[E0178]: expected a path on the left-hand side of `+`
|
||||||
--> $DIR/trait-object-bad-parens.rs:14:16
|
--> $DIR/trait-object-bad-parens.rs:11:16
|
||||||
|
|
|
|
||||||
LL | let _: Box<(dyn Auto) + Auto>;
|
LL | let _: Box<(dyn Auto) + Auto>;
|
||||||
| ^^^^^^^^^^^^^^^^^ expected a path
|
| ^^^^^^^^^^ expected a path
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: parenthesized lifetime bounds are not supported
|
error: parenthesized lifetime bounds are not supported
|
||||||
--> $DIR/trait-object-lifetime-parens.rs:5:21
|
--> $DIR/trait-object-lifetime-parens.rs:9:21
|
||||||
|
|
|
|
||||||
LL | fn f<'a, T: Trait + ('a)>() {}
|
LL | fn f<'a, T: Trait + ('a)>() {}
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
@ -11,7 +11,7 @@ LL + fn f<'a, T: Trait + 'a>() {}
|
||||||
|
|
|
|
||||||
|
|
||||||
error: parenthesized lifetime bounds are not supported
|
error: parenthesized lifetime bounds are not supported
|
||||||
--> $DIR/trait-object-lifetime-parens.rs:8:24
|
--> $DIR/trait-object-lifetime-parens.rs:12:24
|
||||||
|
|
|
|
||||||
LL | let _: Box<Trait + ('a)>;
|
LL | let _: Box<Trait + ('a)>;
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
@ -22,11 +22,16 @@ LL - let _: Box<Trait + ('a)>;
|
||||||
LL + let _: Box<Trait + 'a>;
|
LL + let _: Box<Trait + 'a>;
|
||||||
|
|
|
|
||||||
|
|
||||||
error: lifetime in trait object type must be followed by `+`
|
error: lifetimes must be followed by `+` to form a trait object type
|
||||||
--> $DIR/trait-object-lifetime-parens.rs:10:17
|
--> $DIR/trait-object-lifetime-parens.rs:16:17
|
||||||
|
|
|
|
||||||
LL | let _: Box<('a) + Trait>;
|
LL | let _: Box<('a) + Trait>;
|
||||||
| ^^
|
| ^^
|
||||||
|
|
|
||||||
|
help: consider adding a trait bound after the potential lifetime bound
|
||||||
|
|
|
||||||
|
LL | let _: Box<('a + /* Trait */) + Trait>;
|
||||||
|
| +++++++++++++
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
51
tests/ui/parser/trait-object-lifetime-parens.e2021.stderr
Normal file
51
tests/ui/parser/trait-object-lifetime-parens.e2021.stderr
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
error: parenthesized lifetime bounds are not supported
|
||||||
|
--> $DIR/trait-object-lifetime-parens.rs:9:21
|
||||||
|
|
|
||||||
|
LL | fn f<'a, T: Trait + ('a)>() {}
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
help: remove the parentheses
|
||||||
|
|
|
||||||
|
LL - fn f<'a, T: Trait + ('a)>() {}
|
||||||
|
LL + fn f<'a, T: Trait + 'a>() {}
|
||||||
|
|
|
||||||
|
|
||||||
|
error: parenthesized lifetime bounds are not supported
|
||||||
|
--> $DIR/trait-object-lifetime-parens.rs:12:24
|
||||||
|
|
|
||||||
|
LL | let _: Box<Trait + ('a)>;
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
help: remove the parentheses
|
||||||
|
|
|
||||||
|
LL - let _: Box<Trait + ('a)>;
|
||||||
|
LL + let _: Box<Trait + 'a>;
|
||||||
|
|
|
||||||
|
|
||||||
|
error: expected type, found lifetime
|
||||||
|
--> $DIR/trait-object-lifetime-parens.rs:16:17
|
||||||
|
|
|
||||||
|
LL | let _: Box<('a) + Trait>;
|
||||||
|
| ^^ expected type
|
||||||
|
|
||||||
|
error[E0178]: expected a path on the left-hand side of `+`
|
||||||
|
--> $DIR/trait-object-lifetime-parens.rs:16:16
|
||||||
|
|
|
||||||
|
LL | let _: Box<('a) + Trait>;
|
||||||
|
| ^^^^ expected a path
|
||||||
|
|
||||||
|
error[E0782]: expected a type, found a trait
|
||||||
|
--> $DIR/trait-object-lifetime-parens.rs:12:16
|
||||||
|
|
|
||||||
|
LL | let _: Box<Trait + ('a)>;
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: you can add the `dyn` keyword if you want a trait object
|
||||||
|
|
|
||||||
|
LL | let _: Box<dyn Trait + ('a)>;
|
||||||
|
| +++
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0178, E0782.
|
||||||
|
For more information about an error, try `rustc --explain E0178`.
|
|
@ -1,4 +1,8 @@
|
||||||
#![allow(bare_trait_objects)]
|
//@ revisions: e2015 e2021
|
||||||
|
//@[e2015] edition: 2015
|
||||||
|
//@[e2021] edition: 2021
|
||||||
|
|
||||||
|
#![cfg_attr(e2015, allow(bare_trait_objects))]
|
||||||
|
|
||||||
trait Trait {}
|
trait Trait {}
|
||||||
|
|
||||||
|
@ -6,8 +10,12 @@ fn f<'a, T: Trait + ('a)>() {} //~ ERROR parenthesized lifetime bounds are not s
|
||||||
|
|
||||||
fn check<'a>() {
|
fn check<'a>() {
|
||||||
let _: Box<Trait + ('a)>; //~ ERROR parenthesized lifetime bounds are not supported
|
let _: Box<Trait + ('a)>; //~ ERROR parenthesized lifetime bounds are not supported
|
||||||
// FIXME: It'd be great if we could add suggestion to the following case.
|
//[e2021]~^ ERROR expected a type, found a trait
|
||||||
let _: Box<('a) + Trait>; //~ ERROR lifetime in trait object type must be followed by `+`
|
// FIXME: It'd be great if we could suggest removing the parentheses here too.
|
||||||
|
//[e2015]~v ERROR lifetimes must be followed by `+` to form a trait object type
|
||||||
|
let _: Box<('a) + Trait>;
|
||||||
|
//[e2021]~^ ERROR expected type, found lifetime
|
||||||
|
//[e2021]~| ERROR expected a path on the left-hand side of `+`
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -4,6 +4,6 @@ trait Trait<'a> {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _: &for<'a> Trait<'a> + 'static;
|
let _: &for<'a> Trait<'a> + 'static;
|
||||||
//~^ ERROR expected a path on the left-hand side of `+`, not `&for<'a> Trait<'a>`
|
//~^ ERROR expected a path on the left-hand side of `+`
|
||||||
//~| HELP try adding parentheses
|
//~| HELP try adding parentheses
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0178]: expected a path on the left-hand side of `+`, not `&for<'a> Trait<'a>`
|
error[E0178]: expected a path on the left-hand side of `+`
|
||||||
--> $DIR/trait-object-polytrait-priority.rs:6:12
|
--> $DIR/trait-object-polytrait-priority.rs:6:12
|
||||||
|
|
|
|
||||||
LL | let _: &for<'a> Trait<'a> + 'static;
|
LL | let _: &for<'a> Trait<'a> + 'static;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
help: try adding parentheses
|
help: try adding parentheses
|
||||||
|
|
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ fn bar() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern { //~ WARN extern declarations without an explicit ABI are deprecated
|
extern { //~ WARN `extern` declarations without an explicit ABI are deprecated
|
||||||
fn weird_extern() {
|
fn weird_extern() {
|
||||||
#![print_target_and_args_consume(tenth)]
|
#![print_target_and_args_consume(tenth)]
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ error: expected non-macro inner attribute, found attribute macro `print_attr`
|
||||||
LL | #![print_attr]
|
LL | #![print_attr]
|
||||||
| ^^^^^^^^^^ not a non-macro inner attribute
|
| ^^^^^^^^^^ not a non-macro inner attribute
|
||||||
|
|
||||||
warning: extern declarations without an explicit ABI are deprecated
|
warning: `extern` declarations without an explicit ABI are deprecated
|
||||||
--> $DIR/inner-attrs.rs:85:1
|
--> $DIR/inner-attrs.rs:85:1
|
||||||
|
|
|
|
||||||
LL | extern {
|
LL | extern {
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
//@ revisions: current next
|
||||||
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
// Regression test for trait-system-refactor-initiative#176.
|
||||||
|
//
|
||||||
|
// Normalizing `<Vec<T> as IntoIterator>::IntoIter` has two candidates
|
||||||
|
// inside of the function:
|
||||||
|
// - `impl<T> IntoIterator for Vec<T>` which trivially applies
|
||||||
|
// - `impl<I: Iterator> IntoIterator for I`
|
||||||
|
// - requires `Vec<T>: Iterator`
|
||||||
|
// - where-clause requires `<Vec<T> as IntoIterator>::IntoIter eq Vec<T>`
|
||||||
|
// - normalize `<Vec<T> as IntoIterator>::IntoIter` again, cycle
|
||||||
|
//
|
||||||
|
// We need to treat this cycle as an error to be able to use the actual impl.
|
||||||
|
|
||||||
|
fn test<T>()
|
||||||
|
where
|
||||||
|
<Vec<T> as IntoIterator>::IntoIter: Iterator,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,48 @@
|
||||||
|
error[E0277]: the trait bound `Foo: Bound` is not satisfied
|
||||||
|
--> $DIR/normalizes-to-is-not-productive.rs:41:1
|
||||||
|
|
|
||||||
|
LL | / fn generic<T>()
|
||||||
|
LL | | where
|
||||||
|
LL | | <Foo as Trait<T>>::Assoc: Bound,
|
||||||
|
| |____________________________________^ the trait `Bound` is not implemented for `Foo`
|
||||||
|
|
|
||||||
|
= help: the trait `Bound` is implemented for `u32`
|
||||||
|
note: required for `Foo` to implement `Trait<T>`
|
||||||
|
--> $DIR/normalizes-to-is-not-productive.rs:24:19
|
||||||
|
|
|
||||||
|
LL | impl<T: Bound, U> Trait<U> for T {
|
||||||
|
| ----- ^^^^^^^^ ^
|
||||||
|
| |
|
||||||
|
| unsatisfied trait bound introduced here
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `Foo: Bound` is not satisfied
|
||||||
|
--> $DIR/normalizes-to-is-not-productive.rs:41:4
|
||||||
|
|
|
||||||
|
LL | fn generic<T>()
|
||||||
|
| ^^^^^^^ the trait `Bound` is not implemented for `Foo`
|
||||||
|
|
|
||||||
|
= help: the trait `Bound` is implemented for `u32`
|
||||||
|
note: required for `Foo` to implement `Trait<T>`
|
||||||
|
--> $DIR/normalizes-to-is-not-productive.rs:24:19
|
||||||
|
|
|
||||||
|
LL | impl<T: Bound, U> Trait<U> for T {
|
||||||
|
| ----- ^^^^^^^^ ^
|
||||||
|
| |
|
||||||
|
| unsatisfied trait bound introduced here
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `Foo: Bound` is not satisfied
|
||||||
|
--> $DIR/normalizes-to-is-not-productive.rs:48:19
|
||||||
|
|
|
||||||
|
LL | impls_bound::<Foo>();
|
||||||
|
| ^^^ the trait `Bound` is not implemented for `Foo`
|
||||||
|
|
|
||||||
|
= help: the trait `Bound` is implemented for `u32`
|
||||||
|
note: required by a bound in `impls_bound`
|
||||||
|
--> $DIR/normalizes-to-is-not-productive.rs:28:19
|
||||||
|
|
|
||||||
|
LL | fn impls_bound<T: Bound>() {
|
||||||
|
| ^^^^^ required by this bound in `impls_bound`
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
|
@ -0,0 +1,31 @@
|
||||||
|
error[E0277]: the trait bound `Foo: Bound` is not satisfied
|
||||||
|
--> $DIR/normalizes-to-is-not-productive.rs:43:31
|
||||||
|
|
|
||||||
|
LL | <Foo as Trait<T>>::Assoc: Bound,
|
||||||
|
| ^^^^^ the trait `Bound` is not implemented for `Foo`
|
||||||
|
|
|
||||||
|
= help: the trait `Bound` is implemented for `u32`
|
||||||
|
note: required for `Foo` to implement `Trait<T>`
|
||||||
|
--> $DIR/normalizes-to-is-not-productive.rs:24:19
|
||||||
|
|
|
||||||
|
LL | impl<T: Bound, U> Trait<U> for T {
|
||||||
|
| ----- ^^^^^^^^ ^
|
||||||
|
| |
|
||||||
|
| unsatisfied trait bound introduced here
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `Foo: Bound` is not satisfied
|
||||||
|
--> $DIR/normalizes-to-is-not-productive.rs:48:19
|
||||||
|
|
|
||||||
|
LL | impls_bound::<Foo>();
|
||||||
|
| ^^^ the trait `Bound` is not implemented for `Foo`
|
||||||
|
|
|
||||||
|
= help: the trait `Bound` is implemented for `u32`
|
||||||
|
note: required by a bound in `impls_bound`
|
||||||
|
--> $DIR/normalizes-to-is-not-productive.rs:28:19
|
||||||
|
|
|
||||||
|
LL | fn impls_bound<T: Bound>() {
|
||||||
|
| ^^^^^ required by this bound in `impls_bound`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
|
@ -0,0 +1,54 @@
|
||||||
|
//@ ignore-compare-mode-next-solver (explicit)
|
||||||
|
//@ compile-flags: -Znext-solver
|
||||||
|
|
||||||
|
// Make sure that stepping into impl where-clauses of `NormalizesTo`
|
||||||
|
// goals is unproductive. This must not compile, see the inline
|
||||||
|
// comments.
|
||||||
|
|
||||||
|
trait Bound {
|
||||||
|
fn method();
|
||||||
|
}
|
||||||
|
impl Bound for u32 {
|
||||||
|
fn method() {}
|
||||||
|
}
|
||||||
|
trait Trait<T> {
|
||||||
|
type Assoc: Bound;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
impl Trait<u32> for Foo {
|
||||||
|
type Assoc = u32;
|
||||||
|
}
|
||||||
|
impl<T: Bound, U> Trait<U> for T {
|
||||||
|
type Assoc = T;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn impls_bound<T: Bound>() {
|
||||||
|
T::method();
|
||||||
|
}
|
||||||
|
|
||||||
|
// The where-clause requires `Foo: Trait<T>` to hold to be wf.
|
||||||
|
// If stepping into where-clauses during normalization is considered
|
||||||
|
// to be productive, this would be the case:
|
||||||
|
//
|
||||||
|
// - `Foo: Trait<T>`
|
||||||
|
// - via blanket impls, requires `Foo: Bound`
|
||||||
|
// - via where-bound, requires `Foo eq <Foo as Trait<T>>::Assoc`
|
||||||
|
// - normalize `<Foo as Trait<T>>::Assoc`
|
||||||
|
// - via blanket impl, requires where-clause `Foo: Bound` -> cycle
|
||||||
|
fn generic<T>()
|
||||||
|
where
|
||||||
|
<Foo as Trait<T>>::Assoc: Bound,
|
||||||
|
//~^ ERROR the trait bound `Foo: Bound` is not satisfied
|
||||||
|
{
|
||||||
|
// Requires proving `Foo: Bound` by normalizing
|
||||||
|
// `<Foo as Trait<T>>::Assoc` to `Foo`.
|
||||||
|
impls_bound::<Foo>();
|
||||||
|
//~^ ERROR the trait bound `Foo: Bound` is not satisfied
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
// Requires proving `<Foo as Trait<u32>>::Assoc: Bound`.
|
||||||
|
// This is trivially true.
|
||||||
|
generic::<u32>();
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
error[E0277]: the trait bound `Foo: Bound` is not satisfied
|
||||||
|
--> $DIR/normalizes-to-is-not-productive.rs:42:31
|
||||||
|
|
|
||||||
|
LL | <Foo as Trait<T>>::Assoc: Bound,
|
||||||
|
| ^^^^^ the trait `Bound` is not implemented for `Foo`
|
||||||
|
|
|
||||||
|
= help: the trait `Bound` is implemented for `u32`
|
||||||
|
note: required for `Foo` to implement `Trait<T>`
|
||||||
|
--> $DIR/normalizes-to-is-not-productive.rs:23:19
|
||||||
|
|
|
||||||
|
LL | impl<T: Bound, U> Trait<U> for T {
|
||||||
|
| ----- ^^^^^^^^ ^
|
||||||
|
| |
|
||||||
|
| unsatisfied trait bound introduced here
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `Foo: Bound` is not satisfied
|
||||||
|
--> $DIR/normalizes-to-is-not-productive.rs:47:19
|
||||||
|
|
|
||||||
|
LL | impls_bound::<Foo>();
|
||||||
|
| ^^^ the trait `Bound` is not implemented for `Foo`
|
||||||
|
|
|
||||||
|
= help: the trait `Bound` is implemented for `u32`
|
||||||
|
note: required by a bound in `impls_bound`
|
||||||
|
--> $DIR/normalizes-to-is-not-productive.rs:27:19
|
||||||
|
|
|
||||||
|
LL | fn impls_bound<T: Bound>() {
|
||||||
|
| ^^^^^ required by this bound in `impls_bound`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Add table
Add a link
Reference in a new issue