Auto merge of #113474 - compiler-errors:rollup-07x1up7, r=compiler-errors
Rollup of 8 pull requests Successful merges: - #113413 (Add needs-triage to all new issues) - #113426 (Don't ICE in `resolve_bound_vars` when associated return-type bounds are in bad positions) - #113427 (Remove `variances_of` on RPITIT GATs, remove its one use-case) - #113441 (miri: check that assignments do not self-overlap) - #113453 (Remove unused from_method from rustc_on_unimplemented) - #113456 (Avoid calling report_forbidden_specialization for RPITITs) - #113466 (Update cargo) - #113467 (Fix comment of `fn_can_unwind`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
ce519c5945
20 changed files with 251 additions and 57 deletions
|
@ -700,8 +700,13 @@ where
|
||||||
assert_eq!(src.layout.size, dest.layout.size);
|
assert_eq!(src.layout.size, dest.layout.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setting `nonoverlapping` here only has an effect when we don't hit the fast-path above,
|
||||||
|
// but that should at least match what LLVM does where `memcpy` is also only used when the
|
||||||
|
// type does not have Scalar/ScalarPair layout.
|
||||||
|
// (Or as the `Assign` docs put it, assignments "not producing primitives" must be
|
||||||
|
// non-overlapping.)
|
||||||
self.mem_copy(
|
self.mem_copy(
|
||||||
src.ptr, src.align, dest.ptr, dest.align, dest_size, /*nonoverlapping*/ false,
|
src.ptr, src.align, dest.ptr, dest.align, dest_size, /*nonoverlapping*/ true,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -722,7 +722,14 @@ pub(super) fn check_specialization_validity<'tcx>(
|
||||||
let result = opt_result.unwrap_or(Ok(()));
|
let result = opt_result.unwrap_or(Ok(()));
|
||||||
|
|
||||||
if let Err(parent_impl) = result {
|
if let Err(parent_impl) = result {
|
||||||
report_forbidden_specialization(tcx, impl_item, parent_impl);
|
if !tcx.is_impl_trait_in_trait(impl_item) {
|
||||||
|
report_forbidden_specialization(tcx, impl_item, parent_impl);
|
||||||
|
} else {
|
||||||
|
tcx.sess.delay_span_bug(
|
||||||
|
DUMMY_SP,
|
||||||
|
format!("parent item: {:?} not marked as default", parent_impl),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1485,7 +1492,9 @@ fn opaque_type_cycle_error(
|
||||||
}
|
}
|
||||||
|
|
||||||
for closure_def_id in visitor.closures {
|
for closure_def_id in visitor.closures {
|
||||||
let Some(closure_local_did) = closure_def_id.as_local() else { continue; };
|
let Some(closure_local_did) = closure_def_id.as_local() else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
let typeck_results = tcx.typeck(closure_local_did);
|
let typeck_results = tcx.typeck(closure_local_did);
|
||||||
|
|
||||||
let mut label_match = |ty: Ty<'_>, span| {
|
let mut label_match = |ty: Ty<'_>, span| {
|
||||||
|
|
|
@ -22,7 +22,7 @@ use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor};
|
||||||
use rustc_session::lint;
|
use rustc_session::lint;
|
||||||
use rustc_span::def_id::DefId;
|
use rustc_span::def_id::DefId;
|
||||||
use rustc_span::symbol::{sym, Ident};
|
use rustc_span::symbol::{sym, Ident};
|
||||||
use rustc_span::Span;
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use crate::errors;
|
use crate::errors;
|
||||||
|
@ -338,7 +338,17 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||||
|
|
||||||
Scope::TraitRefBoundary { .. } => {
|
Scope::TraitRefBoundary { .. } => {
|
||||||
// We should only see super trait lifetimes if there is a `Binder` above
|
// We should only see super trait lifetimes if there is a `Binder` above
|
||||||
assert!(supertrait_bound_vars.is_empty());
|
// though this may happen when we call `poly_trait_ref_binder_info` with
|
||||||
|
// an (erroneous, #113423) associated return type bound in an impl header.
|
||||||
|
if !supertrait_bound_vars.is_empty() {
|
||||||
|
self.tcx.sess.delay_span_bug(
|
||||||
|
DUMMY_SP,
|
||||||
|
format!(
|
||||||
|
"found supertrait lifetimes without a binder to append \
|
||||||
|
them to: {supertrait_bound_vars:?}"
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
break (vec![], BinderScopeType::Normal);
|
break (vec![], BinderScopeType::Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ use rustc_arena::DroplessArena;
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
use rustc_middle::ty::{self, CrateVariancesMap, ImplTraitInTraitData, SubstsRef, Ty, TyCtxt};
|
use rustc_middle::ty::{self, CrateVariancesMap, SubstsRef, Ty, TyCtxt};
|
||||||
use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable};
|
use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable};
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
|
@ -59,13 +59,6 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
|
||||||
DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder => {
|
DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder => {
|
||||||
return variance_of_opaque(tcx, item_def_id);
|
return variance_of_opaque(tcx, item_def_id);
|
||||||
}
|
}
|
||||||
DefKind::AssocTy => {
|
|
||||||
if let Some(ImplTraitInTraitData::Trait { .. }) =
|
|
||||||
tcx.opt_rpitit_info(item_def_id.to_def_id())
|
|
||||||
{
|
|
||||||
return variance_of_opaque(tcx, item_def_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +118,8 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
|
||||||
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) check whether this is necessary
|
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) check whether this is necessary
|
||||||
// at all for RPITITs.
|
// at all for RPITITs.
|
||||||
ty::Alias(_, ty::AliasTy { def_id, substs, .. })
|
ty::Alias(_, ty::AliasTy { def_id, substs, .. })
|
||||||
if self.tcx.is_impl_trait_in_trait(*def_id) =>
|
if self.tcx.is_impl_trait_in_trait(*def_id)
|
||||||
|
&& !self.tcx.lower_impl_trait_in_trait_to_assoc_ty() =>
|
||||||
{
|
{
|
||||||
self.visit_opaque(*def_id, substs)
|
self.visit_opaque(*def_id, substs)
|
||||||
}
|
}
|
||||||
|
|
|
@ -473,17 +473,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Alias(ty::Projection, proj) if self.tcx.is_impl_trait_in_trait(proj.def_id) => {
|
|
||||||
// Skip lifetime parameters that are not captures.
|
|
||||||
let variances = self.tcx.variances_of(proj.def_id);
|
|
||||||
|
|
||||||
for (v, s) in std::iter::zip(variances, proj.substs.iter()) {
|
|
||||||
if *v != ty::Variance::Bivariant {
|
|
||||||
s.visit_with(self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
ty.super_visit_with(self);
|
ty.super_visit_with(self);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1110,12 +1110,11 @@ where
|
||||||
///
|
///
|
||||||
/// This takes two primary parameters:
|
/// This takes two primary parameters:
|
||||||
///
|
///
|
||||||
/// * `codegen_fn_attr_flags` - these are flags calculated as part of the
|
/// * `fn_def_id` - the `DefId` of the function. If this is provided then we can
|
||||||
/// codegen attrs for a defined function. For function pointers this set of
|
/// determine more precisely if the function can unwind. If this is not provided
|
||||||
/// flags is the empty set. This is only applicable for Rust-defined
|
/// then we will only infer whether the function can unwind or not based on the
|
||||||
/// functions, and generally isn't needed except for small optimizations where
|
/// ABI of the function. For example, a function marked with `#[rustc_nounwind]`
|
||||||
/// we try to say a function which otherwise might look like it could unwind
|
/// is known to not unwind even if it's using Rust ABI.
|
||||||
/// doesn't actually unwind (such as for intrinsics and such).
|
|
||||||
///
|
///
|
||||||
/// * `abi` - this is the ABI that the function is defined with. This is the
|
/// * `abi` - this is the ABI that the function is defined with. This is the
|
||||||
/// primary factor for determining whether a function can unwind or not.
|
/// primary factor for determining whether a function can unwind or not.
|
||||||
|
@ -1147,11 +1146,6 @@ where
|
||||||
/// aborts the process.
|
/// aborts the process.
|
||||||
/// * This affects whether functions have the LLVM `nounwind` attribute, which
|
/// * This affects whether functions have the LLVM `nounwind` attribute, which
|
||||||
/// affects various optimizations and codegen.
|
/// affects various optimizations and codegen.
|
||||||
///
|
|
||||||
/// FIXME: this is actually buggy with respect to Rust functions. Rust functions
|
|
||||||
/// compiled with `-Cpanic=unwind` and referenced from another crate compiled
|
|
||||||
/// with `-Cpanic=abort` will look like they can't unwind when in fact they
|
|
||||||
/// might (from a foreign exception or similar).
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[tracing::instrument(level = "debug", skip(tcx))]
|
#[tracing::instrument(level = "debug", skip(tcx))]
|
||||||
pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: SpecAbi) -> bool {
|
pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: SpecAbi) -> bool {
|
||||||
|
|
|
@ -759,7 +759,6 @@ symbols! {
|
||||||
from_desugaring,
|
from_desugaring,
|
||||||
from_fn,
|
from_fn,
|
||||||
from_iter,
|
from_iter,
|
||||||
from_method,
|
|
||||||
from_output,
|
from_output,
|
||||||
from_residual,
|
from_residual,
|
||||||
from_size_align_unchecked,
|
from_size_align_unchecked,
|
||||||
|
|
|
@ -41,7 +41,6 @@ pub trait TypeErrCtxtExt<'tcx> {
|
||||||
static ALLOWED_FORMAT_SYMBOLS: &[Symbol] = &[
|
static ALLOWED_FORMAT_SYMBOLS: &[Symbol] = &[
|
||||||
kw::SelfUpper,
|
kw::SelfUpper,
|
||||||
sym::ItemContext,
|
sym::ItemContext,
|
||||||
sym::from_method,
|
|
||||||
sym::from_desugaring,
|
sym::from_desugaring,
|
||||||
sym::direct,
|
sym::direct,
|
||||||
sym::cause,
|
sym::cause,
|
||||||
|
@ -172,23 +171,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let ObligationCauseCode::ItemObligation(item)
|
|
||||||
| ObligationCauseCode::BindingObligation(item, _)
|
|
||||||
| ObligationCauseCode::ExprItemObligation(item, ..)
|
|
||||||
| ObligationCauseCode::ExprBindingObligation(item, ..) = *obligation.cause.code()
|
|
||||||
{
|
|
||||||
// FIXME: maybe also have some way of handling methods
|
|
||||||
// from other traits? That would require name resolution,
|
|
||||||
// which we might want to be some sort of hygienic.
|
|
||||||
//
|
|
||||||
// Currently I'm leaving it for what I need for `try`.
|
|
||||||
if self.tcx.trait_of_item(item) == Some(trait_ref.def_id) {
|
|
||||||
let method = self.tcx.item_name(item);
|
|
||||||
flags.push((sym::from_method, None));
|
|
||||||
flags.push((sym::from_method, Some(method.to_string())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(k) = obligation.cause.span.desugaring_kind() {
|
if let Some(k) = obligation.cause.span.desugaring_kind() {
|
||||||
flags.push((sym::from_desugaring, None));
|
flags.push((sym::from_desugaring, None));
|
||||||
flags.push((sym::from_desugaring, Some(format!("{:?}", k))));
|
flags.push((sym::from_desugaring, Some(format!("{:?}", k))));
|
||||||
|
@ -672,7 +654,7 @@ impl<'tcx> OnUnimplementedFormatString {
|
||||||
None => {
|
None => {
|
||||||
if let Some(val) = options.get(&s) {
|
if let Some(val) = options.get(&s) {
|
||||||
val
|
val
|
||||||
} else if s == sym::from_desugaring || s == sym::from_method {
|
} else if s == sym::from_desugaring {
|
||||||
// don't break messages using these two arguments incorrectly
|
// don't break messages using these two arguments incorrectly
|
||||||
&empty_string
|
&empty_string
|
||||||
} else if s == sym::ItemContext {
|
} else if s == sym::ItemContext {
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 5b377cece0e0dd0af686cf53ce4637d5d85c2a10
|
Subproject commit 45782b6b8afd1da042d45c2daeec9c0744f72cc7
|
23
src/tools/miri/tests/fail/overlapping_assignment.rs
Normal file
23
src/tools/miri/tests/fail/overlapping_assignment.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#![feature(core_intrinsics)]
|
||||||
|
#![feature(custom_mir)]
|
||||||
|
|
||||||
|
use std::intrinsics::mir::*;
|
||||||
|
|
||||||
|
// It's not that easy to fool the MIR validity check
|
||||||
|
// which wants to prevent overlapping assignments...
|
||||||
|
// So we use two separate pointer arguments, and then arrange for them to alias.
|
||||||
|
#[custom_mir(dialect = "runtime", phase = "optimized")]
|
||||||
|
pub fn self_copy(ptr1: *mut [i32; 4], ptr2: *mut [i32; 4]) {
|
||||||
|
mir! {
|
||||||
|
{
|
||||||
|
*ptr1 = *ptr2; //~ERROR: overlapping ranges
|
||||||
|
Return()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
let mut x = [0; 4];
|
||||||
|
let ptr = std::ptr::addr_of_mut!(x);
|
||||||
|
self_copy(ptr, ptr);
|
||||||
|
}
|
20
src/tools/miri/tests/fail/overlapping_assignment.stderr
Normal file
20
src/tools/miri/tests/fail/overlapping_assignment.stderr
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
error: Undefined Behavior: `copy_nonoverlapping` called on overlapping ranges
|
||||||
|
--> $DIR/overlapping_assignment.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | *ptr1 = *ptr2;
|
||||||
|
| ^^^^^^^^^^^^^ `copy_nonoverlapping` called on overlapping ranges
|
||||||
|
|
|
||||||
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||||
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
|
= note: BACKTRACE:
|
||||||
|
= note: inside `self_copy` at $DIR/overlapping_assignment.rs:LL:CC
|
||||||
|
note: inside `main`
|
||||||
|
--> $DIR/overlapping_assignment.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | self_copy(ptr, ptr);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
error[E0046]: not all trait items implemented, missing: `foo`
|
||||||
|
--> $DIR/missing-feature-flag.rs:14:1
|
||||||
|
|
|
||||||
|
LL | async fn foo(_: T) -> &'static str;
|
||||||
|
| ----------------------------------- `foo` from trait
|
||||||
|
...
|
||||||
|
LL | impl<T> MyTrait<T> for MyStruct {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation
|
||||||
|
|
||||||
|
error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
|
||||||
|
--> $DIR/missing-feature-flag.rs:18:5
|
||||||
|
|
|
||||||
|
LL | impl<T> MyTrait<T> for MyStruct {}
|
||||||
|
| ------------------------------- parent `impl` is here
|
||||||
|
...
|
||||||
|
LL | async fn foo(_: i32) -> &'static str {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `foo`
|
||||||
|
|
|
||||||
|
= note: to specialize, `foo` in the parent `impl` must be marked `default`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/missing-feature-flag.rs:18:42
|
||||||
|
|
|
||||||
|
LL | async fn foo(_: i32) -> &'static str {}
|
||||||
|
| ^^ expected `&str`, found `()`
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0046, E0308, E0520.
|
||||||
|
For more information about an error, try `rustc --explain E0046`.
|
|
@ -0,0 +1,30 @@
|
||||||
|
error[E0046]: not all trait items implemented, missing: `foo`
|
||||||
|
--> $DIR/missing-feature-flag.rs:14:1
|
||||||
|
|
|
||||||
|
LL | async fn foo(_: T) -> &'static str;
|
||||||
|
| ----------------------------------- `foo` from trait
|
||||||
|
...
|
||||||
|
LL | impl<T> MyTrait<T> for MyStruct {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation
|
||||||
|
|
||||||
|
error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
|
||||||
|
--> $DIR/missing-feature-flag.rs:18:5
|
||||||
|
|
|
||||||
|
LL | impl<T> MyTrait<T> for MyStruct {}
|
||||||
|
| ------------------------------- parent `impl` is here
|
||||||
|
...
|
||||||
|
LL | async fn foo(_: i32) -> &'static str {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `foo`
|
||||||
|
|
|
||||||
|
= note: to specialize, `foo` in the parent `impl` must be marked `default`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/missing-feature-flag.rs:18:42
|
||||||
|
|
|
||||||
|
LL | async fn foo(_: i32) -> &'static str {}
|
||||||
|
| ^^ expected `&str`, found `()`
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0046, E0308, E0520.
|
||||||
|
For more information about an error, try `rustc --explain E0046`.
|
23
tests/ui/async-await/in-trait/missing-feature-flag.rs
Normal file
23
tests/ui/async-await/in-trait/missing-feature-flag.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// edition:2018
|
||||||
|
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||||
|
// revisions: current next
|
||||||
|
|
||||||
|
#![feature(async_fn_in_trait)]
|
||||||
|
#![feature(min_specialization)]
|
||||||
|
|
||||||
|
struct MyStruct;
|
||||||
|
|
||||||
|
trait MyTrait<T> {
|
||||||
|
async fn foo(_: T) -> &'static str;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> MyTrait<T> for MyStruct {}
|
||||||
|
//~^ ERROR: not all trait items implemented, missing: `foo` [E0046]
|
||||||
|
|
||||||
|
impl MyTrait<i32> for MyStruct {
|
||||||
|
async fn foo(_: i32) -> &'static str {}
|
||||||
|
//~^ ERROR: `foo` specializes an item from a parent `impl`, but that item is not marked `default` [E0520]
|
||||||
|
//~| ERROR: mismatched types [E0308]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,13 @@
|
||||||
|
#![feature(return_type_notation)]
|
||||||
|
//~^ WARN the feature `return_type_notation` is incomplete
|
||||||
|
|
||||||
|
// Shouldn't ICE when we have a (bad) RTN in an impl header
|
||||||
|
|
||||||
|
trait Super1<'a> {
|
||||||
|
fn bar<'b>() -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Super1<'_, bar(): Send> for () {}
|
||||||
|
//~^ ERROR associated type bindings are not allowed here
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,18 @@
|
||||||
|
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/rtn-in-impl-signature.rs:1:12
|
||||||
|
|
|
||||||
|
LL | #![feature(return_type_notation)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
error[E0229]: associated type bindings are not allowed here
|
||||||
|
--> $DIR/rtn-in-impl-signature.rs:10:17
|
||||||
|
|
|
||||||
|
LL | impl Super1<'_, bar(): Send> for () {}
|
||||||
|
| ^^^^^^^^^^^ associated type not allowed here
|
||||||
|
|
||||||
|
error: aborting due to previous error; 1 warning emitted
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0229`.
|
|
@ -0,0 +1,16 @@
|
||||||
|
error[E0277]: the trait bound `impl Foo<u8>: Foo<char>` is not satisfied
|
||||||
|
--> $DIR/return-dont-satisfy-bounds.rs:13:34
|
||||||
|
|
|
||||||
|
LL | fn foo<F2: Foo<u8>>(self) -> impl Foo<u8> {
|
||||||
|
| ^^^^^^^^^^^^ the trait `Foo<char>` is not implemented for `impl Foo<u8>`
|
||||||
|
|
|
||||||
|
= help: the trait `Foo<char>` is implemented for `Bar`
|
||||||
|
note: required by a bound in `Foo::foo::{opaque#0}`
|
||||||
|
--> $DIR/return-dont-satisfy-bounds.rs:7:30
|
||||||
|
|
|
||||||
|
LL | fn foo<F2>(self) -> impl Foo<T>;
|
||||||
|
| ^^^^^^ required by this bound in `Foo::foo::{opaque#0}`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
|
@ -0,0 +1,16 @@
|
||||||
|
error[E0277]: the trait bound `impl Foo<u8>: Foo<char>` is not satisfied
|
||||||
|
--> $DIR/return-dont-satisfy-bounds.rs:13:34
|
||||||
|
|
|
||||||
|
LL | fn foo<F2: Foo<u8>>(self) -> impl Foo<u8> {
|
||||||
|
| ^^^^^^^^^^^^ the trait `Foo<char>` is not implemented for `impl Foo<u8>`
|
||||||
|
|
|
||||||
|
= help: the trait `Foo<char>` is implemented for `Bar`
|
||||||
|
note: required by a bound in `Foo::{opaque#0}`
|
||||||
|
--> $DIR/return-dont-satisfy-bounds.rs:7:30
|
||||||
|
|
|
||||||
|
LL | fn foo<F2>(self) -> impl Foo<T>;
|
||||||
|
| ^^^^^^ required by this bound in `Foo::{opaque#0}`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
19
tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs
Normal file
19
tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||||
|
// revisions: current next
|
||||||
|
|
||||||
|
#![feature(return_position_impl_trait_in_trait)]
|
||||||
|
|
||||||
|
trait Foo<T> {
|
||||||
|
fn foo<F2>(self) -> impl Foo<T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Bar;
|
||||||
|
|
||||||
|
impl Foo<char> for Bar {
|
||||||
|
fn foo<F2: Foo<u8>>(self) -> impl Foo<u8> {
|
||||||
|
//~^ ERROR: the trait bound `impl Foo<u8>: Foo<char>` is not satisfied [E0277]
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -20,6 +20,7 @@ allow-unauthenticated = [
|
||||||
"regression-*",
|
"regression-*",
|
||||||
"perf-*",
|
"perf-*",
|
||||||
"AsyncAwait-OnDeck",
|
"AsyncAwait-OnDeck",
|
||||||
|
"needs-triage",
|
||||||
]
|
]
|
||||||
|
|
||||||
[glacier]
|
[glacier]
|
||||||
|
@ -254,6 +255,9 @@ trigger_files = [
|
||||||
[autolabel."S-waiting-on-review"]
|
[autolabel."S-waiting-on-review"]
|
||||||
new_pr = true
|
new_pr = true
|
||||||
|
|
||||||
|
[autolabel."needs-triage"]
|
||||||
|
new_issue = true
|
||||||
|
|
||||||
[autolabel."WG-trait-system-refactor"]
|
[autolabel."WG-trait-system-refactor"]
|
||||||
trigger_files = [
|
trigger_files = [
|
||||||
"compiler/rustc_trait_selection/src/solve",
|
"compiler/rustc_trait_selection/src/solve",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue