Require any function with a tait in its signature to actually constrain a hidden type
This commit is contained in:
parent
39e7bf6826
commit
0bc2001879
116 changed files with 1524 additions and 708 deletions
|
@ -2,20 +2,23 @@
|
||||||
|
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
trait T {
|
mod helper {
|
||||||
type Item;
|
pub trait T {
|
||||||
}
|
type Item;
|
||||||
|
}
|
||||||
|
|
||||||
type Alias<'a> = impl T<Item = &'a ()>;
|
pub type Alias<'a> = impl T<Item = &'a ()>;
|
||||||
|
|
||||||
struct S;
|
struct S;
|
||||||
impl<'a> T for &'a S {
|
impl<'a> T for &'a S {
|
||||||
type Item = &'a ();
|
type Item = &'a ();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_positive<'a>() -> Alias<'a> {
|
pub fn filter_positive<'a>() -> Alias<'a> {
|
||||||
&S
|
&S
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
use helper::*;
|
||||||
|
|
||||||
fn with_positive(fun: impl Fn(Alias<'_>)) {
|
fn with_positive(fun: impl Fn(Alias<'_>)) {
|
||||||
fun(filter_positive());
|
fun(filter_positive());
|
||||||
|
|
|
@ -146,8 +146,6 @@ pub enum ProcessResult<O, E> {
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||||
struct ObligationTreeId(usize);
|
struct ObligationTreeId(usize);
|
||||||
|
|
||||||
type ObligationTreeIdGenerator = impl Iterator<Item = ObligationTreeId>;
|
|
||||||
|
|
||||||
pub struct ObligationForest<O: ForestObligation> {
|
pub struct ObligationForest<O: ForestObligation> {
|
||||||
/// The list of obligations. In between calls to [Self::process_obligations],
|
/// The list of obligations. In between calls to [Self::process_obligations],
|
||||||
/// this list only contains nodes in the `Pending` or `Waiting` state.
|
/// this list only contains nodes in the `Pending` or `Waiting` state.
|
||||||
|
@ -310,18 +308,25 @@ pub struct Error<O, E> {
|
||||||
pub backtrace: Vec<O>,
|
pub backtrace: Vec<O>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<O: ForestObligation> ObligationForest<O> {
|
mod helper {
|
||||||
pub fn new() -> ObligationForest<O> {
|
use super::*;
|
||||||
ObligationForest {
|
pub type ObligationTreeIdGenerator = impl Iterator<Item = ObligationTreeId>;
|
||||||
nodes: vec![],
|
impl<O: ForestObligation> ObligationForest<O> {
|
||||||
done_cache: Default::default(),
|
pub fn new() -> ObligationForest<O> {
|
||||||
active_cache: Default::default(),
|
ObligationForest {
|
||||||
reused_node_vec: vec![],
|
nodes: vec![],
|
||||||
obligation_tree_id_generator: (0..).map(ObligationTreeId),
|
done_cache: Default::default(),
|
||||||
error_cache: Default::default(),
|
active_cache: Default::default(),
|
||||||
|
reused_node_vec: vec![],
|
||||||
|
obligation_tree_id_generator: (0..).map(ObligationTreeId),
|
||||||
|
error_cache: Default::default(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
use helper::*;
|
||||||
|
|
||||||
|
impl<O: ForestObligation> ObligationForest<O> {
|
||||||
/// Returns the total number of nodes in the forest that have not
|
/// Returns the total number of nodes in the forest that have not
|
||||||
/// yet been fully resolved.
|
/// yet been fully resolved.
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
|
|
|
@ -460,6 +460,10 @@ hir_analysis_static_specialize = cannot specialize on `'static` lifetime
|
||||||
hir_analysis_tait_forward_compat = item constrains opaque type that is not in its signature
|
hir_analysis_tait_forward_compat = item constrains opaque type that is not in its signature
|
||||||
.note = this item must mention the opaque type in its signature in order to be able to register hidden types
|
.note = this item must mention the opaque type in its signature in order to be able to register hidden types
|
||||||
|
|
||||||
|
hir_analysis_tait_forward_compat2 = item does not constrain `{$opaque_type}`, but has it in its signature
|
||||||
|
.note = consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
.opaque = this opaque type is in the signature
|
||||||
|
|
||||||
hir_analysis_target_feature_on_main = `main` function is not allowed to have `#[target_feature]`
|
hir_analysis_target_feature_on_main = `main` function is not allowed to have `#[target_feature]`
|
||||||
|
|
||||||
hir_analysis_too_large_static = extern static is too large for the current architecture
|
hir_analysis_too_large_static = extern static is too large for the current architecture
|
||||||
|
|
|
@ -8,7 +8,7 @@ use rustc_middle::hir::nested_filter;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
|
||||||
use rustc_span::{sym, ErrorGuaranteed, DUMMY_SP};
|
use rustc_span::{sym, ErrorGuaranteed, DUMMY_SP};
|
||||||
|
|
||||||
use crate::errors::{TaitForwardCompat, TypeOf, UnconstrainedOpaqueType};
|
use crate::errors::{TaitForwardCompat, TaitForwardCompat2, TypeOf, UnconstrainedOpaqueType};
|
||||||
|
|
||||||
pub fn test_opaque_hidden_types(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
|
pub fn test_opaque_hidden_types(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
|
||||||
let mut res = Ok(());
|
let mut res = Ok(());
|
||||||
|
@ -229,13 +229,14 @@ impl TaitConstraintLocator<'_> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let opaque_types_defined_by = self.tcx.opaque_types_defined_by(item_def_id);
|
||||||
|
|
||||||
let mut constrained = false;
|
let mut constrained = false;
|
||||||
for (&opaque_type_key, &hidden_type) in &tables.concrete_opaque_types {
|
for (&opaque_type_key, &hidden_type) in &tables.concrete_opaque_types {
|
||||||
if opaque_type_key.def_id != self.def_id {
|
if opaque_type_key.def_id != self.def_id {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
constrained = true;
|
constrained = true;
|
||||||
let opaque_types_defined_by = self.tcx.opaque_types_defined_by(item_def_id);
|
|
||||||
|
|
||||||
if !opaque_types_defined_by.contains(&self.def_id) {
|
if !opaque_types_defined_by.contains(&self.def_id) {
|
||||||
self.tcx.dcx().emit_err(TaitForwardCompat {
|
self.tcx.dcx().emit_err(TaitForwardCompat {
|
||||||
|
@ -259,6 +260,16 @@ impl TaitConstraintLocator<'_> {
|
||||||
|
|
||||||
if !constrained {
|
if !constrained {
|
||||||
debug!("no constraints in typeck results");
|
debug!("no constraints in typeck results");
|
||||||
|
if opaque_types_defined_by.contains(&self.def_id) {
|
||||||
|
self.tcx.dcx().emit_err(TaitForwardCompat2 {
|
||||||
|
span: self
|
||||||
|
.tcx
|
||||||
|
.def_ident_span(item_def_id)
|
||||||
|
.unwrap_or_else(|| self.tcx.def_span(item_def_id)),
|
||||||
|
opaque_type_span: self.tcx.def_span(self.def_id),
|
||||||
|
opaque_type: self.tcx.def_path_str(self.def_id),
|
||||||
|
});
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -390,6 +390,17 @@ pub struct TaitForwardCompat {
|
||||||
pub item_span: Span,
|
pub item_span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(hir_analysis_tait_forward_compat2)]
|
||||||
|
#[note]
|
||||||
|
pub struct TaitForwardCompat2 {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
#[note(hir_analysis_opaque)]
|
||||||
|
pub opaque_type_span: Span,
|
||||||
|
pub opaque_type: String,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct MissingTypeParams {
|
pub struct MissingTypeParams {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub def_span: Span,
|
pub def_span: Span,
|
||||||
|
|
|
@ -377,9 +377,6 @@ pub struct Terminator<'tcx> {
|
||||||
pub kind: TerminatorKind<'tcx>,
|
pub kind: TerminatorKind<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Successors<'a> = impl DoubleEndedIterator<Item = BasicBlock> + 'a;
|
|
||||||
pub type SuccessorsMut<'a> = impl DoubleEndedIterator<Item = &'a mut BasicBlock> + 'a;
|
|
||||||
|
|
||||||
impl<'tcx> Terminator<'tcx> {
|
impl<'tcx> Terminator<'tcx> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn successors(&self) -> Successors<'_> {
|
pub fn successors(&self) -> Successors<'_> {
|
||||||
|
@ -407,81 +404,95 @@ impl<'tcx> TerminatorKind<'tcx> {
|
||||||
pub fn if_(cond: Operand<'tcx>, t: BasicBlock, f: BasicBlock) -> TerminatorKind<'tcx> {
|
pub fn if_(cond: Operand<'tcx>, t: BasicBlock, f: BasicBlock) -> TerminatorKind<'tcx> {
|
||||||
TerminatorKind::SwitchInt { discr: cond, targets: SwitchTargets::static_if(0, f, t) }
|
TerminatorKind::SwitchInt { discr: cond, targets: SwitchTargets::static_if(0, f, t) }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
pub use helper::*;
|
||||||
pub fn successors(&self) -> Successors<'_> {
|
|
||||||
use self::TerminatorKind::*;
|
mod helper {
|
||||||
match *self {
|
use super::*;
|
||||||
Call { target: Some(ref t), unwind: UnwindAction::Cleanup(u), .. }
|
pub type Successors<'a> = impl DoubleEndedIterator<Item = BasicBlock> + 'a;
|
||||||
| Yield { resume: ref t, drop: Some(u), .. }
|
pub type SuccessorsMut<'a> = impl DoubleEndedIterator<Item = &'a mut BasicBlock> + 'a;
|
||||||
| Drop { target: ref t, unwind: UnwindAction::Cleanup(u), .. }
|
impl<'tcx> TerminatorKind<'tcx> {
|
||||||
| Assert { target: ref t, unwind: UnwindAction::Cleanup(u), .. }
|
#[inline]
|
||||||
| FalseUnwind { real_target: ref t, unwind: UnwindAction::Cleanup(u) } => {
|
pub fn successors(&self) -> Successors<'_> {
|
||||||
slice::from_ref(t).into_iter().copied().chain(Some(u))
|
use self::TerminatorKind::*;
|
||||||
|
match *self {
|
||||||
|
Call { target: Some(ref t), unwind: UnwindAction::Cleanup(u), .. }
|
||||||
|
| Yield { resume: ref t, drop: Some(u), .. }
|
||||||
|
| Drop { target: ref t, unwind: UnwindAction::Cleanup(u), .. }
|
||||||
|
| Assert { target: ref t, unwind: UnwindAction::Cleanup(u), .. }
|
||||||
|
| FalseUnwind { real_target: ref t, unwind: UnwindAction::Cleanup(u) } => {
|
||||||
|
slice::from_ref(t).into_iter().copied().chain(Some(u))
|
||||||
|
}
|
||||||
|
Goto { target: ref t }
|
||||||
|
| Call { target: None, unwind: UnwindAction::Cleanup(ref t), .. }
|
||||||
|
| Call { target: Some(ref t), unwind: _, .. }
|
||||||
|
| Yield { resume: ref t, drop: None, .. }
|
||||||
|
| Drop { target: ref t, unwind: _, .. }
|
||||||
|
| Assert { target: ref t, unwind: _, .. }
|
||||||
|
| FalseUnwind { real_target: ref t, unwind: _ } => {
|
||||||
|
slice::from_ref(t).into_iter().copied().chain(None)
|
||||||
|
}
|
||||||
|
UnwindResume
|
||||||
|
| UnwindTerminate(_)
|
||||||
|
| CoroutineDrop
|
||||||
|
| Return
|
||||||
|
| Unreachable
|
||||||
|
| Call { target: None, unwind: _, .. } => (&[]).into_iter().copied().chain(None),
|
||||||
|
InlineAsm { ref targets, unwind: UnwindAction::Cleanup(u), .. } => {
|
||||||
|
targets.iter().copied().chain(Some(u))
|
||||||
|
}
|
||||||
|
InlineAsm { ref targets, unwind: _, .. } => targets.iter().copied().chain(None),
|
||||||
|
SwitchInt { ref targets, .. } => targets.targets.iter().copied().chain(None),
|
||||||
|
FalseEdge { ref real_target, imaginary_target } => {
|
||||||
|
slice::from_ref(real_target).into_iter().copied().chain(Some(imaginary_target))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Goto { target: ref t }
|
}
|
||||||
| Call { target: None, unwind: UnwindAction::Cleanup(ref t), .. }
|
|
||||||
| Call { target: Some(ref t), unwind: _, .. }
|
#[inline]
|
||||||
| Yield { resume: ref t, drop: None, .. }
|
pub fn successors_mut(&mut self) -> SuccessorsMut<'_> {
|
||||||
| Drop { target: ref t, unwind: _, .. }
|
use self::TerminatorKind::*;
|
||||||
| Assert { target: ref t, unwind: _, .. }
|
match *self {
|
||||||
| FalseUnwind { real_target: ref t, unwind: _ } => {
|
Call {
|
||||||
slice::from_ref(t).into_iter().copied().chain(None)
|
target: Some(ref mut t), unwind: UnwindAction::Cleanup(ref mut u), ..
|
||||||
}
|
}
|
||||||
UnwindResume
|
| Yield { resume: ref mut t, drop: Some(ref mut u), .. }
|
||||||
| UnwindTerminate(_)
|
| Drop { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. }
|
||||||
| CoroutineDrop
|
| Assert { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. }
|
||||||
| Return
|
| FalseUnwind {
|
||||||
| Unreachable
|
real_target: ref mut t,
|
||||||
| Call { target: None, unwind: _, .. } => (&[]).into_iter().copied().chain(None),
|
unwind: UnwindAction::Cleanup(ref mut u),
|
||||||
InlineAsm { ref targets, unwind: UnwindAction::Cleanup(u), .. } => {
|
} => slice::from_mut(t).into_iter().chain(Some(u)),
|
||||||
targets.iter().copied().chain(Some(u))
|
Goto { target: ref mut t }
|
||||||
}
|
| Call { target: None, unwind: UnwindAction::Cleanup(ref mut t), .. }
|
||||||
InlineAsm { ref targets, unwind: _, .. } => targets.iter().copied().chain(None),
|
| Call { target: Some(ref mut t), unwind: _, .. }
|
||||||
SwitchInt { ref targets, .. } => targets.targets.iter().copied().chain(None),
|
| Yield { resume: ref mut t, drop: None, .. }
|
||||||
FalseEdge { ref real_target, imaginary_target } => {
|
| Drop { target: ref mut t, unwind: _, .. }
|
||||||
slice::from_ref(real_target).into_iter().copied().chain(Some(imaginary_target))
|
| Assert { target: ref mut t, unwind: _, .. }
|
||||||
}
|
| FalseUnwind { real_target: ref mut t, unwind: _ } => {
|
||||||
}
|
slice::from_mut(t).into_iter().chain(None)
|
||||||
}
|
}
|
||||||
|
UnwindResume
|
||||||
#[inline]
|
| UnwindTerminate(_)
|
||||||
pub fn successors_mut(&mut self) -> SuccessorsMut<'_> {
|
| CoroutineDrop
|
||||||
use self::TerminatorKind::*;
|
| Return
|
||||||
match *self {
|
| Unreachable
|
||||||
Call { target: Some(ref mut t), unwind: UnwindAction::Cleanup(ref mut u), .. }
|
| Call { target: None, unwind: _, .. } => (&mut []).into_iter().chain(None),
|
||||||
| Yield { resume: ref mut t, drop: Some(ref mut u), .. }
|
InlineAsm { ref mut targets, unwind: UnwindAction::Cleanup(ref mut u), .. } => {
|
||||||
| Drop { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. }
|
targets.iter_mut().chain(Some(u))
|
||||||
| Assert { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. }
|
}
|
||||||
| FalseUnwind { real_target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u) } => {
|
InlineAsm { ref mut targets, unwind: _, .. } => targets.iter_mut().chain(None),
|
||||||
slice::from_mut(t).into_iter().chain(Some(u))
|
SwitchInt { ref mut targets, .. } => targets.targets.iter_mut().chain(None),
|
||||||
}
|
FalseEdge { ref mut real_target, ref mut imaginary_target } => {
|
||||||
Goto { target: ref mut t }
|
slice::from_mut(real_target).into_iter().chain(Some(imaginary_target))
|
||||||
| Call { target: None, unwind: UnwindAction::Cleanup(ref mut t), .. }
|
}
|
||||||
| Call { target: Some(ref mut t), unwind: _, .. }
|
|
||||||
| Yield { resume: ref mut t, drop: None, .. }
|
|
||||||
| Drop { target: ref mut t, unwind: _, .. }
|
|
||||||
| Assert { target: ref mut t, unwind: _, .. }
|
|
||||||
| FalseUnwind { real_target: ref mut t, unwind: _ } => {
|
|
||||||
slice::from_mut(t).into_iter().chain(None)
|
|
||||||
}
|
|
||||||
UnwindResume
|
|
||||||
| UnwindTerminate(_)
|
|
||||||
| CoroutineDrop
|
|
||||||
| Return
|
|
||||||
| Unreachable
|
|
||||||
| Call { target: None, unwind: _, .. } => (&mut []).into_iter().chain(None),
|
|
||||||
InlineAsm { ref mut targets, unwind: UnwindAction::Cleanup(ref mut u), .. } => {
|
|
||||||
targets.iter_mut().chain(Some(u))
|
|
||||||
}
|
|
||||||
InlineAsm { ref mut targets, unwind: _, .. } => targets.iter_mut().chain(None),
|
|
||||||
SwitchInt { ref mut targets, .. } => targets.targets.iter_mut().chain(None),
|
|
||||||
FalseEdge { ref mut real_target, ref mut imaginary_target } => {
|
|
||||||
slice::from_mut(real_target).into_iter().chain(Some(imaginary_target))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> TerminatorKind<'tcx> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn unwind(&self) -> Option<&UnwindAction> {
|
pub fn unwind(&self) -> Option<&UnwindAction> {
|
||||||
match *self {
|
match *self {
|
||||||
|
|
|
@ -428,39 +428,43 @@ impl fmt::Display for Backtrace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type LazyResolve = impl (FnOnce() -> Capture) + Send + Sync + UnwindSafe;
|
mod helper {
|
||||||
|
use super::*;
|
||||||
|
pub(super) type LazyResolve = impl (FnOnce() -> Capture) + Send + Sync + UnwindSafe;
|
||||||
|
|
||||||
fn lazy_resolve(mut capture: Capture) -> LazyResolve {
|
pub(super) fn lazy_resolve(mut capture: Capture) -> LazyResolve {
|
||||||
move || {
|
move || {
|
||||||
// Use the global backtrace lock to synchronize this as it's a
|
// Use the global backtrace lock to synchronize this as it's a
|
||||||
// requirement of the `backtrace` crate, and then actually resolve
|
// requirement of the `backtrace` crate, and then actually resolve
|
||||||
// everything.
|
// everything.
|
||||||
let _lock = lock();
|
let _lock = lock();
|
||||||
for frame in capture.frames.iter_mut() {
|
for frame in capture.frames.iter_mut() {
|
||||||
let symbols = &mut frame.symbols;
|
let symbols = &mut frame.symbols;
|
||||||
let frame = match &frame.frame {
|
let frame = match &frame.frame {
|
||||||
RawFrame::Actual(frame) => frame,
|
RawFrame::Actual(frame) => frame,
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
RawFrame::Fake => unimplemented!(),
|
RawFrame::Fake => unimplemented!(),
|
||||||
};
|
};
|
||||||
unsafe {
|
unsafe {
|
||||||
backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| {
|
backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| {
|
||||||
symbols.push(BacktraceSymbol {
|
symbols.push(BacktraceSymbol {
|
||||||
name: symbol.name().map(|m| m.as_bytes().to_vec()),
|
name: symbol.name().map(|m| m.as_bytes().to_vec()),
|
||||||
filename: symbol.filename_raw().map(|b| match b {
|
filename: symbol.filename_raw().map(|b| match b {
|
||||||
BytesOrWideString::Bytes(b) => BytesOrWide::Bytes(b.to_owned()),
|
BytesOrWideString::Bytes(b) => BytesOrWide::Bytes(b.to_owned()),
|
||||||
BytesOrWideString::Wide(b) => BytesOrWide::Wide(b.to_owned()),
|
BytesOrWideString::Wide(b) => BytesOrWide::Wide(b.to_owned()),
|
||||||
}),
|
}),
|
||||||
lineno: symbol.lineno(),
|
lineno: symbol.lineno(),
|
||||||
colno: symbol.colno(),
|
colno: symbol.colno(),
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
capture
|
capture
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
use helper::*;
|
||||||
|
|
||||||
impl RawFrame {
|
impl RawFrame {
|
||||||
fn ip(&self) -> *mut c_void {
|
fn ip(&self) -> *mut c_void {
|
||||||
|
|
|
@ -9,15 +9,18 @@
|
||||||
|
|
||||||
extern crate core;
|
extern crate core;
|
||||||
|
|
||||||
pub type Type1 = impl Send;
|
mod defining_module {
|
||||||
|
pub type Type1 = impl Send;
|
||||||
|
|
||||||
pub fn foo()
|
pub fn foo()
|
||||||
where
|
where
|
||||||
Type1: 'static,
|
Type1: 'static,
|
||||||
{
|
{
|
||||||
pub struct Foo<T, const N: usize>([T; N]);
|
pub struct Foo<T, const N: usize>([T; N]);
|
||||||
let _: Type1 = Foo([0; 32]);
|
let _: Type1 = Foo([0; 32]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
use defining_module::*;
|
||||||
|
|
||||||
pub fn foo1(_: Type1) {}
|
pub fn foo1(_: Type1) {}
|
||||||
// CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
// CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||||
|
@ -26,6 +29,6 @@ pub fn foo2(_: Type1, _: Type1) {}
|
||||||
pub fn foo3(_: Type1, _: Type1, _: Type1) {}
|
pub fn foo3(_: Type1, _: Type1, _: Type1) {}
|
||||||
// CHECK: define{{.*}}4foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
// CHECK: define{{.*}}4foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||||
|
|
||||||
// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo3FooIu3i32Lu5usize32EEE"}
|
// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo3FooIu3i32Lu5usize32EEE"}
|
||||||
// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo3FooIu3i32Lu5usize32EES2_E"}
|
// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo3FooIu3i32Lu5usize32EES2_E"}
|
||||||
// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo3FooIu3i32Lu5usize32EES2_S2_E"}
|
// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo3FooIu3i32Lu5usize32EES2_S2_E"}
|
||||||
|
|
|
@ -9,17 +9,22 @@
|
||||||
|
|
||||||
extern crate core;
|
extern crate core;
|
||||||
|
|
||||||
pub type Type1 = impl Send;
|
mod defining_module {
|
||||||
|
|
||||||
pub fn foo<'a>()
|
pub type Type1 = impl Send;
|
||||||
where
|
|
||||||
Type1: 'static,
|
pub fn foo<'a>()
|
||||||
{
|
where
|
||||||
pub struct Foo<'a>(&'a i32);
|
Type1: 'static,
|
||||||
pub struct Bar<'a, 'b>(&'a i32, &'b Foo<'b>);
|
{
|
||||||
let _: Type1 = Bar;
|
pub struct Foo<'a>(&'a i32);
|
||||||
|
pub struct Bar<'a, 'b>(&'a i32, &'b Foo<'b>);
|
||||||
|
let _: Type1 = Bar;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use defining_module::*;
|
||||||
|
|
||||||
pub fn foo1(_: Type1) {}
|
pub fn foo1(_: Type1) {}
|
||||||
// CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
// CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||||
pub fn foo2(_: Type1, _: Type1) {}
|
pub fn foo2(_: Type1, _: Type1) {}
|
||||||
|
|
|
@ -9,45 +9,47 @@
|
||||||
|
|
||||||
extern crate core;
|
extern crate core;
|
||||||
|
|
||||||
pub type Type1 = impl Send;
|
mod defining_module {
|
||||||
pub type Type2 = impl Send;
|
pub type Type1 = impl Send;
|
||||||
pub type Type3 = impl Send;
|
pub type Type2 = impl Send;
|
||||||
pub type Type4 = impl Send;
|
pub type Type3 = impl Send;
|
||||||
|
pub type Type4 = impl Send;
|
||||||
|
|
||||||
pub fn foo()
|
pub fn foo()
|
||||||
where
|
where
|
||||||
Type1: 'static,
|
Type1: 'static,
|
||||||
Type2: 'static,
|
Type2: 'static,
|
||||||
Type3: 'static,
|
Type4: 'static,
|
||||||
Type4: 'static,
|
{
|
||||||
{
|
// Type in extern path
|
||||||
// Type in extern path
|
extern "C" {
|
||||||
extern "C" {
|
fn bar();
|
||||||
fn bar();
|
|
||||||
}
|
|
||||||
let _: Type1 = bar;
|
|
||||||
|
|
||||||
// Type in closure path
|
|
||||||
|| {
|
|
||||||
pub struct Foo;
|
|
||||||
let _: Type2 = Foo;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Type in const path
|
|
||||||
const {
|
|
||||||
pub struct Foo;
|
|
||||||
fn bar() -> Type3 {
|
|
||||||
Foo
|
|
||||||
}
|
}
|
||||||
};
|
let _: Type1 = bar;
|
||||||
|
|
||||||
// Type in impl path
|
// Type in closure path
|
||||||
struct Foo;
|
|| {
|
||||||
impl Foo {
|
pub struct Foo;
|
||||||
fn bar(&self) {}
|
let _: Type2 = Foo;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Type in const path
|
||||||
|
const {
|
||||||
|
pub struct Foo;
|
||||||
|
fn bar() -> Type3 {
|
||||||
|
Foo
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Type in impl path
|
||||||
|
struct Foo;
|
||||||
|
impl Foo {
|
||||||
|
fn bar(&self) {}
|
||||||
|
}
|
||||||
|
let _: Type4 = <Foo>::bar;
|
||||||
}
|
}
|
||||||
let _: Type4 = <Foo>::bar;
|
|
||||||
}
|
}
|
||||||
|
use defining_module::*;
|
||||||
|
|
||||||
// Force arguments to be passed by using a reference. Otherwise, they may end up PassMode::Ignore
|
// Force arguments to be passed by using a reference. Otherwise, they may end up PassMode::Ignore
|
||||||
|
|
||||||
|
@ -76,15 +78,15 @@ pub fn foo11(_: &Type4, _: &Type4) {}
|
||||||
pub fn foo12(_: &Type4, _: &Type4, _: &Type4) {}
|
pub fn foo12(_: &Type4, _: &Type4, _: &Type4) {}
|
||||||
// CHECK: define{{.*}}5foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
// CHECK: define{{.*}}5foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||||
|
|
||||||
// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo10{{[{}][{}]}}extern{{[}][}]}}3barEE"}
|
// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo10{{[{}][{}]}}extern{{[}][}]}}3barEE"}
|
||||||
// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo10{{[{}][{}]}}extern{{[}][}]}}3barES0_E"}
|
// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo10{{[{}][{}]}}extern{{[}][}]}}3barES0_E"}
|
||||||
// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo10{{[{}][{}]}}extern{{[}][}]}}3barES0_S0_E"}
|
// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo10{{[{}][{}]}}extern{{[}][}]}}3barES0_S0_E"}
|
||||||
// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo11{{[{}][{}]}}closure{{[}][}]}}3FooEE"}
|
// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo11{{[{}][{}]}}closure{{[}][}]}}3FooEE"}
|
||||||
// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_E"}
|
// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_E"}
|
||||||
// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_S0_E"}
|
// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_S0_E"}
|
||||||
// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo12{{[{}][{}]}}constant{{[}][}]}}3FooEE"}
|
// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo12{{[{}][{}]}}constant{{[}][}]}}3FooEE"}
|
||||||
// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_E"}
|
// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_E"}
|
||||||
// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_S0_E"}
|
// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_S0_E"}
|
||||||
// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo8{{[{}][{}]}}impl{{[}][}]}}3barEE"}
|
// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo8{{[{}][{}]}}impl{{[}][}]}}3barEE"}
|
||||||
// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_E"}
|
// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_E"}
|
||||||
// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_S0_E"}
|
// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_S0_E"}
|
||||||
|
|
|
@ -6,6 +6,7 @@ type Foo = impl Sized;
|
||||||
|
|
||||||
fn foo<const C: Foo>() {}
|
fn foo<const C: Foo>() {}
|
||||||
//~^ ERROR: `Foo` is forbidden as the type of a const generic parameter
|
//~^ ERROR: `Foo` is forbidden as the type of a const generic parameter
|
||||||
|
//~| ERROR: item does not constrain
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
foo::<42>();
|
foo::<42>();
|
||||||
|
|
|
@ -1,5 +1,18 @@
|
||||||
|
error: item does not constrain `Foo::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/opaque_types.rs:7:4
|
||||||
|
|
|
||||||
|
LL | fn foo<const C: Foo>() {}
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/opaque_types.rs:3:12
|
||||||
|
|
|
||||||
|
LL | type Foo = impl Sized;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/opaque_types.rs:11:11
|
--> $DIR/opaque_types.rs:12:11
|
||||||
|
|
|
|
||||||
LL | type Foo = impl Sized;
|
LL | type Foo = impl Sized;
|
||||||
| ---------- the expected opaque type
|
| ---------- the expected opaque type
|
||||||
|
@ -22,27 +35,27 @@ note: ...which requires computing type of opaque `Foo::{opaque#0}`...
|
||||||
LL | type Foo = impl Sized;
|
LL | type Foo = impl Sized;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
note: ...which requires type-checking `main`...
|
note: ...which requires type-checking `main`...
|
||||||
--> $DIR/opaque_types.rs:10:1
|
--> $DIR/opaque_types.rs:11:1
|
||||||
|
|
|
|
||||||
LL | fn main() {
|
LL | fn main() {
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
note: ...which requires evaluating type-level constant...
|
note: ...which requires evaluating type-level constant...
|
||||||
--> $DIR/opaque_types.rs:11:11
|
--> $DIR/opaque_types.rs:12:11
|
||||||
|
|
|
|
||||||
LL | foo::<42>();
|
LL | foo::<42>();
|
||||||
| ^^
|
| ^^
|
||||||
note: ...which requires const-evaluating + checking `main::{constant#0}`...
|
note: ...which requires const-evaluating + checking `main::{constant#0}`...
|
||||||
--> $DIR/opaque_types.rs:11:11
|
--> $DIR/opaque_types.rs:12:11
|
||||||
|
|
|
|
||||||
LL | foo::<42>();
|
LL | foo::<42>();
|
||||||
| ^^
|
| ^^
|
||||||
note: ...which requires caching mir of `main::{constant#0}` for CTFE...
|
note: ...which requires caching mir of `main::{constant#0}` for CTFE...
|
||||||
--> $DIR/opaque_types.rs:11:11
|
--> $DIR/opaque_types.rs:12:11
|
||||||
|
|
|
|
||||||
LL | foo::<42>();
|
LL | foo::<42>();
|
||||||
| ^^
|
| ^^
|
||||||
note: ...which requires elaborating drops for `main::{constant#0}`...
|
note: ...which requires elaborating drops for `main::{constant#0}`...
|
||||||
--> $DIR/opaque_types.rs:11:11
|
--> $DIR/opaque_types.rs:12:11
|
||||||
|
|
|
|
||||||
LL | foo::<42>();
|
LL | foo::<42>();
|
||||||
| ^^
|
| ^^
|
||||||
|
@ -70,42 +83,42 @@ LL | type Foo = impl Sized;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: ...which requires type-checking `main`...
|
note: ...which requires type-checking `main`...
|
||||||
--> $DIR/opaque_types.rs:10:1
|
--> $DIR/opaque_types.rs:11:1
|
||||||
|
|
|
|
||||||
LL | fn main() {
|
LL | fn main() {
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
note: ...which requires evaluating type-level constant...
|
note: ...which requires evaluating type-level constant...
|
||||||
--> $DIR/opaque_types.rs:11:11
|
--> $DIR/opaque_types.rs:12:11
|
||||||
|
|
|
|
||||||
LL | foo::<42>();
|
LL | foo::<42>();
|
||||||
| ^^
|
| ^^
|
||||||
note: ...which requires const-evaluating + checking `main::{constant#0}`...
|
note: ...which requires const-evaluating + checking `main::{constant#0}`...
|
||||||
--> $DIR/opaque_types.rs:11:11
|
--> $DIR/opaque_types.rs:12:11
|
||||||
|
|
|
|
||||||
LL | foo::<42>();
|
LL | foo::<42>();
|
||||||
| ^^
|
| ^^
|
||||||
note: ...which requires caching mir of `main::{constant#0}` for CTFE...
|
note: ...which requires caching mir of `main::{constant#0}` for CTFE...
|
||||||
--> $DIR/opaque_types.rs:11:11
|
--> $DIR/opaque_types.rs:12:11
|
||||||
|
|
|
|
||||||
LL | foo::<42>();
|
LL | foo::<42>();
|
||||||
| ^^
|
| ^^
|
||||||
note: ...which requires elaborating drops for `main::{constant#0}`...
|
note: ...which requires elaborating drops for `main::{constant#0}`...
|
||||||
--> $DIR/opaque_types.rs:11:11
|
--> $DIR/opaque_types.rs:12:11
|
||||||
|
|
|
|
||||||
LL | foo::<42>();
|
LL | foo::<42>();
|
||||||
| ^^
|
| ^^
|
||||||
note: ...which requires borrow-checking `main::{constant#0}`...
|
note: ...which requires borrow-checking `main::{constant#0}`...
|
||||||
--> $DIR/opaque_types.rs:11:11
|
--> $DIR/opaque_types.rs:12:11
|
||||||
|
|
|
|
||||||
LL | foo::<42>();
|
LL | foo::<42>();
|
||||||
| ^^
|
| ^^
|
||||||
note: ...which requires promoting constants in MIR for `main::{constant#0}`...
|
note: ...which requires promoting constants in MIR for `main::{constant#0}`...
|
||||||
--> $DIR/opaque_types.rs:11:11
|
--> $DIR/opaque_types.rs:12:11
|
||||||
|
|
|
|
||||||
LL | foo::<42>();
|
LL | foo::<42>();
|
||||||
| ^^
|
| ^^
|
||||||
note: ...which requires const checking `main::{constant#0}`...
|
note: ...which requires const checking `main::{constant#0}`...
|
||||||
--> $DIR/opaque_types.rs:11:11
|
--> $DIR/opaque_types.rs:12:11
|
||||||
|
|
|
|
||||||
LL | foo::<42>();
|
LL | foo::<42>();
|
||||||
| ^^
|
| ^^
|
||||||
|
@ -119,7 +132,7 @@ LL | type Foo = impl Sized;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0308, E0391.
|
Some errors have detailed explanations: E0308, E0391.
|
||||||
For more information about an error, try `rustc --explain E0308`.
|
For more information about an error, try `rustc --explain E0308`.
|
||||||
|
|
28
tests/ui/consts/const-fn-cycle.rs
Normal file
28
tests/ui/consts/const-fn-cycle.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/// Discovered in https://github.com/rust-lang/rust/issues/112602.
|
||||||
|
/// This caused a cycle error, which made no sense.
|
||||||
|
/// Removing the `const` part of the `many` function would make the
|
||||||
|
/// test pass again.
|
||||||
|
/// The issue was that we were running const qualif checks on
|
||||||
|
/// `const fn`s, but never using them. During const qualif checks we tend
|
||||||
|
/// to end up revealing opaque types (the RPIT in `many`'s return type),
|
||||||
|
/// which can quickly lead to cycles.
|
||||||
|
|
||||||
|
pub struct Parser<H>(H);
|
||||||
|
|
||||||
|
impl<H, T> Parser<H>
|
||||||
|
where
|
||||||
|
H: for<'a> Fn(&'a str) -> T,
|
||||||
|
{
|
||||||
|
pub const fn new(handler: H) -> Parser<H> {
|
||||||
|
Parser(handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn many<'s>(&'s self) -> Parser<impl for<'a> Fn(&'a str) -> Vec<T> + 's> {
|
||||||
|
//~^ ERROR: cycle detected
|
||||||
|
Parser::new(|_| unimplemented!())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
34
tests/ui/consts/const-fn-cycle.stderr
Normal file
34
tests/ui/consts/const-fn-cycle.stderr
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
error[E0391]: cycle detected when computing type of opaque `<impl at $DIR/const-fn-cycle.rs:12:1: 14:33>::many::{opaque#0}`
|
||||||
|
--> $DIR/const-fn-cycle.rs:20:47
|
||||||
|
|
|
||||||
|
LL | pub const fn many<'s>(&'s self) -> Parser<impl for<'a> Fn(&'a str) -> Vec<T> + 's> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: ...which requires borrow-checking `<impl at $DIR/const-fn-cycle.rs:12:1: 14:33>::many`...
|
||||||
|
--> $DIR/const-fn-cycle.rs:20:5
|
||||||
|
|
|
||||||
|
LL | pub const fn many<'s>(&'s self) -> Parser<impl for<'a> Fn(&'a str) -> Vec<T> + 's> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: ...which requires promoting constants in MIR for `<impl at $DIR/const-fn-cycle.rs:12:1: 14:33>::many`...
|
||||||
|
--> $DIR/const-fn-cycle.rs:20:5
|
||||||
|
|
|
||||||
|
LL | pub const fn many<'s>(&'s self) -> Parser<impl for<'a> Fn(&'a str) -> Vec<T> + 's> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: ...which requires const checking `<impl at $DIR/const-fn-cycle.rs:12:1: 14:33>::many`...
|
||||||
|
--> $DIR/const-fn-cycle.rs:20:5
|
||||||
|
|
|
||||||
|
LL | pub const fn many<'s>(&'s self) -> Parser<impl for<'a> Fn(&'a str) -> Vec<T> + 's> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
= note: ...which requires computing whether `Parser<<impl at $DIR/const-fn-cycle.rs:12:1: 14:33>::many::{opaque#0}>` is freeze...
|
||||||
|
= note: ...which requires evaluating trait selection obligation `Parser<<impl at $DIR/const-fn-cycle.rs:12:1: 14:33>::many::{opaque#0}>: core::marker::Freeze`...
|
||||||
|
= note: ...which again requires computing type of opaque `<impl at $DIR/const-fn-cycle.rs:12:1: 14:33>::many::{opaque#0}`, completing the cycle
|
||||||
|
note: cycle used when computing type of `<impl at $DIR/const-fn-cycle.rs:12:1: 14:33>::many::{opaque#0}`
|
||||||
|
--> $DIR/const-fn-cycle.rs:20:47
|
||||||
|
|
|
||||||
|
LL | pub const fn many<'s>(&'s self) -> Parser<impl for<'a> Fn(&'a str) -> Vec<T> + 's> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0391`.
|
71
tests/ui/consts/const-promoted-opaque.atomic.stderr
Normal file
71
tests/ui/consts/const-promoted-opaque.atomic.stderr
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
|
||||||
|
--> $DIR/const-promoted-opaque.rs:29:25
|
||||||
|
|
|
||||||
|
LL | let _: &'static _ = &FOO;
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
|
||||||
|
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
|
error[E0493]: destructor of `helper::Foo` cannot be evaluated at compile-time
|
||||||
|
--> $DIR/const-promoted-opaque.rs:29:26
|
||||||
|
|
|
||||||
|
LL | let _: &'static _ = &FOO;
|
||||||
|
| ^^^ the destructor for this type cannot be evaluated in constants
|
||||||
|
...
|
||||||
|
LL | };
|
||||||
|
| - value is dropped here
|
||||||
|
|
||||||
|
error[E0492]: constants cannot refer to interior mutable data
|
||||||
|
--> $DIR/const-promoted-opaque.rs:34:19
|
||||||
|
|
|
||||||
|
LL | const BAZ: &Foo = &FOO;
|
||||||
|
| ^^^^ this borrow of an interior mutable value may end up in the final value
|
||||||
|
|
||||||
|
error[E0716]: temporary value dropped while borrowed
|
||||||
|
--> $DIR/const-promoted-opaque.rs:38:26
|
||||||
|
|
|
||||||
|
LL | let _: &'static _ = &FOO;
|
||||||
|
| ---------- ^^^ creates a temporary value which is freed while still in use
|
||||||
|
| |
|
||||||
|
| type annotation requires that borrow lasts for `'static`
|
||||||
|
LL |
|
||||||
|
LL | }
|
||||||
|
| - temporary value is freed at the end of this statement
|
||||||
|
|
||||||
|
error[E0391]: cycle detected when computing type of opaque `helper::Foo::{opaque#0}`
|
||||||
|
--> $DIR/const-promoted-opaque.rs:14:20
|
||||||
|
|
|
||||||
|
LL | pub type Foo = impl Sized;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: ...which requires borrow-checking `helper::FOO`...
|
||||||
|
--> $DIR/const-promoted-opaque.rs:21:5
|
||||||
|
|
|
||||||
|
LL | pub const FOO: Foo = std::sync::atomic::AtomicU8::new(42);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
note: ...which requires promoting constants in MIR for `helper::FOO`...
|
||||||
|
--> $DIR/const-promoted-opaque.rs:21:5
|
||||||
|
|
|
||||||
|
LL | pub const FOO: Foo = std::sync::atomic::AtomicU8::new(42);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
note: ...which requires const checking `helper::FOO`...
|
||||||
|
--> $DIR/const-promoted-opaque.rs:21:5
|
||||||
|
|
|
||||||
|
LL | pub const FOO: Foo = std::sync::atomic::AtomicU8::new(42);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
= note: ...which requires computing whether `helper::Foo` is freeze...
|
||||||
|
= note: ...which requires evaluating trait selection obligation `helper::Foo: core::marker::Freeze`...
|
||||||
|
= note: ...which again requires computing type of opaque `helper::Foo::{opaque#0}`, completing the cycle
|
||||||
|
note: cycle used when computing type of `helper::Foo::{opaque#0}`
|
||||||
|
--> $DIR/const-promoted-opaque.rs:14:20
|
||||||
|
|
|
||||||
|
LL | pub type Foo = impl Sized;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0391, E0492, E0493, E0658, E0716.
|
||||||
|
For more information about an error, try `rustc --explain E0391`.
|
40
tests/ui/consts/const-promoted-opaque.rs
Normal file
40
tests/ui/consts/const-promoted-opaque.rs
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
//@revisions: string unit atomic
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
//! Check that we do not cause cycle errors when trying to
|
||||||
|
//! obtain information about interior mutability of an opaque type.
|
||||||
|
//! This used to happen, because when the body-analysis failed, we
|
||||||
|
//! checked the type instead, but the constant was also defining the
|
||||||
|
//! hidden type of the opaque type. Thus we ended up relying on the
|
||||||
|
//! result of our analysis to compute the result of our analysis.
|
||||||
|
|
||||||
|
//@[unit] check-pass
|
||||||
|
|
||||||
|
mod helper {
|
||||||
|
pub type Foo = impl Sized;
|
||||||
|
//[string,atomic]~^ ERROR cycle detected
|
||||||
|
|
||||||
|
#[cfg(string)]
|
||||||
|
pub const FOO: Foo = String::new();
|
||||||
|
|
||||||
|
#[cfg(atomic)]
|
||||||
|
pub const FOO: Foo = std::sync::atomic::AtomicU8::new(42);
|
||||||
|
|
||||||
|
#[cfg(unit)]
|
||||||
|
pub const FOO: Foo = ();
|
||||||
|
}
|
||||||
|
use helper::*;
|
||||||
|
|
||||||
|
const BAR: () = {
|
||||||
|
let _: &'static _ = &FOO;
|
||||||
|
//[string,atomic]~^ ERROR: destructor of `helper::Foo` cannot be evaluated at compile-time
|
||||||
|
//[string,atomic]~| ERROR: cannot borrow here
|
||||||
|
};
|
||||||
|
|
||||||
|
const BAZ: &Foo = &FOO;
|
||||||
|
//[string,atomic]~^ ERROR: constants cannot refer to interior mutable data
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _: &'static _ = &FOO;
|
||||||
|
//[string,atomic]~^ ERROR: temporary value dropped while borrowed
|
||||||
|
}
|
71
tests/ui/consts/const-promoted-opaque.string.stderr
Normal file
71
tests/ui/consts/const-promoted-opaque.string.stderr
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
|
||||||
|
--> $DIR/const-promoted-opaque.rs:29:25
|
||||||
|
|
|
||||||
|
LL | let _: &'static _ = &FOO;
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
|
||||||
|
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
|
error[E0493]: destructor of `helper::Foo` cannot be evaluated at compile-time
|
||||||
|
--> $DIR/const-promoted-opaque.rs:29:26
|
||||||
|
|
|
||||||
|
LL | let _: &'static _ = &FOO;
|
||||||
|
| ^^^ the destructor for this type cannot be evaluated in constants
|
||||||
|
...
|
||||||
|
LL | };
|
||||||
|
| - value is dropped here
|
||||||
|
|
||||||
|
error[E0492]: constants cannot refer to interior mutable data
|
||||||
|
--> $DIR/const-promoted-opaque.rs:34:19
|
||||||
|
|
|
||||||
|
LL | const BAZ: &Foo = &FOO;
|
||||||
|
| ^^^^ this borrow of an interior mutable value may end up in the final value
|
||||||
|
|
||||||
|
error[E0716]: temporary value dropped while borrowed
|
||||||
|
--> $DIR/const-promoted-opaque.rs:38:26
|
||||||
|
|
|
||||||
|
LL | let _: &'static _ = &FOO;
|
||||||
|
| ---------- ^^^ creates a temporary value which is freed while still in use
|
||||||
|
| |
|
||||||
|
| type annotation requires that borrow lasts for `'static`
|
||||||
|
LL |
|
||||||
|
LL | }
|
||||||
|
| - temporary value is freed at the end of this statement
|
||||||
|
|
||||||
|
error[E0391]: cycle detected when computing type of opaque `helper::Foo::{opaque#0}`
|
||||||
|
--> $DIR/const-promoted-opaque.rs:14:20
|
||||||
|
|
|
||||||
|
LL | pub type Foo = impl Sized;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: ...which requires borrow-checking `helper::FOO`...
|
||||||
|
--> $DIR/const-promoted-opaque.rs:18:5
|
||||||
|
|
|
||||||
|
LL | pub const FOO: Foo = String::new();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
note: ...which requires promoting constants in MIR for `helper::FOO`...
|
||||||
|
--> $DIR/const-promoted-opaque.rs:18:5
|
||||||
|
|
|
||||||
|
LL | pub const FOO: Foo = String::new();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
note: ...which requires const checking `helper::FOO`...
|
||||||
|
--> $DIR/const-promoted-opaque.rs:18:5
|
||||||
|
|
|
||||||
|
LL | pub const FOO: Foo = String::new();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
= note: ...which requires computing whether `helper::Foo` is freeze...
|
||||||
|
= note: ...which requires evaluating trait selection obligation `helper::Foo: core::marker::Freeze`...
|
||||||
|
= note: ...which again requires computing type of opaque `helper::Foo::{opaque#0}`, completing the cycle
|
||||||
|
note: cycle used when computing type of `helper::Foo::{opaque#0}`
|
||||||
|
--> $DIR/const-promoted-opaque.rs:14:20
|
||||||
|
|
|
||||||
|
LL | pub type Foo = impl Sized;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0391, E0492, E0493, E0658, E0716.
|
||||||
|
For more information about an error, try `rustc --explain E0391`.
|
|
@ -16,13 +16,22 @@ impl<F: Future> Task<F> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
mod helper {
|
||||||
async fn cb() {
|
use super::*;
|
||||||
let a = Foo; //~ ERROR cannot find value `Foo` in this scope
|
pub type F = impl Future;
|
||||||
}
|
fn foo()
|
||||||
|
where
|
||||||
|
F:,
|
||||||
|
{
|
||||||
|
async fn cb() {
|
||||||
|
let a = Foo; //~ ERROR cannot find value `Foo` in this scope
|
||||||
|
}
|
||||||
|
|
||||||
type F = impl Future;
|
Task::spawn(&POOL, || cb());
|
||||||
// Check that statics are inhabited computes they layout.
|
}
|
||||||
static POOL: Task<F> = Task::new();
|
|
||||||
Task::spawn(&POOL, || cb());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check that statics are inhabited computes they layout.
|
||||||
|
static POOL: Task<helper::F> = Task::new();
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0425]: cannot find value `Foo` in this scope
|
error[E0425]: cannot find value `Foo` in this scope
|
||||||
--> $DIR/layout-error.rs:21:17
|
--> $DIR/layout-error.rs:27:21
|
||||||
|
|
|
|
||||||
LL | let a = Foo;
|
LL | let a = Foo;
|
||||||
| ^^^ not found in this scope
|
| ^^^ not found in this scope
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -4,22 +4,23 @@
|
||||||
// Regression test for #80998.
|
// Regression test for #80998.
|
||||||
//
|
//
|
||||||
//@ aux-build:metadata-sufficient-for-layout.rs
|
//@ aux-build:metadata-sufficient-for-layout.rs
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
#![feature(type_alias_impl_trait, rustc_attrs)]
|
#![feature(type_alias_impl_trait, rustc_attrs)]
|
||||||
#![feature(coroutine_trait)]
|
#![feature(coroutine_trait)]
|
||||||
|
|
||||||
extern crate metadata_sufficient_for_layout;
|
extern crate metadata_sufficient_for_layout;
|
||||||
|
|
||||||
use std::ops::Coroutine;
|
mod helper {
|
||||||
|
use std::ops::Coroutine;
|
||||||
|
pub type F = impl Coroutine<(), Yield = (), Return = ()>;
|
||||||
|
|
||||||
type F = impl Coroutine<(), Yield = (), Return = ()>;
|
fn f() -> F {
|
||||||
|
metadata_sufficient_for_layout::g()
|
||||||
// Static queries the layout of the coroutine.
|
}
|
||||||
static A: Option<F> = None;
|
|
||||||
|
|
||||||
fn f() -> F {
|
|
||||||
metadata_sufficient_for_layout::g()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_error]
|
// Static queries the layout of the coroutine.
|
||||||
fn main() {} //~ ERROR
|
static A: Option<helper::F> = None;
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
error: fatal error triggered by #[rustc_error]
|
|
||||||
--> $DIR/metadata-sufficient-for-layout.rs:25:1
|
|
||||||
|
|
|
||||||
LL | fn main() {}
|
|
||||||
| ^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
|
@ -7,11 +7,15 @@
|
||||||
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
|
||||||
type Fut<'a> = impl Future<Output = ()> + 'a;
|
mod foo {
|
||||||
|
use std::future::Future;
|
||||||
|
pub type Fut<'a> = impl Future<Output = ()> + 'a;
|
||||||
|
|
||||||
fn foo<'a>(_: &()) -> Fut<'_> {
|
fn foo<'a>(_: &()) -> Fut<'_> {
|
||||||
async {}
|
async {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
use foo::*;
|
||||||
|
|
||||||
trait Test {
|
trait Test {
|
||||||
fn hello();
|
fn hello();
|
||||||
|
|
|
@ -11,9 +11,13 @@ fn test_closure() {
|
||||||
closure(&opaque());
|
closure(&opaque());
|
||||||
}
|
}
|
||||||
|
|
||||||
type Opaque2 = impl Sized;
|
mod helper {
|
||||||
type Opaque<'a> = Opaque2;
|
pub type Opaque2 = impl Sized;
|
||||||
fn define<'a>() -> Opaque<'a> {}
|
pub type Opaque<'a> = Opaque2;
|
||||||
|
fn define<'a>() -> Opaque<'a> {}
|
||||||
|
}
|
||||||
|
|
||||||
|
use helper::*;
|
||||||
|
|
||||||
fn test_tait(_: &Opaque<'_>) {
|
fn test_tait(_: &Opaque<'_>) {
|
||||||
None::<&'static Opaque<'_>>;
|
None::<&'static Opaque<'_>>;
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
type FooArg<'a> = &'a dyn ToString;
|
type FooArg<'a> = &'a dyn ToString;
|
||||||
type FooRet = impl std::fmt::Debug;
|
|
||||||
|
|
||||||
type FooItem = Box<dyn Fn(FooArg) -> FooRet>;
|
type FooItem = Box<dyn Fn(FooArg) -> FooRet>;
|
||||||
type Foo = impl Iterator<Item = FooItem>;
|
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct Bar(u8);
|
struct Bar(u8);
|
||||||
|
@ -17,19 +15,26 @@ impl Iterator for Bar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn quux(st: FooArg) -> FooRet {
|
mod ret {
|
||||||
Some(st.to_string())
|
pub type FooRet = impl std::fmt::Debug;
|
||||||
|
pub fn quux(st: super::FooArg) -> FooRet {
|
||||||
|
Some(st.to_string())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
use ret::*;
|
||||||
fn ham() -> Foo {
|
mod foo {
|
||||||
Bar(1)
|
pub type Foo = impl Iterator<Item = super::FooItem>;
|
||||||
}
|
pub fn ham() -> Foo {
|
||||||
|
super::Bar(1)
|
||||||
fn oof(_: Foo) -> impl std::fmt::Debug {
|
}
|
||||||
let mut bar = ham();
|
pub fn oof(_: Foo) -> impl std::fmt::Debug {
|
||||||
let func = bar.next().unwrap();
|
//~^ ERROR: item does not constrain `Foo::{opaque#0}`, but has it in its signature
|
||||||
return func(&"oof"); //~ ERROR opaque type's hidden type cannot be another opaque type
|
let mut bar = ham();
|
||||||
|
let func = bar.next().unwrap();
|
||||||
|
return func(&"oof");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
use foo::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _ = oof(ham());
|
let _ = oof(ham());
|
||||||
|
|
|
@ -1,19 +1,15 @@
|
||||||
error: opaque type's hidden type cannot be another opaque type from the same scope
|
error: item does not constrain `Foo::{opaque#0}`, but has it in its signature
|
||||||
--> $DIR/issue-70877.rs:31:12
|
--> $DIR/issue-70877.rs:30:12
|
||||||
|
|
|
|
||||||
LL | return func(&"oof");
|
LL | pub fn oof(_: Foo) -> impl std::fmt::Debug {
|
||||||
| ^^^^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope
|
| ^^^
|
||||||
|
|
|
|
||||||
note: opaque type whose hidden type is being assigned
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
--> $DIR/issue-70877.rs:28:19
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/issue-70877.rs:26:20
|
||||||
|
|
|
|
||||||
LL | fn oof(_: Foo) -> impl std::fmt::Debug {
|
LL | pub type Foo = impl Iterator<Item = super::FooItem>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
note: opaque type being used as hidden type
|
|
||||||
--> $DIR/issue-70877.rs:4:15
|
|
||||||
|
|
|
||||||
LL | type FooRet = impl std::fmt::Debug;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -2,19 +2,20 @@
|
||||||
|
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
|
|
||||||
trait Foo<T> {}
|
pub trait Foo<T> {}
|
||||||
impl<T, U> Foo<T> for U {}
|
impl<T, U> Foo<T> for U {}
|
||||||
|
|
||||||
type Scope = impl Foo<()>;
|
mod scope {
|
||||||
|
pub type Scope = impl super::Foo<()>;
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
fn infer_scope() -> Scope {
|
fn infer_scope() -> Scope {
|
||||||
()
|
()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
fn ice() -> impl Foo<Scope>
|
fn ice() -> impl Foo<scope::Scope> {
|
||||||
{
|
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>
|
||||||
//~^ ERROR unconstrained opaque type
|
//~^ ERROR unconstrained opaque type
|
||||||
|
|
||||||
fn execute_transaction_fut<'f, F, O>(
|
fn execute_transaction_fut<'f, F, O>(
|
||||||
|
//~^ ERROR: item does not constrain
|
||||||
f: F,
|
f: F,
|
||||||
) -> impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O>
|
) -> impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O>
|
||||||
where
|
where
|
||||||
|
@ -37,10 +38,12 @@ where
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
async fn do_transaction<O>(
|
async fn do_transaction<O>(
|
||||||
|
//~^ ERROR: item does not constrain
|
||||||
&self, f: impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O>
|
&self, f: impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O>
|
||||||
) -> TransactionResult<O>
|
) -> TransactionResult<O>
|
||||||
{
|
{
|
||||||
//~^ ERROR expected generic lifetime parameter, found `'_`
|
//~^ ERROR expected generic lifetime parameter, found `'_`
|
||||||
|
//~| ERROR: item does not constrain
|
||||||
let mut conn = Connection {};
|
let mut conn = Connection {};
|
||||||
let mut transaction = TestTransaction { conn: &mut conn };
|
let mut transaction = TestTransaction { conn: &mut conn };
|
||||||
f(&mut transaction).await
|
f(&mut transaction).await
|
||||||
|
|
|
@ -1,3 +1,48 @@
|
||||||
|
error: item does not constrain `TransactionFuture::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/issue-86800.rs:28:4
|
||||||
|
|
|
||||||
|
LL | fn execute_transaction_fut<'f, F, O>(
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/issue-86800.rs:25:34
|
||||||
|
|
|
||||||
|
LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: item does not constrain `TransactionFuture::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/issue-86800.rs:40:14
|
||||||
|
|
|
||||||
|
LL | async fn do_transaction<O>(
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/issue-86800.rs:25:34
|
||||||
|
|
|
||||||
|
LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: item does not constrain `TransactionFuture::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/issue-86800.rs:44:5
|
||||||
|
|
|
||||||
|
LL | / {
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
LL | | let mut conn = Connection {};
|
||||||
|
LL | | let mut transaction = TestTransaction { conn: &mut conn };
|
||||||
|
LL | | f(&mut transaction).await
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/issue-86800.rs:25:34
|
||||||
|
|
|
||||||
|
LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: unconstrained opaque type
|
error: unconstrained opaque type
|
||||||
--> $DIR/issue-86800.rs:25:34
|
--> $DIR/issue-86800.rs:25:34
|
||||||
|
|
|
|
||||||
|
@ -7,7 +52,7 @@ LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResu
|
||||||
= note: `TransactionFuture` must be used in combination with a concrete type within the same module
|
= note: `TransactionFuture` must be used in combination with a concrete type within the same module
|
||||||
|
|
||||||
error[E0792]: expected generic lifetime parameter, found `'_`
|
error[E0792]: expected generic lifetime parameter, found `'_`
|
||||||
--> $DIR/issue-86800.rs:34:5
|
--> $DIR/issue-86800.rs:35:5
|
||||||
|
|
|
|
||||||
LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
|
LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
|
||||||
| --- this generic parameter must be used with a generic lifetime parameter
|
| --- this generic parameter must be used with a generic lifetime parameter
|
||||||
|
@ -16,19 +61,20 @@ LL | f
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error[E0792]: expected generic lifetime parameter, found `'_`
|
error[E0792]: expected generic lifetime parameter, found `'_`
|
||||||
--> $DIR/issue-86800.rs:42:5
|
--> $DIR/issue-86800.rs:44:5
|
||||||
|
|
|
|
||||||
LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
|
LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
|
||||||
| --- this generic parameter must be used with a generic lifetime parameter
|
| --- this generic parameter must be used with a generic lifetime parameter
|
||||||
...
|
...
|
||||||
LL | / {
|
LL | / {
|
||||||
LL | |
|
LL | |
|
||||||
|
LL | |
|
||||||
LL | | let mut conn = Connection {};
|
LL | | let mut conn = Connection {};
|
||||||
LL | | let mut transaction = TestTransaction { conn: &mut conn };
|
LL | | let mut transaction = TestTransaction { conn: &mut conn };
|
||||||
LL | | f(&mut transaction).await
|
LL | | f(&mut transaction).await
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_____^
|
| |_____^
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0792`.
|
For more information about this error, try `rustc --explain E0792`.
|
||||||
|
|
|
@ -2,18 +2,23 @@
|
||||||
|
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
|
|
||||||
trait T { type Item; }
|
mod helper {
|
||||||
|
pub trait T {
|
||||||
|
type Item;
|
||||||
|
}
|
||||||
|
|
||||||
type Alias<'a> = impl T<Item = &'a ()>;
|
pub type Alias<'a> = impl T<Item = &'a ()>;
|
||||||
|
|
||||||
struct S;
|
struct S;
|
||||||
impl<'a> T for &'a S {
|
impl<'a> T for &'a S {
|
||||||
type Item = &'a ();
|
type Item = &'a ();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_positive<'a>() -> Alias<'a> {
|
pub fn filter_positive<'a>() -> Alias<'a> {
|
||||||
&S
|
&S
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
use helper::*;
|
||||||
|
|
||||||
fn with_positive(fun: impl Fn(Alias<'_>)) {
|
fn with_positive(fun: impl Fn(Alias<'_>)) {
|
||||||
fun(filter_positive());
|
fun(filter_positive());
|
||||||
|
|
|
@ -6,20 +6,23 @@
|
||||||
|
|
||||||
use std::marker::Destruct;
|
use std::marker::Destruct;
|
||||||
|
|
||||||
trait T {
|
mod foo {
|
||||||
type Item;
|
trait T {
|
||||||
}
|
type Item;
|
||||||
|
}
|
||||||
|
|
||||||
type Alias<'a> = impl T<Item = &'a ()>;
|
pub type Alias<'a> = impl T<Item = &'a ()>;
|
||||||
|
|
||||||
struct S;
|
struct S;
|
||||||
impl<'a> T for &'a S {
|
impl<'a> T for &'a S {
|
||||||
type Item = &'a ();
|
type Item = &'a ();
|
||||||
}
|
}
|
||||||
|
|
||||||
const fn filter_positive<'a>() -> &'a Alias<'a> {
|
pub const fn filter_positive<'a>() -> &'a Alias<'a> {
|
||||||
&&S
|
&&S
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
use foo::*;
|
||||||
|
|
||||||
const fn with_positive<F: ~const for<'a> Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
|
const fn with_positive<F: ~const for<'a> Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
|
||||||
fun(filter_positive());
|
fun(filter_positive());
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/normalize-tait-in-const.rs:24:42
|
--> $DIR/normalize-tait-in-const.rs:27:42
|
||||||
|
|
|
|
||||||
LL | const fn with_positive<F: ~const for<'a> Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
|
LL | const fn with_positive<F: ~const for<'a> Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0015]: cannot call non-const closure in constant functions
|
error[E0015]: cannot call non-const closure in constant functions
|
||||||
--> $DIR/normalize-tait-in-const.rs:25:5
|
--> $DIR/normalize-tait-in-const.rs:28:5
|
||||||
|
|
|
|
||||||
LL | fun(filter_positive());
|
LL | fun(filter_positive());
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -13,15 +13,15 @@ LL | fun(filter_positive());
|
||||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
help: consider further restricting this bound
|
help: consider further restricting this bound
|
||||||
|
|
|
|
||||||
LL | const fn with_positive<F: ~const for<'a> Fn(&'a Alias<'a>) + ~const Destruct + ~const Fn(&Alias<'_>)>(fun: F) {
|
LL | const fn with_positive<F: ~const for<'a> Fn(&'a Alias<'a>) + ~const Destruct + ~const Fn(&foo::Alias<'_>)>(fun: F) {
|
||||||
| +++++++++++++++++++++++
|
| ++++++++++++++++++++++++++++
|
||||||
help: add `#![feature(effects)]` to the crate attributes to enable
|
help: add `#![feature(effects)]` to the crate attributes to enable
|
||||||
|
|
|
|
||||||
LL + #![feature(effects)]
|
LL + #![feature(effects)]
|
||||||
|
|
|
|
||||||
|
|
||||||
error[E0493]: destructor of `F` cannot be evaluated at compile-time
|
error[E0493]: destructor of `F` cannot be evaluated at compile-time
|
||||||
--> $DIR/normalize-tait-in-const.rs:24:79
|
--> $DIR/normalize-tait-in-const.rs:27:79
|
||||||
|
|
|
|
||||||
LL | const fn with_positive<F: ~const for<'a> Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
|
LL | const fn with_positive<F: ~const for<'a> Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
|
||||||
| ^^^ the destructor for this type cannot be evaluated in constant functions
|
| ^^^ the destructor for this type cannot be evaluated in constant functions
|
||||||
|
|
|
@ -2,7 +2,14 @@
|
||||||
|
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
|
|
||||||
type Foo = impl PartialEq<(Foo, i32)>;
|
mod foo {
|
||||||
|
pub type Foo = impl PartialEq<(Foo, i32)>;
|
||||||
|
|
||||||
|
fn foo() -> Foo {
|
||||||
|
super::Bar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
use foo::Foo;
|
||||||
|
|
||||||
struct Bar;
|
struct Bar;
|
||||||
|
|
||||||
|
@ -12,8 +19,4 @@ impl PartialEq<(Foo, i32)> for Bar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo() -> Foo {
|
|
||||||
Bar
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -9,6 +9,7 @@ mod a {
|
||||||
impl PartialEq<(Bar, i32)> for Bar {
|
impl PartialEq<(Bar, i32)> for Bar {
|
||||||
fn eq(&self, _other: &(Foo, i32)) -> bool {
|
fn eq(&self, _other: &(Foo, i32)) -> bool {
|
||||||
//~^ ERROR: `eq` has an incompatible type for trait
|
//~^ ERROR: `eq` has an incompatible type for trait
|
||||||
|
//~| ERROR: item does not constrain `a::Foo::{opaque#0}`
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,16 @@
|
||||||
|
error: item does not constrain `a::Foo::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:12
|
||||||
|
|
|
||||||
|
LL | fn eq(&self, _other: &(Foo, i32)) -> bool {
|
||||||
|
| ^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16
|
||||||
|
|
|
||||||
|
LL | type Foo = impl PartialEq<(Foo, i32)>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: unconstrained opaque type
|
error: unconstrained opaque type
|
||||||
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16
|
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16
|
||||||
|
|
|
|
||||||
|
@ -22,7 +35,7 @@ LL | fn eq(&self, _other: &(Foo, i32)) -> bool {
|
||||||
found signature `fn(&a::Bar, &(a::Foo, _)) -> _`
|
found signature `fn(&a::Bar, &(a::Foo, _)) -> _`
|
||||||
|
|
||||||
error: unconstrained opaque type
|
error: unconstrained opaque type
|
||||||
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:18:16
|
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:19:16
|
||||||
|
|
|
|
||||||
LL | type Foo = impl PartialEq<(Foo, i32)>;
|
LL | type Foo = impl PartialEq<(Foo, i32)>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -30,7 +43,7 @@ LL | type Foo = impl PartialEq<(Foo, i32)>;
|
||||||
= note: `Foo` must be used in combination with a concrete type within the same module
|
= note: `Foo` must be used in combination with a concrete type within the same module
|
||||||
|
|
||||||
error[E0053]: method `eq` has an incompatible type for trait
|
error[E0053]: method `eq` has an incompatible type for trait
|
||||||
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:30
|
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:25:30
|
||||||
|
|
|
|
||||||
LL | type Foo = impl PartialEq<(Foo, i32)>;
|
LL | type Foo = impl PartialEq<(Foo, i32)>;
|
||||||
| -------------------------- the expected opaque type
|
| -------------------------- the expected opaque type
|
||||||
|
@ -44,11 +57,11 @@ LL | fn eq(&self, _other: &(Bar, i32)) -> bool {
|
||||||
= note: expected signature `fn(&b::Bar, &(b::Foo, _)) -> _`
|
= note: expected signature `fn(&b::Bar, &(b::Foo, _)) -> _`
|
||||||
found signature `fn(&b::Bar, &(b::Bar, _)) -> _`
|
found signature `fn(&b::Bar, &(b::Bar, _)) -> _`
|
||||||
note: this item must have the opaque type in its signature in order to be able to register hidden types
|
note: this item must have the opaque type in its signature in order to be able to register hidden types
|
||||||
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:12
|
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:25:12
|
||||||
|
|
|
|
||||||
LL | fn eq(&self, _other: &(Bar, i32)) -> bool {
|
LL | fn eq(&self, _other: &(Bar, i32)) -> bool {
|
||||||
| ^^
|
| ^^
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0053`.
|
For more information about this error, try `rustc --explain E0053`.
|
||||||
|
|
|
@ -1,3 +1,16 @@
|
||||||
|
error: item does not constrain `A::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/two_tait_defining_each_other2.rs:11:4
|
||||||
|
|
|
||||||
|
LL | fn muh(x: A) -> B {
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/two_tait_defining_each_other2.rs:6:10
|
||||||
|
|
|
||||||
|
LL | type A = impl Foo;
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
||||||
error: unconstrained opaque type
|
error: unconstrained opaque type
|
||||||
--> $DIR/two_tait_defining_each_other2.rs:6:10
|
--> $DIR/two_tait_defining_each_other2.rs:6:10
|
||||||
|
|
|
|
||||||
|
@ -7,7 +20,7 @@ LL | type A = impl Foo;
|
||||||
= note: `A` must be used in combination with a concrete type within the same module
|
= note: `A` must be used in combination with a concrete type within the same module
|
||||||
|
|
||||||
error: opaque type's hidden type cannot be another opaque type from the same scope
|
error: opaque type's hidden type cannot be another opaque type from the same scope
|
||||||
--> $DIR/two_tait_defining_each_other2.rs:13:5
|
--> $DIR/two_tait_defining_each_other2.rs:14:5
|
||||||
|
|
|
|
||||||
LL | x // B's hidden type is A (opaquely)
|
LL | x // B's hidden type is A (opaquely)
|
||||||
| ^ one of the two opaque types used here has to be outside its defining scope
|
| ^ one of the two opaque types used here has to be outside its defining scope
|
||||||
|
@ -23,5 +36,5 @@ note: opaque type being used as hidden type
|
||||||
LL | type A = impl Foo;
|
LL | type A = impl Foo;
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,8 @@ type B = impl Foo;
|
||||||
trait Foo {}
|
trait Foo {}
|
||||||
|
|
||||||
fn muh(x: A) -> B {
|
fn muh(x: A) -> B {
|
||||||
//[next]~^ ERROR type annotations needed: cannot satisfy `_ == A`
|
//[current]~^ ERROR: item does not constrain `A::{opaque#0}`
|
||||||
|
//[next]~^^ ERROR: cannot satisfy `_ == A`
|
||||||
x // B's hidden type is A (opaquely)
|
x // B's hidden type is A (opaquely)
|
||||||
//[current]~^ ERROR opaque type's hidden type cannot be another opaque type
|
//[current]~^ ERROR opaque type's hidden type cannot be another opaque type
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
//@ build-pass (FIXME(62277): could be check-pass?)
|
//! Test that it is basically not possible to declare *and opaquely use* opaque types
|
||||||
|
//! in function bodies. This will work again once we have a `#[defines]` attribute
|
||||||
|
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
//~^ ERROR: item does not constrain
|
||||||
type Existential = impl Debug;
|
type Existential = impl Debug;
|
||||||
|
|
||||||
fn f() -> Existential {}
|
fn f() -> Existential {}
|
||||||
|
|
15
tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.stderr
Normal file
15
tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.stderr
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
error: item does not constrain `Existential::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/type-alias-impl-trait-in-fn-body.rs:8:4
|
||||||
|
|
|
||||||
|
LL | fn main() {
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/type-alias-impl-trait-in-fn-body.rs:10:24
|
||||||
|
|
|
||||||
|
LL | type Existential = impl Debug;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
|
@ -13,10 +13,13 @@ trait MyFrom<T>: Sized {
|
||||||
fn my_from(value: T) -> Result<Self, Self::Error>;
|
fn my_from(value: T) -> Result<Self, Self::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
trait F {}
|
mod f {
|
||||||
impl F for () {}
|
pub trait F {}
|
||||||
type DummyT<T> = impl F;
|
impl F for () {}
|
||||||
fn _dummy_t<T>() -> DummyT<T> {}
|
pub type DummyT<T> = impl F;
|
||||||
|
fn _dummy_t<T>() -> DummyT<T> {}
|
||||||
|
}
|
||||||
|
use f::*;
|
||||||
|
|
||||||
struct Phantom1<T>(PhantomData<T>);
|
struct Phantom1<T>(PhantomData<T>);
|
||||||
struct Phantom2<T>(PhantomData<T>);
|
struct Phantom2<T>(PhantomData<T>);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: fatal error triggered by #[rustc_error]
|
error: fatal error triggered by #[rustc_error]
|
||||||
--> $DIR/issue-75053.rs:46:1
|
--> $DIR/issue-75053.rs:49:1
|
||||||
|
|
|
|
||||||
LL | fn main() {
|
LL | fn main() {
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
|
@ -7,6 +7,7 @@ type Bar = impl Sized;
|
||||||
impl Foo {
|
impl Foo {
|
||||||
fn foo(self: Bar) {}
|
fn foo(self: Bar) {}
|
||||||
//~^ ERROR: invalid `self` parameter type: `Bar`
|
//~^ ERROR: invalid `self` parameter type: `Bar`
|
||||||
|
//~| ERROR: item does not constrain
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,3 +1,16 @@
|
||||||
|
error: item does not constrain `Bar::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/arbitrary-self-opaque.rs:8:8
|
||||||
|
|
|
||||||
|
LL | fn foo(self: Bar) {}
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/arbitrary-self-opaque.rs:4:12
|
||||||
|
|
|
||||||
|
LL | type Bar = impl Sized;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: unconstrained opaque type
|
error: unconstrained opaque type
|
||||||
--> $DIR/arbitrary-self-opaque.rs:4:12
|
--> $DIR/arbitrary-self-opaque.rs:4:12
|
||||||
|
|
|
|
||||||
|
@ -15,6 +28,6 @@ LL | fn foo(self: Bar) {}
|
||||||
= note: type of `self` must be `Self` or a type that dereferences to it
|
= note: type of `self` must be `Self` or a type that dereferences to it
|
||||||
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
|
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0307`.
|
For more information about this error, try `rustc --explain E0307`.
|
||||||
|
|
|
@ -1,13 +1,21 @@
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
use std::fmt::Debug;
|
|
||||||
|
|
||||||
type Foo = impl Debug;
|
mod foo {
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
fn foo1(mut x: Foo) {
|
pub type Foo = impl Debug;
|
||||||
x = 22_u32;
|
|
||||||
|
fn foo1(mut x: Foo) {
|
||||||
|
x = 22_u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn foo_value() -> Foo {
|
||||||
|
11_u32
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
use foo::*;
|
||||||
|
|
||||||
fn foo2(mut x: Foo) {
|
fn foo2(mut x: Foo) {
|
||||||
// no constraint on x
|
// no constraint on x
|
||||||
|
@ -17,10 +25,6 @@ fn foo3(x: Foo) {
|
||||||
println!("{:?}", x);
|
println!("{:?}", x);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo_value() -> Foo {
|
|
||||||
11_u32
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
foo3(foo_value());
|
foo3(foo_value());
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,18 +2,23 @@
|
||||||
|
|
||||||
//@ build-pass
|
//@ build-pass
|
||||||
|
|
||||||
trait T { type Item; }
|
mod helper {
|
||||||
|
pub trait T {
|
||||||
|
type Item;
|
||||||
|
}
|
||||||
|
|
||||||
type Alias<'a> = impl T<Item = &'a ()>;
|
pub type Alias<'a> = impl T<Item = &'a ()>;
|
||||||
|
|
||||||
struct S;
|
struct S;
|
||||||
impl<'a> T for &'a S {
|
impl<'a> T for &'a S {
|
||||||
type Item = &'a ();
|
type Item = &'a ();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_positive<'a>() -> Alias<'a> {
|
pub fn filter_positive<'a>() -> Alias<'a> {
|
||||||
&S
|
&S
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
use helper::*;
|
||||||
|
|
||||||
fn with_positive(fun: impl Fn(Alias<'_>)) {
|
fn with_positive(fun: impl Fn(Alias<'_>)) {
|
||||||
fun(filter_positive());
|
fun(filter_positive());
|
||||||
|
|
|
@ -3,12 +3,15 @@
|
||||||
|
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
type X<T> = impl Clone;
|
mod foo {
|
||||||
|
pub type X<T> = impl Clone;
|
||||||
|
|
||||||
fn f<T: Clone>(t: T) -> X<T> {
|
fn f<T: Clone>(t: T) -> X<T> {
|
||||||
t
|
t
|
||||||
//~^ ERROR the trait bound `T: Clone` is not satisfied
|
//~^ ERROR the trait bound `T: Clone` is not satisfied
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
use foo::X;
|
||||||
|
|
||||||
fn g<T>(o: Option<X<T>>) -> Option<X<T>> {
|
fn g<T>(o: Option<X<T>>) -> Option<X<T>> {
|
||||||
o.clone()
|
o.clone()
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
error[E0277]: the trait bound `T: Clone` is not satisfied
|
error[E0277]: the trait bound `T: Clone` is not satisfied
|
||||||
--> $DIR/bounds-are-checked-2.rs:9:5
|
--> $DIR/bounds-are-checked-2.rs:10:9
|
||||||
|
|
|
|
||||||
LL | t
|
LL | t
|
||||||
| ^ the trait `Clone` is not implemented for `T`
|
| ^ the trait `Clone` is not implemented for `T`
|
||||||
|
|
|
|
||||||
help: consider restricting type parameter `T`
|
help: consider restricting type parameter `T`
|
||||||
|
|
|
|
||||||
LL | type X<T: std::clone::Clone> = impl Clone;
|
LL | pub type X<T: std::clone::Clone> = impl Clone;
|
||||||
| +++++++++++++++++++
|
| +++++++++++++++++++
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,14 @@
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
type WithEmplacableForFn<'a> = impl EmplacableFn + 'a;
|
mod foo {
|
||||||
|
pub type WithEmplacableForFn<'a> = impl super::EmplacableFn + 'a;
|
||||||
|
|
||||||
|
fn _constrain(_: &mut ()) -> WithEmplacableForFn<'_> {
|
||||||
|
()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
use foo::*;
|
||||||
|
|
||||||
fn with_emplacable_for<'a, F, R>(mut f: F) -> R
|
fn with_emplacable_for<'a, F, R>(mut f: F) -> R
|
||||||
where
|
where
|
||||||
|
@ -16,9 +23,6 @@ where
|
||||||
_: &'a (),
|
_: &'a (),
|
||||||
_: &mut dyn FnMut(Emplacable<WithEmplacableForFn<'a>>) -> R,
|
_: &mut dyn FnMut(Emplacable<WithEmplacableForFn<'a>>) -> R,
|
||||||
) -> R {
|
) -> R {
|
||||||
fn _constrain(_: &mut ()) -> WithEmplacableForFn<'_> {
|
|
||||||
()
|
|
||||||
}
|
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,20 +4,24 @@
|
||||||
|
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
trait Anything {}
|
mod foo {
|
||||||
impl<T> Anything for T {}
|
pub trait Anything {}
|
||||||
type Input = impl Anything;
|
impl<T> Anything for T {}
|
||||||
|
pub type Input = impl Anything;
|
||||||
|
|
||||||
|
fn bop(_: Input) {
|
||||||
|
super::run(
|
||||||
|
|x: u32| {
|
||||||
|
println!("{x}");
|
||||||
|
},
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
use foo::Input;
|
||||||
|
|
||||||
fn run<F: FnOnce(Input) -> ()>(f: F, i: Input) {
|
fn run<F: FnOnce(Input) -> ()>(f: F, i: Input) {
|
||||||
f(i);
|
f(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bop(_: Input) {
|
|
||||||
run(
|
|
||||||
|x: u32| {
|
|
||||||
println!("{x}");
|
|
||||||
},
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -2,20 +2,28 @@
|
||||||
|
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
trait Foo {
|
mod foo {
|
||||||
// This was reachable in https://github.com/rust-lang/rust/issues/100800
|
pub trait Foo {
|
||||||
fn foo(&self) {
|
// This was reachable in https://github.com/rust-lang/rust/issues/100800
|
||||||
unreachable!()
|
fn foo(&self) {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T> Foo for T {}
|
||||||
|
|
||||||
|
pub struct B;
|
||||||
|
impl B {
|
||||||
|
fn foo(&self) {}
|
||||||
|
}
|
||||||
|
pub type Input = impl Foo;
|
||||||
|
fn bop() -> Input {
|
||||||
|
super::run1(|x: B| x.foo(), B);
|
||||||
|
super::run2(|x: B| x.foo(), B);
|
||||||
|
panic!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T> Foo for T {}
|
use foo::*;
|
||||||
|
|
||||||
struct B;
|
|
||||||
impl B {
|
|
||||||
fn foo(&self) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Input = impl Foo;
|
|
||||||
fn run1<F: FnOnce(Input)>(f: F, i: Input) {
|
fn run1<F: FnOnce(Input)>(f: F, i: Input) {
|
||||||
f(i)
|
f(i)
|
||||||
}
|
}
|
||||||
|
@ -23,10 +31,4 @@ fn run2<F: FnOnce(B)>(f: F, i: B) {
|
||||||
f(i)
|
f(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bop() -> Input {
|
|
||||||
run1(|x: B| x.foo(), B);
|
|
||||||
run2(|x: B| x.foo(), B);
|
|
||||||
panic!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,3 +1,36 @@
|
||||||
|
error: item does not constrain `Bar::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/const_generic_type.rs:8:10
|
||||||
|
|
|
||||||
|
LL | async fn test<const N: crate::Bar>() {
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/const_generic_type.rs:5:12
|
||||||
|
|
|
||||||
|
LL | type Bar = impl std::fmt::Display;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: item does not constrain `Bar::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/const_generic_type.rs:8:38
|
||||||
|
|
|
||||||
|
LL | async fn test<const N: crate::Bar>() {
|
||||||
|
| ______________________________________^
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
LL | | #[cfg(infer)]
|
||||||
|
LL | | let x: u32 = N;
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/const_generic_type.rs:5:12
|
||||||
|
|
|
||||||
|
LL | type Bar = impl std::fmt::Display;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: unconstrained opaque type
|
error: unconstrained opaque type
|
||||||
--> $DIR/const_generic_type.rs:5:12
|
--> $DIR/const_generic_type.rs:5:12
|
||||||
|
|
|
|
||||||
|
@ -14,5 +47,5 @@ LL | async fn test<const N: crate::Bar>() {
|
||||||
|
|
|
|
||||||
= note: the only supported types are integers, `bool` and `char`
|
= note: the only supported types are integers, `bool` and `char`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@ type Bar = impl std::fmt::Display;
|
||||||
|
|
||||||
async fn test<const N: crate::Bar>() {
|
async fn test<const N: crate::Bar>() {
|
||||||
//~^ ERROR: `Bar` is forbidden as the type of a const generic parameter
|
//~^ ERROR: `Bar` is forbidden as the type of a const generic parameter
|
||||||
|
//[no_infer]~^^ ERROR item does not constrain
|
||||||
|
//[no_infer]~| ERROR item does not constrain
|
||||||
#[cfg(infer)]
|
#[cfg(infer)]
|
||||||
let x: u32 = N;
|
let x: u32 = N;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ mod lifetime_params {
|
||||||
fn defining(s: &str) -> Ty<'_> { s }
|
fn defining(s: &str) -> Ty<'_> { s }
|
||||||
fn execute(ty: Ty<'_>) -> &str { todo!() }
|
fn execute(ty: Ty<'_>) -> &str { todo!() }
|
||||||
//~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
|
//~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
|
||||||
|
//~| ERROR item does not constrain
|
||||||
|
|
||||||
type BadFnSig = fn(Ty<'_>) -> &str;
|
type BadFnSig = fn(Ty<'_>) -> &str;
|
||||||
//~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
|
//~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
|
||||||
|
@ -17,6 +18,7 @@ mod lifetime_params_2 {
|
||||||
fn defining(s: &str) -> Ty<'_> { move || s }
|
fn defining(s: &str) -> Ty<'_> { move || s }
|
||||||
fn execute(ty: Ty<'_>) -> &str { ty() }
|
fn execute(ty: Ty<'_>) -> &str { ty() }
|
||||||
//~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
|
//~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
|
||||||
|
//~| ERROR item does not constrain
|
||||||
}
|
}
|
||||||
|
|
||||||
// regression test for https://github.com/rust-lang/rust/issues/97104
|
// regression test for https://github.com/rust-lang/rust/issues/97104
|
||||||
|
|
|
@ -7,8 +7,21 @@ LL | fn execute(ty: Ty<'_>) -> &str { todo!() }
|
||||||
= note: lifetimes appearing in an associated or opaque type are not considered constrained
|
= note: lifetimes appearing in an associated or opaque type are not considered constrained
|
||||||
= note: consider introducing a named lifetime parameter
|
= note: consider introducing a named lifetime parameter
|
||||||
|
|
||||||
|
error: item does not constrain `lifetime_params::Ty::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/constrain_inputs.rs:6:8
|
||||||
|
|
|
||||||
|
LL | fn execute(ty: Ty<'_>) -> &str { todo!() }
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/constrain_inputs.rs:4:19
|
||||||
|
|
|
||||||
|
LL | type Ty<'a> = impl Sized;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
|
error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
|
||||||
--> $DIR/constrain_inputs.rs:9:35
|
--> $DIR/constrain_inputs.rs:10:35
|
||||||
|
|
|
|
||||||
LL | type BadFnSig = fn(Ty<'_>) -> &str;
|
LL | type BadFnSig = fn(Ty<'_>) -> &str;
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
@ -17,7 +30,7 @@ LL | type BadFnSig = fn(Ty<'_>) -> &str;
|
||||||
= note: consider introducing a named lifetime parameter
|
= note: consider introducing a named lifetime parameter
|
||||||
|
|
||||||
error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types
|
error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types
|
||||||
--> $DIR/constrain_inputs.rs:11:42
|
--> $DIR/constrain_inputs.rs:12:42
|
||||||
|
|
|
|
||||||
LL | type BadTraitRef = dyn Fn(Ty<'_>) -> &str;
|
LL | type BadTraitRef = dyn Fn(Ty<'_>) -> &str;
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
@ -26,7 +39,7 @@ LL | type BadTraitRef = dyn Fn(Ty<'_>) -> &str;
|
||||||
= note: consider introducing a named lifetime parameter
|
= note: consider introducing a named lifetime parameter
|
||||||
|
|
||||||
error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
|
error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
|
||||||
--> $DIR/constrain_inputs.rs:18:31
|
--> $DIR/constrain_inputs.rs:19:31
|
||||||
|
|
|
|
||||||
LL | fn execute(ty: Ty<'_>) -> &str { ty() }
|
LL | fn execute(ty: Ty<'_>) -> &str { ty() }
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
@ -34,8 +47,21 @@ LL | fn execute(ty: Ty<'_>) -> &str { ty() }
|
||||||
= note: lifetimes appearing in an associated or opaque type are not considered constrained
|
= note: lifetimes appearing in an associated or opaque type are not considered constrained
|
||||||
= note: consider introducing a named lifetime parameter
|
= note: consider introducing a named lifetime parameter
|
||||||
|
|
||||||
|
error: item does not constrain `lifetime_params_2::Ty::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/constrain_inputs.rs:19:8
|
||||||
|
|
|
||||||
|
LL | fn execute(ty: Ty<'_>) -> &str { ty() }
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/constrain_inputs.rs:17:19
|
||||||
|
|
|
||||||
|
LL | type Ty<'a> = impl FnOnce() -> &'a str;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
|
error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
|
||||||
--> $DIR/constrain_inputs.rs:27:37
|
--> $DIR/constrain_inputs.rs:29:37
|
||||||
|
|
|
|
||||||
LL | type BadFnSig = fn(Ty<&str>) -> &str;
|
LL | type BadFnSig = fn(Ty<&str>) -> &str;
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
@ -44,7 +70,7 @@ LL | type BadFnSig = fn(Ty<&str>) -> &str;
|
||||||
= note: consider introducing a named lifetime parameter
|
= note: consider introducing a named lifetime parameter
|
||||||
|
|
||||||
error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types
|
error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types
|
||||||
--> $DIR/constrain_inputs.rs:29:44
|
--> $DIR/constrain_inputs.rs:31:44
|
||||||
|
|
|
|
||||||
LL | type BadTraitRef = dyn Fn(Ty<&str>) -> &str;
|
LL | type BadTraitRef = dyn Fn(Ty<&str>) -> &str;
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
@ -52,7 +78,7 @@ LL | type BadTraitRef = dyn Fn(Ty<&str>) -> &str;
|
||||||
= note: lifetimes appearing in an associated or opaque type are not considered constrained
|
= note: lifetimes appearing in an associated or opaque type are not considered constrained
|
||||||
= note: consider introducing a named lifetime parameter
|
= note: consider introducing a named lifetime parameter
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0581, E0582.
|
Some errors have detailed explanations: E0581, E0582.
|
||||||
For more information about an error, try `rustc --explain E0581`.
|
For more information about an error, try `rustc --explain E0581`.
|
||||||
|
|
|
@ -3,10 +3,12 @@
|
||||||
|
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
type Debuggable = impl core::fmt::Debug;
|
mod bar {
|
||||||
|
pub type Debuggable = impl core::fmt::Debug;
|
||||||
|
fn foo() -> Debuggable {
|
||||||
|
0u32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
use bar::Debuggable;
|
||||||
|
|
||||||
static mut TEST: Option<Debuggable> = None;
|
static mut TEST: Option<Debuggable> = None;
|
||||||
|
|
||||||
fn foo() -> Debuggable {
|
|
||||||
0u32
|
|
||||||
}
|
|
||||||
|
|
|
@ -23,9 +23,11 @@ impl<F: for<'a> Fn(&'a ()) -> StateWidget<'a>> Widget<()> for StatefulWidget<F>
|
||||||
type State = ();
|
type State = ();
|
||||||
|
|
||||||
fn make_state(&self) -> Self::State {}
|
fn make_state(&self) -> Self::State {}
|
||||||
|
//~^ ERROR item does not constrain
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_stateful_widget<F: for<'a> Fn(&'a ()) -> StateWidget<'a>>(build: F) -> impl Widget<()> {
|
fn new_stateful_widget<F: for<'a> Fn(&'a ()) -> StateWidget<'a>>(build: F) -> impl Widget<()> {
|
||||||
|
//~^ ERROR item does not constrain
|
||||||
StatefulWidget(build)
|
StatefulWidget(build)
|
||||||
//~^ ERROR expected generic lifetime parameter, found `'a`
|
//~^ ERROR expected generic lifetime parameter, found `'a`
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,31 @@
|
||||||
|
error: item does not constrain `StateWidget::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/failed-to-normalize-ice-99945.rs:25:8
|
||||||
|
|
|
||||||
|
LL | fn make_state(&self) -> Self::State {}
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/failed-to-normalize-ice-99945.rs:20:24
|
||||||
|
|
|
||||||
|
LL | type StateWidget<'a> = impl Widget<&'a ()>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: item does not constrain `StateWidget::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/failed-to-normalize-ice-99945.rs:29:4
|
||||||
|
|
|
||||||
|
LL | fn new_stateful_widget<F: for<'a> Fn(&'a ()) -> StateWidget<'a>>(build: F) -> impl Widget<()> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/failed-to-normalize-ice-99945.rs:20:24
|
||||||
|
|
|
||||||
|
LL | type StateWidget<'a> = impl Widget<&'a ()>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/failed-to-normalize-ice-99945.rs:34:29
|
--> $DIR/failed-to-normalize-ice-99945.rs:36:29
|
||||||
|
|
|
|
||||||
LL | type StateWidget<'a> = impl Widget<&'a ()>;
|
LL | type StateWidget<'a> = impl Widget<&'a ()>;
|
||||||
| ------------------- the expected opaque type
|
| ------------------- the expected opaque type
|
||||||
|
@ -11,7 +37,7 @@ LL | new_stateful_widget(|_| ()).make_state();
|
||||||
found unit type `()`
|
found unit type `()`
|
||||||
|
|
||||||
error[E0792]: expected generic lifetime parameter, found `'a`
|
error[E0792]: expected generic lifetime parameter, found `'a`
|
||||||
--> $DIR/failed-to-normalize-ice-99945.rs:29:5
|
--> $DIR/failed-to-normalize-ice-99945.rs:31:5
|
||||||
|
|
|
|
||||||
LL | type StateWidget<'a> = impl Widget<&'a ()>;
|
LL | type StateWidget<'a> = impl Widget<&'a ()>;
|
||||||
| -- this generic parameter must be used with a generic lifetime parameter
|
| -- this generic parameter must be used with a generic lifetime parameter
|
||||||
|
@ -19,7 +45,7 @@ LL | type StateWidget<'a> = impl Widget<&'a ()>;
|
||||||
LL | StatefulWidget(build)
|
LL | StatefulWidget(build)
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0308, E0792.
|
Some errors have detailed explanations: E0308, E0792.
|
||||||
For more information about an error, try `rustc --explain E0308`.
|
For more information about an error, try `rustc --explain E0308`.
|
||||||
|
|
|
@ -17,10 +17,12 @@ async fn operation(_: &mut ()) -> () {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn call<F>(_f: F)
|
async fn call<F>(_f: F)
|
||||||
|
//~^ ERROR item does not constrain
|
||||||
where
|
where
|
||||||
for<'any> F: FnMut(&'any mut ()) -> FutNothing<'any>,
|
for<'any> F: FnMut(&'any mut ()) -> FutNothing<'any>,
|
||||||
{
|
{
|
||||||
//~^ ERROR: expected generic lifetime parameter, found `'any`
|
//~^ ERROR: expected generic lifetime parameter, found `'any`
|
||||||
|
//~| ERROR item does not constrain
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,3 +1,32 @@
|
||||||
|
error: item does not constrain `FutNothing::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/hkl_forbidden4.rs:19:10
|
||||||
|
|
|
||||||
|
LL | async fn call<F>(_f: F)
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/hkl_forbidden4.rs:10:23
|
||||||
|
|
|
||||||
|
LL | type FutNothing<'a> = impl 'a + Future<Output = ()>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: item does not constrain `FutNothing::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/hkl_forbidden4.rs:23:1
|
||||||
|
|
|
||||||
|
LL | / {
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/hkl_forbidden4.rs:10:23
|
||||||
|
|
|
||||||
|
LL | type FutNothing<'a> = impl 'a + Future<Output = ()>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: unconstrained opaque type
|
error: unconstrained opaque type
|
||||||
--> $DIR/hkl_forbidden4.rs:10:23
|
--> $DIR/hkl_forbidden4.rs:10:23
|
||||||
|
|
|
|
||||||
|
@ -16,13 +45,14 @@ LL | call(operation).await
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0792]: expected generic lifetime parameter, found `'any`
|
error[E0792]: expected generic lifetime parameter, found `'any`
|
||||||
--> $DIR/hkl_forbidden4.rs:22:1
|
--> $DIR/hkl_forbidden4.rs:23:1
|
||||||
|
|
|
|
||||||
LL | type FutNothing<'a> = impl 'a + Future<Output = ()>;
|
LL | type FutNothing<'a> = impl 'a + Future<Output = ()>;
|
||||||
| -- this generic parameter must be used with a generic lifetime parameter
|
| -- this generic parameter must be used with a generic lifetime parameter
|
||||||
...
|
...
|
||||||
LL | / {
|
LL | / {
|
||||||
LL | |
|
LL | |
|
||||||
|
LL | |
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_^
|
| |_^
|
||||||
|
|
||||||
|
@ -38,6 +68,6 @@ note: previous use here
|
||||||
LL | call(operation).await
|
LL | call(operation).await
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0792`.
|
For more information about this error, try `rustc --explain E0792`.
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
|
||||||
trait MyIndex<T> {
|
trait MyIndex<T> {
|
||||||
type O;
|
type O;
|
||||||
fn my_index(self) -> Self::O;
|
fn my_index(self) -> Self::O;
|
||||||
|
@ -16,7 +15,6 @@ trait MyFrom<T>: Sized {
|
||||||
fn my_from(value: T) -> Result<Self, Self::Error>;
|
fn my_from(value: T) -> Result<Self, Self::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
trait F {}
|
trait F {}
|
||||||
impl F for () {}
|
impl F for () {}
|
||||||
type DummyT<T> = impl F;
|
type DummyT<T> = impl F;
|
||||||
|
@ -28,6 +26,7 @@ struct Scope<T>(Phantom2<DummyT<T>>);
|
||||||
|
|
||||||
impl<T> Scope<T> {
|
impl<T> Scope<T> {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
|
//~^ ERROR item does not constrain
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,6 +42,7 @@ impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<DummyT<T>> for Scope<U> {
|
||||||
//~^ ERROR the type parameter `T` is not constrained by the impl
|
//~^ ERROR the type parameter `T` is not constrained by the impl
|
||||||
type O = T;
|
type O = T;
|
||||||
fn my_index(self) -> Self::O {
|
fn my_index(self) -> Self::O {
|
||||||
|
//~^ ERROR item does not constrain
|
||||||
MyFrom::my_from(self.0).ok().unwrap()
|
MyFrom::my_from(self.0).ok().unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,35 @@
|
||||||
|
error: item does not constrain `DummyT::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/ice-failed-to-resolve-instance-for-110696.rs:28:8
|
||||||
|
|
|
||||||
|
LL | fn new() -> Self {
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/ice-failed-to-resolve-instance-for-110696.rs:20:18
|
||||||
|
|
|
||||||
|
LL | type DummyT<T> = impl F;
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
|
error: item does not constrain `DummyT::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/ice-failed-to-resolve-instance-for-110696.rs:44:8
|
||||||
|
|
|
||||||
|
LL | fn my_index(self) -> Self::O {
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/ice-failed-to-resolve-instance-for-110696.rs:20:18
|
||||||
|
|
|
||||||
|
LL | type DummyT<T> = impl F;
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
|
error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
|
||||||
--> $DIR/ice-failed-to-resolve-instance-for-110696.rs:42:6
|
--> $DIR/ice-failed-to-resolve-instance-for-110696.rs:41:6
|
||||||
|
|
|
|
||||||
LL | impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<DummyT<T>> for Scope<U> {
|
LL | impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<DummyT<T>> for Scope<U> {
|
||||||
| ^ unconstrained type parameter
|
| ^ unconstrained type parameter
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0207`.
|
For more information about this error, try `rustc --explain E0207`.
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
type WithLifetime<'a> = impl Equals<SelfType = ()>;
|
mod foo {
|
||||||
fn _defining_use<'a>() -> WithLifetime<'a> {}
|
use super::Equals;
|
||||||
|
pub type WithLifetime<'a> = impl Equals<SelfType = ()>;
|
||||||
|
fn _defining_use<'a>() -> WithLifetime<'a> {}
|
||||||
|
}
|
||||||
|
use foo::WithLifetime;
|
||||||
|
|
||||||
trait Convert<'a> {
|
trait Convert<'a> {
|
||||||
type Witness;
|
type Witness;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/implied_bounds.rs:17:9
|
--> $DIR/implied_bounds.rs:21:9
|
||||||
|
|
|
|
||||||
LL | impl<'a> Convert<'a> for () {
|
LL | impl<'a> Convert<'a> for () {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
|
|
|
@ -2,9 +2,17 @@
|
||||||
|
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
type Ty<'a, A> = impl Sized + 'a;
|
mod helper {
|
||||||
fn defining<'a, A>() -> Ty<'a, A> {}
|
pub type Ty<'a, A> = impl Sized + 'a;
|
||||||
fn assert_static<T: 'static>() {}
|
fn defining<'a, A>() -> Ty<'a, A> {}
|
||||||
fn test<'a, A>() where Ty<'a, A>: 'static, { assert_static::<Ty<'a, A>>() }
|
pub fn assert_static<T: 'static>() {}
|
||||||
|
}
|
||||||
|
use helper::*;
|
||||||
|
fn test<'a, A>()
|
||||||
|
where
|
||||||
|
Ty<'a, A>: 'static,
|
||||||
|
{
|
||||||
|
assert_static::<Ty<'a, A>>()
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
type WithLifetime<T> = impl Equals<SelfType = ()>;
|
mod foo {
|
||||||
fn _defining_use<T>() -> WithLifetime<T> {}
|
use super::Equals;
|
||||||
|
pub type WithLifetime<T> = impl Equals<SelfType = ()>;
|
||||||
|
fn _defining_use<T>() -> WithLifetime<T> {}
|
||||||
|
}
|
||||||
|
use foo::WithLifetime;
|
||||||
|
|
||||||
trait Convert<'a> {
|
trait Convert<'a> {
|
||||||
type Witness;
|
type Witness;
|
||||||
|
@ -12,7 +16,6 @@ impl<'a> Convert<'a> for () {
|
||||||
type Witness = WithLifetime<&'a ()>;
|
type Witness = WithLifetime<&'a ()>;
|
||||||
|
|
||||||
fn convert<'b, T: ?Sized>(_proof: &'b WithLifetime<&'a ()>, x: &'a T) -> &'b T {
|
fn convert<'b, T: ?Sized>(_proof: &'b WithLifetime<&'a ()>, x: &'a T) -> &'b T {
|
||||||
//~^ ERROR non-defining opaque type use
|
|
||||||
// compiler used to think it gets to assume 'a: 'b here because
|
// compiler used to think it gets to assume 'a: 'b here because
|
||||||
// of the `&'b WithLifetime<&'a ()>` argument
|
// of the `&'b WithLifetime<&'a ()>` argument
|
||||||
x
|
x
|
||||||
|
|
|
@ -1,17 +1,5 @@
|
||||||
error[E0792]: non-defining opaque type use in defining scope
|
|
||||||
--> $DIR/implied_bounds_from_types.rs:14:39
|
|
||||||
|
|
|
||||||
LL | fn convert<'b, T: ?Sized>(_proof: &'b WithLifetime<&'a ()>, x: &'a T) -> &'b T {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ argument `&'a ()` is not a generic parameter
|
|
||||||
|
|
|
||||||
note: for this opaque type
|
|
||||||
--> $DIR/implied_bounds_from_types.rs:3:24
|
|
||||||
|
|
|
||||||
LL | type WithLifetime<T> = impl Equals<SelfType = ()>;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/implied_bounds_from_types.rs:18:9
|
--> $DIR/implied_bounds_from_types.rs:21:9
|
||||||
|
|
|
|
||||||
LL | impl<'a> Convert<'a> for () {
|
LL | impl<'a> Convert<'a> for () {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
|
@ -24,6 +12,5 @@ LL | x
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'b`
|
= help: consider adding the following bound: `'a: 'b`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0792`.
|
|
||||||
|
|
|
@ -1,40 +1,68 @@
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
mod test_lifetime_param {
|
mod test_lifetime_param {
|
||||||
type Ty<'a> = impl Sized;
|
pub type Ty<'a> = impl Sized;
|
||||||
fn defining(a: &str) -> Ty<'_> { a }
|
fn defining(a: &str) -> Ty<'_> {
|
||||||
fn assert_static<'a: 'static>() {}
|
a
|
||||||
fn test<'a>() where Ty<'a>: 'static { assert_static::<'a>() }
|
}
|
||||||
|
pub fn assert_static<'a: 'static>() {}
|
||||||
|
}
|
||||||
|
fn test_lifetime_param_test<'a>()
|
||||||
|
where
|
||||||
|
test_lifetime_param::Ty<'a>: 'static,
|
||||||
|
{
|
||||||
|
test_lifetime_param::assert_static::<'a>()
|
||||||
//~^ ERROR: lifetime may not live long enough
|
//~^ ERROR: lifetime may not live long enough
|
||||||
}
|
}
|
||||||
|
|
||||||
mod test_higher_kinded_lifetime_param {
|
mod test_higher_kinded_lifetime_param {
|
||||||
type Ty<'a> = impl Sized;
|
pub type Ty<'a> = impl Sized + 'a;
|
||||||
fn defining(a: &str) -> Ty<'_> { a }
|
fn defining(a: &str) -> Ty<'_> {
|
||||||
fn assert_static<'a: 'static>() {}
|
a
|
||||||
fn test<'a>() where for<'b> Ty<'b>: 'a { assert_static::<'a>() }
|
}
|
||||||
|
pub fn assert_static<'a: 'static>() {}
|
||||||
|
}
|
||||||
|
fn test_higher_kinded_lifetime_param_test<'a>()
|
||||||
|
where
|
||||||
|
for<'b> test_higher_kinded_lifetime_param::Ty<'b>: 'a,
|
||||||
|
{
|
||||||
|
test_higher_kinded_lifetime_param::assert_static::<'a>()
|
||||||
//~^ ERROR: lifetime may not live long enough
|
//~^ ERROR: lifetime may not live long enough
|
||||||
}
|
}
|
||||||
|
|
||||||
mod test_higher_kinded_lifetime_param2 {
|
mod test_higher_kinded_lifetime_param2 {
|
||||||
fn assert_static<'a: 'static>() {}
|
fn assert_static<'a: 'static>() {}
|
||||||
fn test<'a>() { assert_static::<'a>() }
|
fn test<'a>() {
|
||||||
//~^ ERROR: lifetime may not live long enough
|
assert_static::<'a>()
|
||||||
|
//~^ ERROR: lifetime may not live long enough
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod test_type_param {
|
mod test_type_param {
|
||||||
type Ty<A> = impl Sized;
|
pub type Ty<A> = impl Sized;
|
||||||
fn defining<A>(s: A) -> Ty<A> { s }
|
fn defining<A>(s: A) -> Ty<A> {
|
||||||
fn assert_static<A: 'static>() {}
|
s
|
||||||
fn test<A>() where Ty<A>: 'static { assert_static::<A>() }
|
}
|
||||||
|
pub fn assert_static<A: 'static>() {}
|
||||||
|
}
|
||||||
|
fn test_type_param_test<A>()
|
||||||
|
where
|
||||||
|
test_type_param::Ty<A>: 'static,
|
||||||
|
{
|
||||||
|
test_type_param::assert_static::<A>()
|
||||||
//~^ ERROR: parameter type `A` may not live long enough
|
//~^ ERROR: parameter type `A` may not live long enough
|
||||||
}
|
}
|
||||||
|
|
||||||
mod test_implied_from_fn_sig {
|
mod test_implied_from_fn_sig {
|
||||||
type Opaque<T: 'static> = impl Sized;
|
mod foo {
|
||||||
fn defining<T: 'static>() -> Opaque<T> {}
|
pub type Opaque<T: 'static> = impl Sized;
|
||||||
|
fn defining<T: 'static>() -> Opaque<T> {}
|
||||||
|
}
|
||||||
fn assert_static<T: 'static>() {}
|
fn assert_static<T: 'static>() {}
|
||||||
fn test<T>(_: Opaque<T>) { assert_static::<T>(); }
|
|
||||||
|
fn test<T>(_: foo::Opaque<T>) {
|
||||||
|
assert_static::<T>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,36 +1,42 @@
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/implied_lifetime_wf_check3.rs:7:43
|
--> $DIR/implied_lifetime_wf_check3.rs:14:5
|
||||||
|
|
|
|
||||||
LL | fn test<'a>() where Ty<'a>: 'static { assert_static::<'a>() }
|
LL | fn test_lifetime_param_test<'a>()
|
||||||
| -- lifetime `'a` defined here ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
| -- lifetime `'a` defined here
|
||||||
|
...
|
||||||
|
LL | test_lifetime_param::assert_static::<'a>()
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/implied_lifetime_wf_check3.rs:15:46
|
--> $DIR/implied_lifetime_wf_check3.rs:29:5
|
||||||
|
|
|
|
||||||
LL | fn test<'a>() where for<'b> Ty<'b>: 'a { assert_static::<'a>() }
|
LL | fn test_higher_kinded_lifetime_param_test<'a>()
|
||||||
| -- lifetime `'a` defined here ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
| -- lifetime `'a` defined here
|
||||||
|
...
|
||||||
|
LL | test_higher_kinded_lifetime_param::assert_static::<'a>()
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/implied_lifetime_wf_check3.rs:21:21
|
--> $DIR/implied_lifetime_wf_check3.rs:36:9
|
||||||
|
|
|
|
||||||
LL | fn test<'a>() { assert_static::<'a>() }
|
LL | fn test<'a>() {
|
||||||
| -- ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
| -- lifetime `'a` defined here
|
||||||
| |
|
LL | assert_static::<'a>()
|
||||||
| lifetime `'a` defined here
|
| ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
error[E0310]: the parameter type `A` may not live long enough
|
error[E0310]: the parameter type `A` may not live long enough
|
||||||
--> $DIR/implied_lifetime_wf_check3.rs:29:41
|
--> $DIR/implied_lifetime_wf_check3.rs:52:5
|
||||||
|
|
|
|
||||||
LL | fn test<A>() where Ty<A>: 'static { assert_static::<A>() }
|
LL | test_type_param::assert_static::<A>()
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
| |
|
| |
|
||||||
| the parameter type `A` must be valid for the static lifetime...
|
| the parameter type `A` must be valid for the static lifetime...
|
||||||
| ...so that the type `A` will meet its required lifetime bounds
|
| ...so that the type `A` will meet its required lifetime bounds
|
||||||
|
|
|
|
||||||
help: consider adding an explicit lifetime bound
|
help: consider adding an explicit lifetime bound
|
||||||
|
|
|
|
||||||
LL | fn test<A: 'static>() where Ty<A>: 'static { assert_static::<A>() }
|
LL | fn test_type_param_test<A: 'static>()
|
||||||
| +++++++++
|
| +++++++++
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,20 @@
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
mod test_type_param_static {
|
mod test_type_param_static {
|
||||||
type Ty<A> = impl Sized + 'static;
|
pub type Ty<A> = impl Sized + 'static;
|
||||||
//~^ ERROR: the parameter type `A` may not live long enough
|
//~^ ERROR: the parameter type `A` may not live long enough
|
||||||
fn defining<A: 'static>(s: A) -> Ty<A> { s }
|
fn defining<A: 'static>(s: A) -> Ty<A> {
|
||||||
fn assert_static<A: 'static>() {}
|
s
|
||||||
fn test<A>() where Ty<A>: 'static { assert_static::<A>() }
|
}
|
||||||
|
pub fn assert_static<A: 'static>() {}
|
||||||
|
}
|
||||||
|
use test_type_param_static::*;
|
||||||
|
|
||||||
|
fn test<A>()
|
||||||
|
where
|
||||||
|
Ty<A>: 'static,
|
||||||
|
{
|
||||||
|
assert_static::<A>()
|
||||||
//~^ ERROR: the parameter type `A` may not live long enough
|
//~^ ERROR: the parameter type `A` may not live long enough
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,30 +1,30 @@
|
||||||
error[E0310]: the parameter type `A` may not live long enough
|
error[E0310]: the parameter type `A` may not live long enough
|
||||||
--> $DIR/implied_lifetime_wf_check4_static.rs:4:18
|
--> $DIR/implied_lifetime_wf_check4_static.rs:4:22
|
||||||
|
|
|
|
||||||
LL | type Ty<A> = impl Sized + 'static;
|
LL | pub type Ty<A> = impl Sized + 'static;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
| |
|
| |
|
||||||
| the parameter type `A` must be valid for the static lifetime...
|
| the parameter type `A` must be valid for the static lifetime...
|
||||||
| ...so that the type `A` will meet its required lifetime bounds
|
| ...so that the type `A` will meet its required lifetime bounds
|
||||||
|
|
|
|
||||||
help: consider adding an explicit lifetime bound
|
help: consider adding an explicit lifetime bound
|
||||||
|
|
|
|
||||||
LL | type Ty<A: 'static> = impl Sized + 'static;
|
LL | pub type Ty<A: 'static> = impl Sized + 'static;
|
||||||
| +++++++++
|
| +++++++++
|
||||||
|
|
||||||
error[E0310]: the parameter type `A` may not live long enough
|
error[E0310]: the parameter type `A` may not live long enough
|
||||||
--> $DIR/implied_lifetime_wf_check4_static.rs:8:41
|
--> $DIR/implied_lifetime_wf_check4_static.rs:17:5
|
||||||
|
|
|
|
||||||
LL | fn test<A>() where Ty<A>: 'static { assert_static::<A>() }
|
LL | assert_static::<A>()
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
| |
|
| |
|
||||||
| the parameter type `A` must be valid for the static lifetime...
|
| the parameter type `A` must be valid for the static lifetime...
|
||||||
| ...so that the type `A` will meet its required lifetime bounds
|
| ...so that the type `A` will meet its required lifetime bounds
|
||||||
|
|
|
|
||||||
help: consider adding an explicit lifetime bound
|
help: consider adding an explicit lifetime bound
|
||||||
|
|
|
|
||||||
LL | fn test<A: 'static>() where Ty<A>: 'static { assert_static::<A>() }
|
LL | fn test<A: 'static>()
|
||||||
| +++++++++
|
| +++++++++
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -2,17 +2,21 @@
|
||||||
|
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
|
|
||||||
trait Trait {}
|
mod foo {
|
||||||
|
pub trait Trait {}
|
||||||
|
|
||||||
type TAIT = impl Trait;
|
pub type TAIT = impl Trait;
|
||||||
|
|
||||||
struct Concrete;
|
pub struct Concrete;
|
||||||
impl Trait for Concrete {}
|
impl Trait for Concrete {}
|
||||||
|
|
||||||
fn tait() -> TAIT {
|
pub fn tait() -> TAIT {
|
||||||
Concrete
|
Concrete
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use foo::*;
|
||||||
|
|
||||||
trait OuterTrait {
|
trait OuterTrait {
|
||||||
type Item;
|
type Item;
|
||||||
}
|
}
|
||||||
|
@ -24,9 +28,7 @@ impl<T> OuterTrait for Dummy<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tait_and_impl_trait() -> impl OuterTrait<Item = (TAIT, impl Trait)> {
|
fn tait_and_impl_trait() -> impl OuterTrait<Item = (TAIT, impl Trait)> {
|
||||||
Dummy {
|
Dummy { t: (tait(), Concrete) }
|
||||||
t: (tait(), Concrete),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tait_and_dyn_trait() -> impl OuterTrait<Item = (TAIT, Box<dyn Trait>)> {
|
fn tait_and_dyn_trait() -> impl OuterTrait<Item = (TAIT, Box<dyn Trait>)> {
|
||||||
|
|
|
@ -11,6 +11,7 @@ impl std::ops::Deref for CallMe {
|
||||||
type Target = FnType;
|
type Target = FnType;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
|
//~^ ERROR: item does not constrain `ReturnType
|
||||||
fn inner(val: &u32) -> ReturnType {
|
fn inner(val: &u32) -> ReturnType {
|
||||||
async move { *val * 2 }
|
async move { *val * 2 }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,18 @@
|
||||||
|
error: item does not constrain `ReturnType::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/issue-109054.rs:13:8
|
||||||
|
|
|
||||||
|
LL | fn deref(&self) -> &Self::Target {
|
||||||
|
| ^^^^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/issue-109054.rs:7:23
|
||||||
|
|
|
||||||
|
LL | type ReturnType<'a> = impl std::future::Future<Output = u32> + 'a;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0792]: expected generic lifetime parameter, found `'_`
|
error[E0792]: expected generic lifetime parameter, found `'_`
|
||||||
--> $DIR/issue-109054.rs:18:9
|
--> $DIR/issue-109054.rs:19:9
|
||||||
|
|
|
|
||||||
LL | type ReturnType<'a> = impl std::future::Future<Output = u32> + 'a;
|
LL | type ReturnType<'a> = impl std::future::Future<Output = u32> + 'a;
|
||||||
| -- this generic parameter must be used with a generic lifetime parameter
|
| -- this generic parameter must be used with a generic lifetime parameter
|
||||||
|
@ -7,6 +20,6 @@ LL | type ReturnType<'a> = impl std::future::Future<Output = u32> + 'a;
|
||||||
LL | &inner
|
LL | &inner
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0792`.
|
For more information about this error, try `rustc --explain E0792`.
|
||||||
|
|
|
@ -1,7 +1,14 @@
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
type Bug<T, U> = impl Fn(T) -> U + Copy;
|
mod bug {
|
||||||
|
pub type Bug<T, U> = impl Fn(T) -> U + Copy;
|
||||||
|
|
||||||
|
fn make_bug<T, U: From<T>>() -> Bug<T, U> {
|
||||||
|
|x| x.into() //~ ERROR the trait bound `U: From<T>` is not satisfied
|
||||||
|
}
|
||||||
|
}
|
||||||
|
use bug::Bug;
|
||||||
|
|
||||||
union Moo {
|
union Moo {
|
||||||
x: Bug<u8, ()>,
|
x: Bug<u8, ()>,
|
||||||
|
@ -9,11 +16,6 @@ union Moo {
|
||||||
}
|
}
|
||||||
|
|
||||||
const CONST_BUG: Bug<u8, ()> = unsafe { Moo { y: () }.x };
|
const CONST_BUG: Bug<u8, ()> = unsafe { Moo { y: () }.x };
|
||||||
//~^ ERROR non-defining opaque type use
|
|
||||||
|
|
||||||
fn make_bug<T, U: From<T>>() -> Bug<T, U> {
|
|
||||||
|x| x.into() //~ ERROR the trait bound `U: From<T>` is not satisfied
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
CONST_BUG(0);
|
CONST_BUG(0);
|
||||||
|
|
|
@ -1,32 +1,19 @@
|
||||||
error[E0792]: non-defining opaque type use in defining scope
|
|
||||||
--> $DIR/issue-53092.rs:11:18
|
|
||||||
|
|
|
||||||
LL | const CONST_BUG: Bug<u8, ()> = unsafe { Moo { y: () }.x };
|
|
||||||
| ^^^^^^^^^^^ argument `u8` is not a generic parameter
|
|
||||||
|
|
|
||||||
note: for this opaque type
|
|
||||||
--> $DIR/issue-53092.rs:4:18
|
|
||||||
|
|
|
||||||
LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `U: From<T>` is not satisfied
|
error[E0277]: the trait bound `U: From<T>` is not satisfied
|
||||||
--> $DIR/issue-53092.rs:15:5
|
--> $DIR/issue-53092.rs:8:9
|
||||||
|
|
|
|
||||||
LL | |x| x.into()
|
LL | |x| x.into()
|
||||||
| ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U`
|
| ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U`
|
||||||
|
|
|
|
||||||
note: required by a bound in `make_bug`
|
note: required by a bound in `make_bug`
|
||||||
--> $DIR/issue-53092.rs:14:19
|
--> $DIR/issue-53092.rs:7:23
|
||||||
|
|
|
|
||||||
LL | fn make_bug<T, U: From<T>>() -> Bug<T, U> {
|
LL | fn make_bug<T, U: From<T>>() -> Bug<T, U> {
|
||||||
| ^^^^^^^ required by this bound in `make_bug`
|
| ^^^^^^^ required by this bound in `make_bug`
|
||||||
help: consider restricting type parameter `U`
|
help: consider restricting type parameter `U`
|
||||||
|
|
|
|
||||||
LL | type Bug<T, U: std::convert::From<T>> = impl Fn(T) -> U + Copy;
|
LL | pub type Bug<T, U: std::convert::From<T>> = impl Fn(T) -> U + Copy;
|
||||||
| +++++++++++++++++++++++
|
| +++++++++++++++++++++++
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0792.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
type Foo = impl Fn() -> usize;
|
mod foo {
|
||||||
const fn bar() -> Foo {
|
pub type Foo = impl Fn() -> usize;
|
||||||
|| 0usize
|
pub const fn bar() -> Foo {
|
||||||
|
|| 0usize
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
use foo::*;
|
||||||
const BAZR: Foo = bar();
|
const BAZR: Foo = bar();
|
||||||
|
|
||||||
#[rustc_error]
|
#[rustc_error]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: fatal error triggered by #[rustc_error]
|
error: fatal error triggered by #[rustc_error]
|
||||||
--> $DIR/issue-53096.rs:11:1
|
--> $DIR/issue-53096.rs:14:1
|
||||||
|
|
|
|
||||||
LL | fn main() {}
|
LL | fn main() {}
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
|
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
type A = impl Iterator;
|
mod helper {
|
||||||
|
pub type A = impl Iterator;
|
||||||
|
|
||||||
fn def_a() -> A {
|
pub fn def_a() -> A {
|
||||||
0..1
|
0..1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn use_a() {
|
pub fn use_a() {
|
||||||
def_a().map(|x| x);
|
helper::def_a().map(|x| x);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
#![feature(type_alias_impl_trait, rustc_attrs)]
|
#![feature(type_alias_impl_trait, rustc_attrs)]
|
||||||
|
|
||||||
type Debuggable = impl core::fmt::Debug;
|
mod bar {
|
||||||
|
pub type Debuggable = impl core::fmt::Debug;
|
||||||
|
|
||||||
|
pub fn foo() -> Debuggable {
|
||||||
|
0u32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
use bar::*;
|
||||||
|
|
||||||
static mut TEST: Option<Debuggable> = None;
|
static mut TEST: Option<Debuggable> = None;
|
||||||
|
|
||||||
|
@ -9,7 +16,3 @@ fn main() {
|
||||||
//~^ ERROR
|
//~^ ERROR
|
||||||
unsafe { TEST = Some(foo()) }
|
unsafe { TEST = Some(foo()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo() -> Debuggable {
|
|
||||||
0u32
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: fatal error triggered by #[rustc_error]
|
error: fatal error triggered by #[rustc_error]
|
||||||
--> $DIR/issue-60407.rs:8:1
|
--> $DIR/issue-60407.rs:15:1
|
||||||
|
|
|
|
||||||
LL | fn main() {
|
LL | fn main() {
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
//@ check-pass
|
|
||||||
|
|
||||||
pub trait Foo {}
|
pub trait Foo {}
|
||||||
|
|
||||||
|
@ -39,6 +38,7 @@ impl Baz for () {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bar() -> Self::Bar {
|
fn bar() -> Self::Bar {
|
||||||
|
//~^ ERROR: item does not constrain `FooImpl::{opaque#0}`
|
||||||
()
|
()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
15
tests/ui/type-alias-impl-trait/issue-63355.stderr
Normal file
15
tests/ui/type-alias-impl-trait/issue-63355.stderr
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
error: item does not constrain `FooImpl::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/issue-63355.rs:40:8
|
||||||
|
|
|
||||||
|
LL | fn bar() -> Self::Bar {
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/issue-63355.rs:29:20
|
||||||
|
|
|
||||||
|
LL | pub type FooImpl = impl Foo;
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
|
@ -1,19 +1,21 @@
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
|
|
||||||
#![feature(type_alias_impl_trait, rustc_attrs)]
|
#![feature(type_alias_impl_trait, rustc_attrs)]
|
||||||
|
mod foo {
|
||||||
|
pub type T = impl Sized;
|
||||||
|
// The concrete type referred by impl-trait-type-alias(`T`) is guaranteed
|
||||||
|
// to be the same as where it occurs, whereas `impl Trait`'s instance is location sensitive;
|
||||||
|
// so difference assertion should not be declared on impl-trait-type-alias's instances.
|
||||||
|
// for details, check RFC-2515:
|
||||||
|
// https://github.com/rust-lang/rfcs/blob/master/text/2515-type_alias_impl_trait.md
|
||||||
|
|
||||||
type T = impl Sized;
|
fn bop(_: T) {
|
||||||
// The concrete type referred by impl-trait-type-alias(`T`) is guaranteed
|
super::take(|| {});
|
||||||
// to be the same as where it occurs, whereas `impl Trait`'s instance is location sensitive;
|
super::take(|| {});
|
||||||
// so difference assertion should not be declared on impl-trait-type-alias's instances.
|
}
|
||||||
// for details, check RFC-2515:
|
}
|
||||||
// https://github.com/rust-lang/rfcs/blob/master/text/2515-type_alias_impl_trait.md
|
use foo::*;
|
||||||
|
|
||||||
fn take(_: fn() -> T) {}
|
fn take(_: fn() -> T) {}
|
||||||
|
|
||||||
fn bop(_: T) {
|
|
||||||
take(|| {});
|
|
||||||
take(|| {});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -15,10 +15,13 @@ trait MyFrom<T>: Sized {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MCVE starts here */
|
/* MCVE starts here */
|
||||||
trait F {}
|
mod f {
|
||||||
impl F for () {}
|
pub trait F {}
|
||||||
type DummyT<T> = impl F;
|
impl F for () {}
|
||||||
fn _dummy_t<T>() -> DummyT<T> {}
|
pub type DummyT<T> = impl F;
|
||||||
|
fn _dummy_t<T>() -> DummyT<T> {}
|
||||||
|
}
|
||||||
|
use f::DummyT;
|
||||||
|
|
||||||
struct Phantom1<T>(PhantomData<T>);
|
struct Phantom1<T>(PhantomData<T>);
|
||||||
struct Phantom2<T>(PhantomData<T>);
|
struct Phantom2<T>(PhantomData<T>);
|
||||||
|
|
|
@ -3,18 +3,24 @@
|
||||||
|
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
trait T { type Item; }
|
mod foo {
|
||||||
|
pub trait T {
|
||||||
|
type Item;
|
||||||
|
}
|
||||||
|
|
||||||
type Alias<'a> = impl T<Item = &'a ()>;
|
pub type Alias<'a> = impl T<Item = &'a ()>;
|
||||||
|
|
||||||
struct S;
|
struct S;
|
||||||
impl<'a> T for &'a S {
|
impl<'a> T for &'a S {
|
||||||
type Item = &'a ();
|
type Item = &'a ();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn filter_positive<'a>() -> Alias<'a> {
|
||||||
|
&S
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_positive<'a>() -> Alias<'a> {
|
use foo::*;
|
||||||
&S
|
|
||||||
}
|
|
||||||
|
|
||||||
fn with_positive(fun: impl Fn(Alias<'_>)) {
|
fn with_positive(fun: impl Fn(Alias<'_>)) {
|
||||||
fun(filter_positive());
|
fun(filter_positive());
|
||||||
|
|
|
@ -7,11 +7,18 @@
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
mod g {
|
||||||
|
pub trait Dummy {}
|
||||||
|
impl Dummy for () {}
|
||||||
|
pub type F = impl Dummy;
|
||||||
|
pub fn f() -> F {}
|
||||||
|
}
|
||||||
|
use g::*;
|
||||||
|
|
||||||
trait Test {
|
trait Test {
|
||||||
fn test(self);
|
fn test(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Test for define::F {
|
impl Test for define::F {
|
||||||
fn test(self) {}
|
fn test(self) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,18 @@
|
||||||
|
error: item does not constrain `Bar::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/issue-84660-unsoundness.rs:22:8
|
||||||
|
|
|
||||||
|
LL | fn convert(_i: In) -> Self::Out {
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/issue-84660-unsoundness.rs:12:12
|
||||||
|
|
|
||||||
|
LL | type Bar = impl Foo;
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
||||||
error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
|
error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
|
||||||
--> $DIR/issue-84660-unsoundness.rs:28:1
|
--> $DIR/issue-84660-unsoundness.rs:29:1
|
||||||
|
|
|
|
||||||
LL | impl<In, Out> Trait<Bar, In> for Out {
|
LL | impl<In, Out> Trait<Bar, In> for Out {
|
||||||
| ------------------------------------ first implementation here
|
| ------------------------------------ first implementation here
|
||||||
|
@ -7,6 +20,6 @@ LL | impl<In, Out> Trait<Bar, In> for Out {
|
||||||
LL | impl<In, Out> Trait<(), In> for Out {
|
LL | impl<In, Out> Trait<(), In> for Out {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0119`.
|
For more information about this error, try `rustc --explain E0119`.
|
||||||
|
|
|
@ -4,12 +4,13 @@ error[E0284]: type annotations needed: cannot satisfy `<Out as Trait<Bar, In>>::
|
||||||
LL | fn convert(_i: In) -> Self::Out {
|
LL | fn convert(_i: In) -> Self::Out {
|
||||||
| _____________________________________^
|
| _____________________________________^
|
||||||
LL | |
|
LL | |
|
||||||
|
LL | |
|
||||||
LL | | unreachable!();
|
LL | | unreachable!();
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_____^ cannot satisfy `<Out as Trait<Bar, In>>::Out == ()`
|
| |_____^ cannot satisfy `<Out as Trait<Bar, In>>::Out == ()`
|
||||||
|
|
||||||
error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
|
error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
|
||||||
--> $DIR/issue-84660-unsoundness.rs:28:1
|
--> $DIR/issue-84660-unsoundness.rs:29:1
|
||||||
|
|
|
|
||||||
LL | impl<In, Out> Trait<Bar, In> for Out {
|
LL | impl<In, Out> Trait<Bar, In> for Out {
|
||||||
| ------------------------------------ first implementation here
|
| ------------------------------------ first implementation here
|
||||||
|
|
|
@ -21,6 +21,7 @@ impl<In, Out> Trait<Bar, In> for Out {
|
||||||
type Out = Out;
|
type Out = Out;
|
||||||
fn convert(_i: In) -> Self::Out {
|
fn convert(_i: In) -> Self::Out {
|
||||||
//[next]~^ ERROR: cannot satisfy `<Out as Trait<Bar, In>>::Out == ()`
|
//[next]~^ ERROR: cannot satisfy `<Out as Trait<Bar, In>>::Out == ()`
|
||||||
|
//[current]~^^ ERROR: item does not constrain `Bar::{opaque#0}`, but has it in its signature
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,13 @@ use std::fmt::Debug;
|
||||||
type FooX = impl Debug;
|
type FooX = impl Debug;
|
||||||
//~^ ERROR unconstrained opaque type
|
//~^ ERROR unconstrained opaque type
|
||||||
|
|
||||||
trait Foo<A> { }
|
trait Foo<A> {}
|
||||||
|
|
||||||
impl Foo<FooX> for () { }
|
impl Foo<FooX> for () {}
|
||||||
|
|
||||||
fn foo() -> impl Foo<FooX> {
|
fn foo() -> impl Foo<FooX> {
|
||||||
|
//~^ ERROR: item does not constrain
|
||||||
()
|
()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() { }
|
fn main() {}
|
||||||
|
|
|
@ -1,3 +1,16 @@
|
||||||
|
error: item does not constrain `FooX::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/nested-tait-inference3.rs:13:4
|
||||||
|
|
|
||||||
|
LL | fn foo() -> impl Foo<FooX> {
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/nested-tait-inference3.rs:6:13
|
||||||
|
|
|
||||||
|
LL | type FooX = impl Debug;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: unconstrained opaque type
|
error: unconstrained opaque type
|
||||||
--> $DIR/nested-tait-inference3.rs:6:13
|
--> $DIR/nested-tait-inference3.rs:6:13
|
||||||
|
|
|
|
||||||
|
@ -6,5 +19,5 @@ LL | type FooX = impl Debug;
|
||||||
|
|
|
|
||||||
= note: `FooX` must be used in combination with a concrete type within the same module
|
= note: `FooX` must be used in combination with a concrete type within the same module
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ trait Trait<T> {}
|
||||||
impl<T, U> Trait<T> for U {}
|
impl<T, U> Trait<T> for U {}
|
||||||
|
|
||||||
fn bar() -> Bar {
|
fn bar() -> Bar {
|
||||||
|
//~^ ERROR: item does not constrain
|
||||||
42
|
42
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,18 @@
|
||||||
|
error: item does not constrain `Foo::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/nested.rs:10:4
|
||||||
|
|
|
||||||
|
LL | fn bar() -> Bar {
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/nested.rs:3:12
|
||||||
|
|
|
||||||
|
LL | type Foo = impl std::fmt::Debug;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0277]: `Bar` doesn't implement `Debug`
|
error[E0277]: `Bar` doesn't implement `Debug`
|
||||||
--> $DIR/nested.rs:15:22
|
--> $DIR/nested.rs:16:22
|
||||||
|
|
|
|
||||||
LL | println!("{:?}", bar());
|
LL | println!("{:?}", bar());
|
||||||
| ^^^^^ `Bar` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
| ^^^^^ `Bar` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
||||||
|
@ -7,6 +20,6 @@ LL | println!("{:?}", bar());
|
||||||
= help: the trait `Debug` is not implemented for `Bar`
|
= help: the trait `Debug` is not implemented for `Bar`
|
||||||
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -11,6 +11,7 @@ mod my_mod {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_foot(_: Foo) -> Foot {
|
pub fn get_foot(_: Foo) -> Foot {
|
||||||
|
//~^ ERROR: item does not constrain `Foo::{opaque#0}`, but has it in its signature
|
||||||
get_foo() //~ ERROR opaque type's hidden type cannot be another opaque type
|
get_foo() //~ ERROR opaque type's hidden type cannot be another opaque type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,18 @@
|
||||||
|
error: item does not constrain `Foo::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/nested_type_alias_impl_trait.rs:13:12
|
||||||
|
|
|
||||||
|
LL | pub fn get_foot(_: Foo) -> Foot {
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/nested_type_alias_impl_trait.rs:6:20
|
||||||
|
|
|
||||||
|
LL | pub type Foo = impl Debug;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: opaque type's hidden type cannot be another opaque type from the same scope
|
error: opaque type's hidden type cannot be another opaque type from the same scope
|
||||||
--> $DIR/nested_type_alias_impl_trait.rs:14:9
|
--> $DIR/nested_type_alias_impl_trait.rs:15:9
|
||||||
|
|
|
|
||||||
LL | get_foo()
|
LL | get_foo()
|
||||||
| ^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope
|
| ^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope
|
||||||
|
@ -15,5 +28,5 @@ note: opaque type being used as hidden type
|
||||||
LL | pub type Foo = impl Debug;
|
LL | pub type Foo = impl Debug;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ mod foo {
|
||||||
|
|
||||||
// make compiler happy about using 'Foo'
|
// make compiler happy about using 'Foo'
|
||||||
pub fn bar(x: Foo) -> Foo {
|
pub fn bar(x: Foo) -> Foo {
|
||||||
|
//~^ ERROR: item does not constrain `Foo::{opaque#0}`
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,16 @@
|
||||||
|
error: item does not constrain `Foo::{opaque#0}`, but has it in its signature
|
||||||
|
--> $DIR/no_inferrable_concrete_type.rs:11:12
|
||||||
|
|
|
||||||
|
LL | pub fn bar(x: Foo) -> Foo {
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||||
|
note: this opaque type is in the signature
|
||||||
|
--> $DIR/no_inferrable_concrete_type.rs:7:20
|
||||||
|
|
|
||||||
|
LL | pub type Foo = impl Copy;
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error: unconstrained opaque type
|
error: unconstrained opaque type
|
||||||
--> $DIR/no_inferrable_concrete_type.rs:7:20
|
--> $DIR/no_inferrable_concrete_type.rs:7:20
|
||||||
|
|
|
|
||||||
|
@ -6,5 +19,5 @@ LL | pub type Foo = impl Copy;
|
||||||
|
|
|
|
||||||
= note: `Foo` must be used in combination with a concrete type within the same module
|
= note: `Foo` must be used in combination with a concrete type within the same module
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -8,25 +8,32 @@ pub trait Tr {
|
||||||
|
|
||||||
impl Tr for (u32,) {
|
impl Tr for (u32,) {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get(&self) -> u32 { self.0 }
|
fn get(&self) -> u32 {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tr1() -> impl Tr {
|
pub fn tr1() -> impl Tr {
|
||||||
(32,)
|
(32,)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tr2() -> impl Tr {
|
struct Inner {
|
||||||
struct Inner {
|
x: helper::X,
|
||||||
x: X,
|
}
|
||||||
}
|
impl Tr for Inner {
|
||||||
type X = impl Tr;
|
fn get(&self) -> u32 {
|
||||||
impl Tr for Inner {
|
self.x.get()
|
||||||
fn get(&self) -> u32 {
|
}
|
||||||
self.x.get()
|
}
|
||||||
}
|
|
||||||
}
|
mod helper {
|
||||||
|
pub use super::*;
|
||||||
Inner {
|
pub type X = impl Tr;
|
||||||
x: tr1(),
|
|
||||||
|
pub fn tr2() -> impl Tr
|
||||||
|
where
|
||||||
|
X:,
|
||||||
|
{
|
||||||
|
Inner { x: tr1() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,11 @@
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
type Ty<'a> = impl Sized + 'a;
|
mod tait {
|
||||||
fn define<'a>() -> Ty<'a> {}
|
pub type Ty<'a> = impl Sized + 'a;
|
||||||
|
fn define<'a>() -> Ty<'a> {}
|
||||||
|
}
|
||||||
|
use tait::Ty;
|
||||||
|
|
||||||
// Ty<'^0>: 'static
|
// Ty<'^0>: 'static
|
||||||
fn test1(_: &'static fn(Ty<'_>)) {}
|
fn test1(_: &'static fn(Ty<'_>)) {}
|
||||||
|
@ -15,4 +18,4 @@ fn test2() {
|
||||||
None::<&fn(Ty<'_>)>;
|
None::<&fn(Ty<'_>)>;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() { }
|
fn main() {}
|
||||||
|
|
|
@ -9,26 +9,29 @@ struct A;
|
||||||
impl Test for A {}
|
impl Test for A {}
|
||||||
|
|
||||||
struct B<T> {
|
struct B<T> {
|
||||||
inner: T,
|
inner: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Test> Test for B<T> {}
|
impl<T: Test> Test for B<T> {}
|
||||||
|
|
||||||
type TestImpl = impl Test;
|
mod helper {
|
||||||
|
use super::*;
|
||||||
|
pub type TestImpl = impl Test;
|
||||||
|
|
||||||
fn test() -> TestImpl {
|
pub fn test() -> TestImpl {
|
||||||
A
|
A
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_option2() -> Option<TestImpl> {
|
||||||
|
let inner = make_option().unwrap();
|
||||||
|
|
||||||
|
Some(B { inner })
|
||||||
|
//~^ ERROR concrete type differs from previous defining opaque type use
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_option() -> Option<TestImpl> {
|
fn make_option() -> Option<helper::TestImpl> {
|
||||||
Some(test())
|
Some(helper::test())
|
||||||
}
|
|
||||||
|
|
||||||
fn make_option2() -> Option<TestImpl> {
|
|
||||||
let inner = make_option().unwrap();
|
|
||||||
|
|
||||||
Some(B { inner })
|
|
||||||
//~^ ERROR concrete type differs from previous defining opaque type use
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
error: concrete type differs from previous defining opaque type use
|
error: concrete type differs from previous defining opaque type use
|
||||||
--> $DIR/recursive-tait-conflicting-defn.rs:30:3
|
--> $DIR/recursive-tait-conflicting-defn.rs:28:9
|
||||||
|
|
|
|
||||||
LL | Some(B { inner })
|
LL | Some(B { inner })
|
||||||
| ^^^^^^^^^^^^^^^^^ expected `A`, got `B<TestImpl>`
|
| ^^^^^^^^^^^^^^^^^ expected `A`, got `B<TestImpl>`
|
||||||
|
|
|
|
||||||
note: previous use here
|
note: previous use here
|
||||||
--> $DIR/recursive-tait-conflicting-defn.rs:20:3
|
--> $DIR/recursive-tait-conflicting-defn.rs:22:9
|
||||||
|
|
|
|
||||||
LL | A
|
LL | A
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue