Auto merge of #119927 - matthiaskrgr:rollup-885ws57, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #119587 (Varargs support for system ABI) - #119891 (rename `reported_signature_mismatch` to reflect its use) - #119894 (Allow `~const` on associated type bounds again) - #119896 (Taint `_` placeholder types in trait impl method signatures) - #119898 (Remove unused `ErrorReporting` variant from overflow handling) - #119902 (fix typo in `fn()` docs) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
c6c4abf584
33 changed files with 289 additions and 104 deletions
|
@ -232,6 +232,9 @@ ast_passes_tilde_const_disallowed = `~const` is not allowed here
|
||||||
.trait = this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds
|
.trait = this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds
|
||||||
.trait_impl = this impl is not `const`, so it cannot have `~const` trait bounds
|
.trait_impl = this impl is not `const`, so it cannot have `~const` trait bounds
|
||||||
.impl = inherent impls cannot have `~const` trait bounds
|
.impl = inherent impls cannot have `~const` trait bounds
|
||||||
|
.trait_assoc_ty = associated types in non-`#[const_trait]` traits cannot have `~const` trait bounds
|
||||||
|
.trait_impl_assoc_ty = associated types in non-const impls cannot have `~const` trait bounds
|
||||||
|
.inherent_assoc_ty = inherent associated types cannot have `~const` trait bounds
|
||||||
.object = trait objects cannot have `~const` trait bounds
|
.object = trait objects cannot have `~const` trait bounds
|
||||||
.item = this item cannot have `~const` trait bounds
|
.item = this item cannot have `~const` trait bounds
|
||||||
|
|
||||||
|
|
|
@ -37,12 +37,17 @@ enum SelfSemantic {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// What is the context that prevents using `~const`?
|
/// What is the context that prevents using `~const`?
|
||||||
|
// FIXME(effects): Consider getting rid of this in favor of `errors::TildeConstReason`, they're
|
||||||
|
// almost identical. This gets rid of an abstraction layer which might be considered bad.
|
||||||
enum DisallowTildeConstContext<'a> {
|
enum DisallowTildeConstContext<'a> {
|
||||||
TraitObject,
|
TraitObject,
|
||||||
Fn(FnKind<'a>),
|
Fn(FnKind<'a>),
|
||||||
Trait(Span),
|
Trait(Span),
|
||||||
TraitImpl(Span),
|
TraitImpl(Span),
|
||||||
Impl(Span),
|
Impl(Span),
|
||||||
|
TraitAssocTy(Span),
|
||||||
|
TraitImplAssocTy(Span),
|
||||||
|
InherentAssocTy(Span),
|
||||||
Item,
|
Item,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,6 +321,7 @@ impl<'a> AstValidator<'a> {
|
||||||
constness: Const::No,
|
constness: Const::No,
|
||||||
polarity: ImplPolarity::Positive,
|
polarity: ImplPolarity::Positive,
|
||||||
trait_ref,
|
trait_ref,
|
||||||
|
..
|
||||||
} = parent
|
} = parent
|
||||||
{
|
{
|
||||||
Some(trait_ref.path.span.shrink_to_lo())
|
Some(trait_ref.path.span.shrink_to_lo())
|
||||||
|
@ -1286,6 +1292,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
// suggestion for moving such bounds to the assoc const fns if available.
|
// suggestion for moving such bounds to the assoc const fns if available.
|
||||||
errors::TildeConstReason::Impl { span }
|
errors::TildeConstReason::Impl { span }
|
||||||
}
|
}
|
||||||
|
&DisallowTildeConstContext::TraitAssocTy(span) => {
|
||||||
|
errors::TildeConstReason::TraitAssocTy { span }
|
||||||
|
}
|
||||||
|
&DisallowTildeConstContext::TraitImplAssocTy(span) => {
|
||||||
|
errors::TildeConstReason::TraitImplAssocTy { span }
|
||||||
|
}
|
||||||
|
&DisallowTildeConstContext::InherentAssocTy(span) => {
|
||||||
|
errors::TildeConstReason::InherentAssocTy { span }
|
||||||
|
}
|
||||||
DisallowTildeConstContext::TraitObject => {
|
DisallowTildeConstContext::TraitObject => {
|
||||||
errors::TildeConstReason::TraitObject
|
errors::TildeConstReason::TraitObject
|
||||||
}
|
}
|
||||||
|
@ -1483,13 +1498,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
self.check_item_named(item.ident, "const");
|
self.check_item_named(item.ident, "const");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let parent_is_const =
|
||||||
|
self.outer_trait_or_trait_impl.as_ref().and_then(TraitOrTraitImpl::constness).is_some();
|
||||||
|
|
||||||
match &item.kind {
|
match &item.kind {
|
||||||
AssocItemKind::Fn(box Fn { sig, generics, body, .. })
|
AssocItemKind::Fn(box Fn { sig, generics, body, .. })
|
||||||
if self
|
if parent_is_const
|
||||||
.outer_trait_or_trait_impl
|
|
||||||
.as_ref()
|
|
||||||
.and_then(TraitOrTraitImpl::constness)
|
|
||||||
.is_some()
|
|
||||||
|| ctxt == AssocCtxt::Trait
|
|| ctxt == AssocCtxt::Trait
|
||||||
|| matches!(sig.header.constness, Const::Yes(_)) =>
|
|| matches!(sig.header.constness, Const::Yes(_)) =>
|
||||||
{
|
{
|
||||||
|
@ -1505,6 +1519,20 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
);
|
);
|
||||||
self.visit_fn(kind, item.span, item.id);
|
self.visit_fn(kind, item.span, item.id);
|
||||||
}
|
}
|
||||||
|
AssocItemKind::Type(_) => {
|
||||||
|
let disallowed = (!parent_is_const).then(|| match self.outer_trait_or_trait_impl {
|
||||||
|
Some(TraitOrTraitImpl::Trait { .. }) => {
|
||||||
|
DisallowTildeConstContext::TraitAssocTy(item.span)
|
||||||
|
}
|
||||||
|
Some(TraitOrTraitImpl::TraitImpl { .. }) => {
|
||||||
|
DisallowTildeConstContext::TraitImplAssocTy(item.span)
|
||||||
|
}
|
||||||
|
None => DisallowTildeConstContext::InherentAssocTy(item.span),
|
||||||
|
});
|
||||||
|
self.with_tilde_const(disallowed, |this| {
|
||||||
|
this.with_in_trait_impl(None, |this| visit::walk_assoc_item(this, item, ctxt))
|
||||||
|
})
|
||||||
|
}
|
||||||
_ => self.with_in_trait_impl(None, |this| visit::walk_assoc_item(this, item, ctxt)),
|
_ => self.with_in_trait_impl(None, |this| visit::walk_assoc_item(this, item, ctxt)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -565,6 +565,8 @@ pub struct ConstBoundTraitObject {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME(effects): Consider making the note/reason the message of the diagnostic.
|
||||||
|
// FIXME(effects): Provide structured suggestions (e.g., add `const` / `#[const_trait]` here).
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_tilde_const_disallowed)]
|
#[diag(ast_passes_tilde_const_disallowed)]
|
||||||
pub struct TildeConstDisallowed {
|
pub struct TildeConstDisallowed {
|
||||||
|
@ -598,6 +600,21 @@ pub enum TildeConstReason {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
span: Span,
|
span: Span,
|
||||||
},
|
},
|
||||||
|
#[note(ast_passes_trait_assoc_ty)]
|
||||||
|
TraitAssocTy {
|
||||||
|
#[primary_span]
|
||||||
|
span: Span,
|
||||||
|
},
|
||||||
|
#[note(ast_passes_trait_impl_assoc_ty)]
|
||||||
|
TraitImplAssocTy {
|
||||||
|
#[primary_span]
|
||||||
|
span: Span,
|
||||||
|
},
|
||||||
|
#[note(ast_passes_inherent_assoc_ty)]
|
||||||
|
InherentAssocTy {
|
||||||
|
#[primary_span]
|
||||||
|
span: Span,
|
||||||
|
},
|
||||||
#[note(ast_passes_object)]
|
#[note(ast_passes_object)]
|
||||||
TraitObject,
|
TraitObject,
|
||||||
#[note(ast_passes_item)]
|
#[note(ast_passes_item)]
|
||||||
|
|
|
@ -2659,7 +2659,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
self.suggest_trait_fn_ty_for_impl_fn_infer(hir_id, Some(i))
|
self.suggest_trait_fn_ty_for_impl_fn_infer(hir_id, Some(i))
|
||||||
{
|
{
|
||||||
infer_replacements.push((a.span, suggested_ty.to_string()));
|
infer_replacements.push((a.span, suggested_ty.to_string()));
|
||||||
return suggested_ty;
|
return Ty::new_error_with_message(
|
||||||
|
self.tcx(),
|
||||||
|
a.span,
|
||||||
|
suggested_ty.to_string(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2677,7 +2681,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
self.suggest_trait_fn_ty_for_impl_fn_infer(hir_id, None)
|
self.suggest_trait_fn_ty_for_impl_fn_infer(hir_id, None)
|
||||||
{
|
{
|
||||||
infer_replacements.push((output.span, suggested_ty.to_string()));
|
infer_replacements.push((output.span, suggested_ty.to_string()));
|
||||||
suggested_ty
|
Ty::new_error_with_message(self.tcx(), output.span, suggested_ty.to_string())
|
||||||
} else {
|
} else {
|
||||||
visitor.visit_ty(output);
|
visitor.visit_ty(output);
|
||||||
self.ast_ty_to_ty(output)
|
self.ast_ty_to_ty(output)
|
||||||
|
|
|
@ -116,7 +116,8 @@ use rustc_hir::def::DefKind;
|
||||||
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
||||||
|
|
||||||
fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi, span: Span) {
|
fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi, span: Span) {
|
||||||
const CONVENTIONS_UNSTABLE: &str = "`C`, `cdecl`, `aapcs`, `win64`, `sysv64` or `efiapi`";
|
const CONVENTIONS_UNSTABLE: &str =
|
||||||
|
"`C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`";
|
||||||
const CONVENTIONS_STABLE: &str = "`C` or `cdecl`";
|
const CONVENTIONS_STABLE: &str = "`C` or `cdecl`";
|
||||||
const UNSTABLE_EXPLAIN: &str =
|
const UNSTABLE_EXPLAIN: &str =
|
||||||
"using calling conventions other than `C` or `cdecl` for varargs functions is unstable";
|
"using calling conventions other than `C` or `cdecl` for varargs functions is unstable";
|
||||||
|
|
|
@ -84,7 +84,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
selection_cache: self.selection_cache.clone(),
|
selection_cache: self.selection_cache.clone(),
|
||||||
evaluation_cache: self.evaluation_cache.clone(),
|
evaluation_cache: self.evaluation_cache.clone(),
|
||||||
reported_trait_errors: self.reported_trait_errors.clone(),
|
reported_trait_errors: self.reported_trait_errors.clone(),
|
||||||
reported_closure_mismatch: self.reported_closure_mismatch.clone(),
|
reported_signature_mismatch: self.reported_signature_mismatch.clone(),
|
||||||
tainted_by_errors: self.tainted_by_errors.clone(),
|
tainted_by_errors: self.tainted_by_errors.clone(),
|
||||||
err_count_on_creation: self.err_count_on_creation,
|
err_count_on_creation: self.err_count_on_creation,
|
||||||
universe: self.universe.clone(),
|
universe: self.universe.clone(),
|
||||||
|
|
|
@ -278,7 +278,7 @@ pub struct InferCtxt<'tcx> {
|
||||||
/// avoid reporting the same error twice.
|
/// avoid reporting the same error twice.
|
||||||
pub reported_trait_errors: RefCell<FxIndexMap<Span, Vec<ty::Predicate<'tcx>>>>,
|
pub reported_trait_errors: RefCell<FxIndexMap<Span, Vec<ty::Predicate<'tcx>>>>,
|
||||||
|
|
||||||
pub reported_closure_mismatch: RefCell<FxHashSet<(Span, Option<Span>)>>,
|
pub reported_signature_mismatch: RefCell<FxHashSet<(Span, Option<Span>)>>,
|
||||||
|
|
||||||
/// When an error occurs, we want to avoid reporting "derived"
|
/// When an error occurs, we want to avoid reporting "derived"
|
||||||
/// errors that are due to this original failure. Normally, we
|
/// errors that are due to this original failure. Normally, we
|
||||||
|
@ -702,7 +702,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
||||||
selection_cache: Default::default(),
|
selection_cache: Default::default(),
|
||||||
evaluation_cache: Default::default(),
|
evaluation_cache: Default::default(),
|
||||||
reported_trait_errors: Default::default(),
|
reported_trait_errors: Default::default(),
|
||||||
reported_closure_mismatch: Default::default(),
|
reported_signature_mismatch: Default::default(),
|
||||||
tainted_by_errors: Cell::new(None),
|
tainted_by_errors: Cell::new(None),
|
||||||
err_count_on_creation: tcx.dcx().err_count(),
|
err_count_on_creation: tcx.dcx().err_count(),
|
||||||
universe: Cell::new(ty::UniverseIndex::ROOT),
|
universe: Cell::new(ty::UniverseIndex::ROOT),
|
||||||
|
|
|
@ -520,12 +520,24 @@ impl<'tcx> Collector<'tcx> {
|
||||||
) -> DllImport {
|
) -> DllImport {
|
||||||
let span = self.tcx.def_span(item);
|
let span = self.tcx.def_span(item);
|
||||||
|
|
||||||
|
// this logic is similar to `Target::adjust_abi` (in rustc_target/src/spec/mod.rs) but errors on unsupported inputs
|
||||||
let calling_convention = if self.tcx.sess.target.arch == "x86" {
|
let calling_convention = if self.tcx.sess.target.arch == "x86" {
|
||||||
match abi {
|
match abi {
|
||||||
Abi::C { .. } | Abi::Cdecl { .. } => DllCallingConvention::C,
|
Abi::C { .. } | Abi::Cdecl { .. } => DllCallingConvention::C,
|
||||||
Abi::Stdcall { .. } | Abi::System { .. } => {
|
Abi::Stdcall { .. } => DllCallingConvention::Stdcall(self.i686_arg_list_size(item)),
|
||||||
|
// On Windows, `extern "system"` behaves like msvc's `__stdcall`.
|
||||||
|
// `__stdcall` only applies on x86 and on non-variadic functions:
|
||||||
|
// https://learn.microsoft.com/en-us/cpp/cpp/stdcall?view=msvc-170
|
||||||
|
Abi::System { .. } => {
|
||||||
|
let c_variadic =
|
||||||
|
self.tcx.type_of(item).instantiate_identity().fn_sig(self.tcx).c_variadic();
|
||||||
|
|
||||||
|
if c_variadic {
|
||||||
|
DllCallingConvention::C
|
||||||
|
} else {
|
||||||
DllCallingConvention::Stdcall(self.i686_arg_list_size(item))
|
DllCallingConvention::Stdcall(self.i686_arg_list_size(item))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Abi::Fastcall { .. } => {
|
Abi::Fastcall { .. } => {
|
||||||
DllCallingConvention::Fastcall(self.i686_arg_list_size(item))
|
DllCallingConvention::Fastcall(self.i686_arg_list_size(item))
|
||||||
}
|
}
|
||||||
|
|
|
@ -611,9 +611,6 @@ pub enum SelectionError<'tcx> {
|
||||||
NotConstEvaluatable(NotConstEvaluatable),
|
NotConstEvaluatable(NotConstEvaluatable),
|
||||||
/// Exceeded the recursion depth during type projection.
|
/// Exceeded the recursion depth during type projection.
|
||||||
Overflow(OverflowError),
|
Overflow(OverflowError),
|
||||||
/// Signaling that an error has already been emitted, to avoid
|
|
||||||
/// multiple errors being shown.
|
|
||||||
ErrorReporting,
|
|
||||||
/// Computing an opaque type's hidden type caused an error (e.g. a cycle error).
|
/// Computing an opaque type's hidden type caused an error (e.g. a cycle error).
|
||||||
/// We can thus not know whether the hidden type implements an auto trait, so
|
/// We can thus not know whether the hidden type implements an auto trait, so
|
||||||
/// we should not presume anything about it.
|
/// we should not presume anything about it.
|
||||||
|
|
|
@ -302,7 +302,6 @@ impl EvaluationResult {
|
||||||
pub enum OverflowError {
|
pub enum OverflowError {
|
||||||
Error(ErrorGuaranteed),
|
Error(ErrorGuaranteed),
|
||||||
Canonical,
|
Canonical,
|
||||||
ErrorReporting,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ErrorGuaranteed> for OverflowError {
|
impl From<ErrorGuaranteed> for OverflowError {
|
||||||
|
@ -318,7 +317,6 @@ impl<'tcx> From<OverflowError> for SelectionError<'tcx> {
|
||||||
match overflow_error {
|
match overflow_error {
|
||||||
OverflowError::Error(e) => SelectionError::Overflow(OverflowError::Error(e)),
|
OverflowError::Error(e) => SelectionError::Overflow(OverflowError::Error(e)),
|
||||||
OverflowError::Canonical => SelectionError::Overflow(OverflowError::Canonical),
|
OverflowError::Canonical => SelectionError::Overflow(OverflowError::Canonical),
|
||||||
OverflowError::ErrorReporting => SelectionError::ErrorReporting,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -840,7 +840,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
|
||||||
"sparc" => sparc::compute_abi_info(cx, self),
|
"sparc" => sparc::compute_abi_info(cx, self),
|
||||||
"sparc64" => sparc64::compute_abi_info(cx, self),
|
"sparc64" => sparc64::compute_abi_info(cx, self),
|
||||||
"nvptx64" => {
|
"nvptx64" => {
|
||||||
if cx.target_spec().adjust_abi(abi) == spec::abi::Abi::PtxKernel {
|
if cx.target_spec().adjust_abi(abi, self.c_variadic) == spec::abi::Abi::PtxKernel {
|
||||||
nvptx64::compute_ptx_kernel_abi_info(cx, self)
|
nvptx64::compute_ptx_kernel_abi_info(cx, self)
|
||||||
} else {
|
} else {
|
||||||
nvptx64::compute_abi_info(self)
|
nvptx64::compute_abi_info(self)
|
||||||
|
@ -849,7 +849,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
|
||||||
"hexagon" => hexagon::compute_abi_info(self),
|
"hexagon" => hexagon::compute_abi_info(self),
|
||||||
"riscv32" | "riscv64" => riscv::compute_abi_info(cx, self),
|
"riscv32" | "riscv64" => riscv::compute_abi_info(cx, self),
|
||||||
"wasm32" | "wasm64" => {
|
"wasm32" | "wasm64" => {
|
||||||
if cx.target_spec().adjust_abi(abi) == spec::abi::Abi::Wasm {
|
if cx.target_spec().adjust_abi(abi, self.c_variadic) == spec::abi::Abi::Wasm {
|
||||||
wasm::compute_wasm_abi_info(self)
|
wasm::compute_wasm_abi_info(self)
|
||||||
} else {
|
} else {
|
||||||
wasm::compute_c_abi_info(cx, self)
|
wasm::compute_c_abi_info(cx, self)
|
||||||
|
|
|
@ -70,15 +70,16 @@ impl Abi {
|
||||||
// * C and Cdecl obviously support varargs.
|
// * C and Cdecl obviously support varargs.
|
||||||
// * C can be based on Aapcs, SysV64 or Win64, so they must support varargs.
|
// * C can be based on Aapcs, SysV64 or Win64, so they must support varargs.
|
||||||
// * EfiApi is based on Win64 or C, so it also supports it.
|
// * EfiApi is based on Win64 or C, so it also supports it.
|
||||||
|
// * System falls back to C for functions with varargs.
|
||||||
//
|
//
|
||||||
// * Stdcall does not, because it would be impossible for the callee to clean
|
// * Stdcall does not, because it would be impossible for the callee to clean
|
||||||
// up the arguments. (callee doesn't know how many arguments are there)
|
// up the arguments. (callee doesn't know how many arguments are there)
|
||||||
// * Same for Fastcall, Vectorcall and Thiscall.
|
// * Same for Fastcall, Vectorcall and Thiscall.
|
||||||
// * System can become Stdcall, so is also a no-no.
|
|
||||||
// * Other calling conventions are related to hardware or the compiler itself.
|
// * Other calling conventions are related to hardware or the compiler itself.
|
||||||
match self {
|
match self {
|
||||||
Self::C { .. }
|
Self::C { .. }
|
||||||
| Self::Cdecl { .. }
|
| Self::Cdecl { .. }
|
||||||
|
| Self::System { .. }
|
||||||
| Self::Aapcs { .. }
|
| Self::Aapcs { .. }
|
||||||
| Self::Win64 { .. }
|
| Self::Win64 { .. }
|
||||||
| Self::SysV64 { .. }
|
| Self::SysV64 { .. }
|
||||||
|
|
|
@ -2401,10 +2401,14 @@ impl DerefMut for Target {
|
||||||
|
|
||||||
impl Target {
|
impl Target {
|
||||||
/// Given a function ABI, turn it into the correct ABI for this target.
|
/// Given a function ABI, turn it into the correct ABI for this target.
|
||||||
pub fn adjust_abi(&self, abi: Abi) -> Abi {
|
pub fn adjust_abi(&self, abi: Abi, c_variadic: bool) -> Abi {
|
||||||
match abi {
|
match abi {
|
||||||
Abi::C { .. } => self.default_adjusted_cabi.unwrap_or(abi),
|
Abi::C { .. } => self.default_adjusted_cabi.unwrap_or(abi),
|
||||||
Abi::System { unwind } if self.is_like_windows && self.arch == "x86" => {
|
|
||||||
|
// On Windows, `extern "system"` behaves like msvc's `__stdcall`.
|
||||||
|
// `__stdcall` only applies on x86 and on non-variadic functions:
|
||||||
|
// https://learn.microsoft.com/en-us/cpp/cpp/stdcall?view=msvc-170
|
||||||
|
Abi::System { unwind } if self.is_like_windows && self.arch == "x86" && !c_variadic => {
|
||||||
Abi::Stdcall { unwind }
|
Abi::Stdcall { unwind }
|
||||||
}
|
}
|
||||||
Abi::System { unwind } => Abi::C { unwind },
|
Abi::System { unwind } => Abi::C { unwind },
|
||||||
|
|
|
@ -947,9 +947,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
Overflow(_) => {
|
Overflow(_) => {
|
||||||
bug!("overflow should be handled before the `report_selection_error` path");
|
bug!("overflow should be handled before the `report_selection_error` path");
|
||||||
}
|
}
|
||||||
SelectionError::ErrorReporting => {
|
|
||||||
bug!("ErrorReporting Overflow should not reach `report_selection_err` call")
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.note_obligation_cause(&mut err, &obligation);
|
self.note_obligation_cause(&mut err, &obligation);
|
||||||
|
@ -3459,14 +3456,12 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
let found_node = found_did.and_then(|did| self.tcx.hir().get_if_local(did));
|
let found_node = found_did.and_then(|did| self.tcx.hir().get_if_local(did));
|
||||||
let found_span = found_did.and_then(|did| self.tcx.hir().span_if_local(did));
|
let found_span = found_did.and_then(|did| self.tcx.hir().span_if_local(did));
|
||||||
|
|
||||||
if self.reported_closure_mismatch.borrow().contains(&(span, found_span)) {
|
if !self.reported_signature_mismatch.borrow_mut().insert((span, found_span)) {
|
||||||
// We check closures twice, with obligations flowing in different directions,
|
// We check closures twice, with obligations flowing in different directions,
|
||||||
// but we want to complain about them only once.
|
// but we want to complain about them only once.
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.reported_closure_mismatch.borrow_mut().insert((span, found_span));
|
|
||||||
|
|
||||||
let mut not_tupled = false;
|
let mut not_tupled = false;
|
||||||
|
|
||||||
let found = match found_trait_ref.skip_binder().args.type_at(1).kind() {
|
let found = match found_trait_ref.skip_binder().args.type_at(1).kind() {
|
||||||
|
|
|
@ -116,11 +116,9 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||||
r,
|
r,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
OverflowError::ErrorReporting => EvaluationResult::EvaluatedToErr,
|
|
||||||
OverflowError::Error(_) => EvaluationResult::EvaluatedToErr,
|
OverflowError::Error(_) => EvaluationResult::EvaluatedToErr,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Err(OverflowError::ErrorReporting) => EvaluationResult::EvaluatedToErr,
|
|
||||||
Err(OverflowError::Error(_)) => EvaluationResult::EvaluatedToErr,
|
Err(OverflowError::Error(_)) => EvaluationResult::EvaluatedToErr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,9 @@ use super::util;
|
||||||
use super::util::closure_trait_ref_and_return_type;
|
use super::util::closure_trait_ref_and_return_type;
|
||||||
use super::wf;
|
use super::wf;
|
||||||
use super::{
|
use super::{
|
||||||
ErrorReporting, ImplDerivedObligation, ImplDerivedObligationCause, Normalized, Obligation,
|
ImplDerivedObligation, ImplDerivedObligationCause, Normalized, Obligation, ObligationCause,
|
||||||
ObligationCause, ObligationCauseCode, Overflow, PolyTraitObligation, PredicateObligation,
|
ObligationCauseCode, Overflow, PolyTraitObligation, PredicateObligation, Selection,
|
||||||
Selection, SelectionError, SelectionResult, TraitQueryMode,
|
SelectionError, SelectionResult, TraitQueryMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::infer::{InferCtxt, InferOk, TypeFreshener};
|
use crate::infer::{InferCtxt, InferOk, TypeFreshener};
|
||||||
|
@ -496,7 +496,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
Ok(_) => Ok(None),
|
Ok(_) => Ok(None),
|
||||||
Err(OverflowError::Canonical) => Err(Overflow(OverflowError::Canonical)),
|
Err(OverflowError::Canonical) => Err(Overflow(OverflowError::Canonical)),
|
||||||
Err(OverflowError::ErrorReporting) => Err(ErrorReporting),
|
|
||||||
Err(OverflowError::Error(e)) => Err(Overflow(OverflowError::Error(e))),
|
Err(OverflowError::Error(e)) => Err(Overflow(OverflowError::Error(e))),
|
||||||
})
|
})
|
||||||
.flat_map(Result::transpose)
|
.flat_map(Result::transpose)
|
||||||
|
@ -1233,7 +1232,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
Ok(Some(c)) => self.evaluate_candidate(stack, &c),
|
Ok(Some(c)) => self.evaluate_candidate(stack, &c),
|
||||||
Ok(None) => Ok(EvaluatedToAmbig),
|
Ok(None) => Ok(EvaluatedToAmbig),
|
||||||
Err(Overflow(OverflowError::Canonical)) => Err(OverflowError::Canonical),
|
Err(Overflow(OverflowError::Canonical)) => Err(OverflowError::Canonical),
|
||||||
Err(ErrorReporting) => Err(OverflowError::ErrorReporting),
|
|
||||||
Err(..) => Ok(EvaluatedToErr),
|
Err(..) => Ok(EvaluatedToErr),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,9 +228,9 @@ fn fn_sig_for_fn_abi<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi) -> Conv {
|
fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi, c_variadic: bool) -> Conv {
|
||||||
use rustc_target::spec::abi::Abi::*;
|
use rustc_target::spec::abi::Abi::*;
|
||||||
match tcx.sess.target.adjust_abi(abi) {
|
match tcx.sess.target.adjust_abi(abi, c_variadic) {
|
||||||
RustIntrinsic | PlatformIntrinsic | Rust | RustCall => Conv::Rust,
|
RustIntrinsic | PlatformIntrinsic | Rust | RustCall => Conv::Rust,
|
||||||
|
|
||||||
// This is intentionally not using `Conv::Cold`, as that has to preserve
|
// This is intentionally not using `Conv::Cold`, as that has to preserve
|
||||||
|
@ -488,7 +488,7 @@ fn fn_abi_new_uncached<'tcx>(
|
||||||
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> {
|
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> {
|
||||||
let sig = cx.tcx.normalize_erasing_late_bound_regions(cx.param_env, sig);
|
let sig = cx.tcx.normalize_erasing_late_bound_regions(cx.param_env, sig);
|
||||||
|
|
||||||
let conv = conv_from_spec_abi(cx.tcx(), sig.abi);
|
let conv = conv_from_spec_abi(cx.tcx(), sig.abi, sig.c_variadic);
|
||||||
|
|
||||||
let mut inputs = sig.inputs();
|
let mut inputs = sig.inputs();
|
||||||
let extra_args = if sig.abi == RustCall {
|
let extra_args = if sig.abi == RustCall {
|
||||||
|
|
|
@ -1605,9 +1605,9 @@ mod prim_ref {}
|
||||||
/// type in the function pointer to the type at the function declaration, and the return value is
|
/// type in the function pointer to the type at the function declaration, and the return value is
|
||||||
/// [`transmute`d][mem::transmute] from the type in the declaration to the type in the
|
/// [`transmute`d][mem::transmute] from the type in the declaration to the type in the
|
||||||
/// pointer. All the usual caveats and concerns around transmutation apply; for instance, if the
|
/// pointer. All the usual caveats and concerns around transmutation apply; for instance, if the
|
||||||
/// function expects a `NonNullI32` and the function pointer uses the ABI-compatible type
|
/// function expects a `NonZeroI32` and the function pointer uses the ABI-compatible type
|
||||||
/// `Option<NonNullI32>`, and the value used for the argument is `None`, then this call is Undefined
|
/// `Option<NonZeroI32>`, and the value used for the argument is `None`, then this call is Undefined
|
||||||
/// Behavior since transmuting `None::<NonNullI32>` to `NonNullI32` violates the non-null
|
/// Behavior since transmuting `None::<NonZeroI32>` to `NonZeroI32` violates the non-zero
|
||||||
/// requirement.
|
/// requirement.
|
||||||
///
|
///
|
||||||
/// #### Requirements concerning target features
|
/// #### Requirements concerning target features
|
||||||
|
|
|
@ -81,7 +81,6 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
|
||||||
match infcx.evaluate_obligation(&obligation) {
|
match infcx.evaluate_obligation(&obligation) {
|
||||||
Ok(eval_result) if eval_result.may_apply() => {}
|
Ok(eval_result) if eval_result.may_apply() => {}
|
||||||
Err(traits::OverflowError::Canonical) => {}
|
Err(traits::OverflowError::Canonical) => {}
|
||||||
Err(traits::OverflowError::ErrorReporting) => {}
|
|
||||||
_ => continue 'blanket_impls,
|
_ => continue 'blanket_impls,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,13 @@
|
||||||
|
|
||||||
fn baz(f: extern "stdcall" fn(usize, ...)) {
|
fn baz(f: extern "stdcall" fn(usize, ...)) {
|
||||||
//~^ ERROR: C-variadic function must have a compatible calling convention,
|
//~^ ERROR: C-variadic function must have a compatible calling convention,
|
||||||
// like C, cdecl, aapcs, win64, sysv64 or efiapi
|
// like C, cdecl, system, aapcs, win64, sysv64 or efiapi
|
||||||
f(22, 44);
|
f(22, 44);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn system(f: extern "system" fn(usize, ...)) {
|
||||||
|
f(22, 44);
|
||||||
|
}
|
||||||
fn aapcs(f: extern "aapcs" fn(usize, ...)) {
|
fn aapcs(f: extern "aapcs" fn(usize, ...)) {
|
||||||
f(22, 44);
|
f(22, 44);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `aapcs`, `win64`, `sysv64` or `efiapi`
|
error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`
|
||||||
--> $DIR/variadic-ffi-2.rs:4:11
|
--> $DIR/variadic-ffi-2.rs:4:11
|
||||||
|
|
|
|
||||||
LL | fn baz(f: extern "stdcall" fn(usize, ...)) {
|
LL | fn baz(f: extern "stdcall" fn(usize, ...)) {
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
error[E0277]: the trait bound `T: Trait` is not satisfied
|
||||||
|
--> $DIR/assoc-type-const-bound-usage-0.rs:21:6
|
||||||
|
|
|
||||||
|
LL | <T as /* FIXME: ~const */ Trait>::Assoc::func()
|
||||||
|
| ^ the trait `Trait` is not implemented for `T`
|
||||||
|
|
|
||||||
|
help: consider further restricting this bound
|
||||||
|
|
|
||||||
|
LL | const fn qualified<T: ~const Trait + Trait>() -> i32 {
|
||||||
|
| +++++++
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
|
@ -0,0 +1,24 @@
|
||||||
|
// FIXME(effects): Collapse the revisions into one once we support `<Ty as ~const Trait>::Proj`.
|
||||||
|
// revisions: unqualified qualified
|
||||||
|
//[unqualified] check-pass
|
||||||
|
//[qualified] known-bug: unknown
|
||||||
|
|
||||||
|
#![feature(const_trait_impl, effects)]
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
trait Trait {
|
||||||
|
type Assoc: ~const Trait;
|
||||||
|
fn func() -> i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unqualified)]
|
||||||
|
const fn unqualified<T: ~const Trait>() -> i32 {
|
||||||
|
T::Assoc::func()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(qualified)]
|
||||||
|
const fn qualified<T: ~const Trait>() -> i32 {
|
||||||
|
<T as /* FIXME: ~const */ Trait>::Assoc::func()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,14 @@
|
||||||
|
error[E0277]: the trait bound `T: Trait` is not satisfied
|
||||||
|
--> $DIR/assoc-type-const-bound-usage-1.rs:23:43
|
||||||
|
|
|
||||||
|
LL | fn qualified<T: const Trait>() -> Type<{ <T as /* FIXME: const */ Trait>::Assoc::func() }> {
|
||||||
|
| ^ the trait `Trait` is not implemented for `T`
|
||||||
|
|
|
||||||
|
help: consider further restricting this bound
|
||||||
|
|
|
||||||
|
LL | fn qualified<T: const Trait + Trait>() -> Type<{ <T as /* FIXME: const */ Trait>::Assoc::func() }> {
|
||||||
|
| +++++++
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
|
@ -0,0 +1,27 @@
|
||||||
|
// FIXME(effects): Collapse the revisions into one once we support `<Ty as const Trait>::Proj`.
|
||||||
|
// revisions: unqualified qualified
|
||||||
|
//[unqualified] check-pass
|
||||||
|
//[qualified] known-bug: unknown
|
||||||
|
|
||||||
|
#![feature(const_trait_impl, effects, generic_const_exprs)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
trait Trait {
|
||||||
|
type Assoc: ~const Trait;
|
||||||
|
fn func() -> i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Type<const N: i32>;
|
||||||
|
|
||||||
|
#[cfg(unqualified)]
|
||||||
|
fn unqualified<T: const Trait>() -> Type<{ T::Assoc::func() }> {
|
||||||
|
Type
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(qualified)]
|
||||||
|
fn qualified<T: const Trait>() -> Type<{ <T as /* FIXME: const */ Trait>::Assoc::func() }> {
|
||||||
|
Type
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -1,15 +0,0 @@
|
||||||
// known-bug: #110395
|
|
||||||
// FIXME check-pass
|
|
||||||
#![feature(const_trait_impl, effects)]
|
|
||||||
|
|
||||||
#[const_trait]
|
|
||||||
trait Foo {
|
|
||||||
type Assoc: ~const Foo;
|
|
||||||
fn foo() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
const fn foo<T: ~const Foo>() {
|
|
||||||
<T as /* FIXME: ~const */ Foo>::Assoc::foo();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {}
|
|
|
@ -1,22 +0,0 @@
|
||||||
error: `~const` is not allowed here
|
|
||||||
--> $DIR/assoc-type-const-bound-usage.rs:7:17
|
|
||||||
|
|
|
||||||
LL | type Assoc: ~const Foo;
|
|
||||||
| ^^^^^^
|
|
||||||
|
|
|
||||||
= note: this item cannot have `~const` trait bounds
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `T: Foo` is not satisfied
|
|
||||||
--> $DIR/assoc-type-const-bound-usage.rs:12:6
|
|
||||||
|
|
|
||||||
LL | <T as /* FIXME: ~const */ Foo>::Assoc::foo();
|
|
||||||
| ^ the trait `Foo` is not implemented for `T`
|
|
||||||
|
|
|
||||||
help: consider further restricting this bound
|
|
||||||
|
|
|
||||||
LL | const fn foo<T: ~const Foo + Foo>() {
|
|
||||||
| +++++
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
|
@ -1,29 +1,43 @@
|
||||||
// known-bug: #110395
|
// FIXME(effects): Replace `Add` with `std::ops::Add` once the latter a `#[const_trait]` again.
|
||||||
|
#![feature(const_trait_impl, effects)]
|
||||||
|
|
||||||
#![feature(const_trait_impl)]
|
#[const_trait]
|
||||||
|
trait Add<Rhs = Self> {
|
||||||
|
type Output;
|
||||||
|
|
||||||
|
fn add(self, other: Rhs) -> Self::Output;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl const Add for i32 {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn add(self, other: Self) -> Self::Output {
|
||||||
|
self + other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct NonConstAdd(i32);
|
struct NonConstAdd(i32);
|
||||||
|
|
||||||
impl std::ops::Add for NonConstAdd {
|
impl Add for NonConstAdd {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn add(self, rhs: Self) -> Self {
|
fn add(self, rhs: Self) -> Self {
|
||||||
NonConstAdd(self.0 + rhs.0)
|
NonConstAdd(self.0.add(rhs.0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[const_trait]
|
#[const_trait]
|
||||||
trait Foo {
|
trait Foo {
|
||||||
type Bar: ~const std::ops::Add;
|
type Bar: ~const Add;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl const Foo for NonConstAdd {
|
impl const Foo for NonConstAdd {
|
||||||
type Bar = NonConstAdd;
|
type Bar = NonConstAdd; //~ ERROR the trait bound `NonConstAdd: ~const Add` is not satisfied
|
||||||
}
|
}
|
||||||
|
|
||||||
#[const_trait]
|
#[const_trait]
|
||||||
trait Baz {
|
trait Baz {
|
||||||
type Qux: std::ops::Add;
|
type Qux: Add;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl const Baz for NonConstAdd {
|
impl const Baz for NonConstAdd {
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
error: `~const` is not allowed here
|
error[E0277]: the trait bound `NonConstAdd: ~const Add` is not satisfied
|
||||||
--> $DIR/assoc-type.rs:17:15
|
--> $DIR/assoc-type.rs:35:16
|
||||||
|
|
|
|
||||||
LL | type Bar: ~const std::ops::Add;
|
LL | type Bar = NonConstAdd;
|
||||||
| ^^^^^^
|
| ^^^^^^^^^^^ the trait `~const Add` is not implemented for `NonConstAdd`
|
||||||
|
|
|
|
||||||
= note: this item cannot have `~const` trait bounds
|
= help: the trait `Add` is implemented for `NonConstAdd`
|
||||||
|
note: required by a bound in `Foo::Bar`
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
--> $DIR/assoc-type.rs:31:15
|
||||||
--> $DIR/assoc-type.rs:17:22
|
|
||||||
|
|
|
|
||||||
LL | type Bar: ~const std::ops::Add;
|
LL | type Bar: ~const Add;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^ required by this bound in `Foo::Bar`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -72,7 +72,11 @@ error: `~const` is not allowed here
|
||||||
LL | type Type<T: ~const Trait>: ~const Trait;
|
LL | type Type<T: ~const Trait>: ~const Trait;
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
|
|
||||||
= note: this item cannot have `~const` trait bounds
|
note: associated types in non-`#[const_trait]` traits cannot have `~const` trait bounds
|
||||||
|
--> $DIR/tilde-const-invalid-places.rs:25:5
|
||||||
|
|
|
||||||
|
LL | type Type<T: ~const Trait>: ~const Trait;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `~const` is not allowed here
|
error: `~const` is not allowed here
|
||||||
--> $DIR/tilde-const-invalid-places.rs:25:33
|
--> $DIR/tilde-const-invalid-places.rs:25:33
|
||||||
|
@ -80,7 +84,11 @@ error: `~const` is not allowed here
|
||||||
LL | type Type<T: ~const Trait>: ~const Trait;
|
LL | type Type<T: ~const Trait>: ~const Trait;
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
|
|
||||||
= note: this item cannot have `~const` trait bounds
|
note: associated types in non-`#[const_trait]` traits cannot have `~const` trait bounds
|
||||||
|
--> $DIR/tilde-const-invalid-places.rs:25:5
|
||||||
|
|
|
||||||
|
LL | type Type<T: ~const Trait>: ~const Trait;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `~const` is not allowed here
|
error: `~const` is not allowed here
|
||||||
--> $DIR/tilde-const-invalid-places.rs:28:30
|
--> $DIR/tilde-const-invalid-places.rs:28:30
|
||||||
|
@ -108,7 +116,11 @@ error: `~const` is not allowed here
|
||||||
LL | type Type<T: ~const Trait> = ();
|
LL | type Type<T: ~const Trait> = ();
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
|
|
||||||
= note: this item cannot have `~const` trait bounds
|
note: associated types in non-const impls cannot have `~const` trait bounds
|
||||||
|
--> $DIR/tilde-const-invalid-places.rs:34:5
|
||||||
|
|
|
||||||
|
LL | type Type<T: ~const Trait> = ();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `~const` is not allowed here
|
error: `~const` is not allowed here
|
||||||
--> $DIR/tilde-const-invalid-places.rs:36:30
|
--> $DIR/tilde-const-invalid-places.rs:36:30
|
||||||
|
@ -136,7 +148,11 @@ error: `~const` is not allowed here
|
||||||
LL | type Type<T: ~const Trait> = ();
|
LL | type Type<T: ~const Trait> = ();
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
|
|
||||||
= note: this item cannot have `~const` trait bounds
|
note: inherent associated types cannot have `~const` trait bounds
|
||||||
|
--> $DIR/tilde-const-invalid-places.rs:44:5
|
||||||
|
|
|
||||||
|
LL | type Type<T: ~const Trait> = ();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `~const` is not allowed here
|
error: `~const` is not allowed here
|
||||||
--> $DIR/tilde-const-invalid-places.rs:46:30
|
--> $DIR/tilde-const-invalid-places.rs:46:30
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
// check-pass
|
||||||
|
#![feature(const_trait_impl, effects)]
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
trait Trait {
|
||||||
|
// FIXME(effects): `~const` bounds in trait associated types (excluding associated type bounds)
|
||||||
|
// don't look super useful. Should we forbid them again?
|
||||||
|
type Assoc<T: ~const Bound>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl const Trait for () {
|
||||||
|
type Assoc<T: ~const Bound> = T;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
trait Bound {}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,13 @@
|
||||||
|
trait Deserialize {
|
||||||
|
fn deserialize(&self);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ArchivedVec<T>(T);
|
||||||
|
|
||||||
|
impl<T> Deserialize for ArchivedVec<T> {
|
||||||
|
fn deserialize(s: _) {}
|
||||||
|
//~^ ERROR: `_` is not allowed within types on item signatures
|
||||||
|
//~| ERROR: has a `&self` declaration in the trait, but not in the impl
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,24 @@
|
||||||
|
error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
|
||||||
|
--> $DIR/method-argument-mismatch-variance-ice-119867.rs:8:23
|
||||||
|
|
|
||||||
|
LL | fn deserialize(s: _) {}
|
||||||
|
| ^ not allowed in type signatures
|
||||||
|
|
|
||||||
|
help: try replacing `_` with the type in the corresponding trait method signature
|
||||||
|
|
|
||||||
|
LL | fn deserialize(s: &ArchivedVec<T>) {}
|
||||||
|
| ~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
error[E0186]: method `deserialize` has a `&self` declaration in the trait, but not in the impl
|
||||||
|
--> $DIR/method-argument-mismatch-variance-ice-119867.rs:8:5
|
||||||
|
|
|
||||||
|
LL | fn deserialize(&self);
|
||||||
|
| ---------------------- `&self` used in trait
|
||||||
|
...
|
||||||
|
LL | fn deserialize(s: _) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^ expected `&self` in impl
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0121, E0186.
|
||||||
|
For more information about an error, try `rustc --explain E0121`.
|
Loading…
Add table
Add a link
Reference in a new issue