mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-23 13:13:17 +00:00
Require any function with a tait in its signature to actually constrain a hidden type
This commit is contained in:
parent
39e7bf6826
commit
0bc2001879
@ -2,20 +2,23 @@
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
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;
|
||||
impl<'a> T for &'a S {
|
||||
type Item = &'a ();
|
||||
}
|
||||
struct S;
|
||||
impl<'a> T for &'a S {
|
||||
type Item = &'a ();
|
||||
}
|
||||
|
||||
fn filter_positive<'a>() -> Alias<'a> {
|
||||
&S
|
||||
pub fn filter_positive<'a>() -> Alias<'a> {
|
||||
&S
|
||||
}
|
||||
}
|
||||
use helper::*;
|
||||
|
||||
fn with_positive(fun: impl Fn(Alias<'_>)) {
|
||||
fun(filter_positive());
|
||||
|
@ -146,8 +146,6 @@ pub enum ProcessResult<O, E> {
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||
struct ObligationTreeId(usize);
|
||||
|
||||
type ObligationTreeIdGenerator = impl Iterator<Item = ObligationTreeId>;
|
||||
|
||||
pub struct ObligationForest<O: ForestObligation> {
|
||||
/// The list of obligations. In between calls to [Self::process_obligations],
|
||||
/// this list only contains nodes in the `Pending` or `Waiting` state.
|
||||
@ -310,18 +308,25 @@ pub struct Error<O, E> {
|
||||
pub backtrace: Vec<O>,
|
||||
}
|
||||
|
||||
impl<O: ForestObligation> ObligationForest<O> {
|
||||
pub fn new() -> ObligationForest<O> {
|
||||
ObligationForest {
|
||||
nodes: vec![],
|
||||
done_cache: Default::default(),
|
||||
active_cache: Default::default(),
|
||||
reused_node_vec: vec![],
|
||||
obligation_tree_id_generator: (0..).map(ObligationTreeId),
|
||||
error_cache: Default::default(),
|
||||
mod helper {
|
||||
use super::*;
|
||||
pub type ObligationTreeIdGenerator = impl Iterator<Item = ObligationTreeId>;
|
||||
impl<O: ForestObligation> ObligationForest<O> {
|
||||
pub fn new() -> ObligationForest<O> {
|
||||
ObligationForest {
|
||||
nodes: vec![],
|
||||
done_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
|
||||
/// yet been fully resolved.
|
||||
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
|
||||
.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_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_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> {
|
||||
let mut res = Ok(());
|
||||
@ -229,13 +229,14 @@ impl TaitConstraintLocator<'_> {
|
||||
return;
|
||||
}
|
||||
|
||||
let opaque_types_defined_by = self.tcx.opaque_types_defined_by(item_def_id);
|
||||
|
||||
let mut constrained = false;
|
||||
for (&opaque_type_key, &hidden_type) in &tables.concrete_opaque_types {
|
||||
if opaque_type_key.def_id != self.def_id {
|
||||
continue;
|
||||
}
|
||||
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) {
|
||||
self.tcx.dcx().emit_err(TaitForwardCompat {
|
||||
@ -259,6 +260,16 @@ impl TaitConstraintLocator<'_> {
|
||||
|
||||
if !constrained {
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -390,6 +390,17 @@ pub struct TaitForwardCompat {
|
||||
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 span: Span,
|
||||
pub def_span: Span,
|
||||
|
@ -377,9 +377,6 @@ pub struct Terminator<'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> {
|
||||
#[inline]
|
||||
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> {
|
||||
TerminatorKind::SwitchInt { discr: cond, targets: SwitchTargets::static_if(0, f, t) }
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn successors(&self) -> Successors<'_> {
|
||||
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))
|
||||
pub use helper::*;
|
||||
|
||||
mod helper {
|
||||
use super::*;
|
||||
pub type Successors<'a> = impl DoubleEndedIterator<Item = BasicBlock> + 'a;
|
||||
pub type SuccessorsMut<'a> = impl DoubleEndedIterator<Item = &'a mut BasicBlock> + 'a;
|
||||
impl<'tcx> TerminatorKind<'tcx> {
|
||||
#[inline]
|
||||
pub fn successors(&self) -> Successors<'_> {
|
||||
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: _, .. }
|
||||
| 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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn successors_mut(&mut self) -> SuccessorsMut<'_> {
|
||||
use self::TerminatorKind::*;
|
||||
match *self {
|
||||
Call { target: Some(ref mut t), unwind: UnwindAction::Cleanup(ref mut u), .. }
|
||||
| Yield { resume: ref mut t, drop: Some(ref mut u), .. }
|
||||
| Drop { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. }
|
||||
| Assert { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. }
|
||||
| FalseUnwind { real_target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u) } => {
|
||||
slice::from_mut(t).into_iter().chain(Some(u))
|
||||
}
|
||||
Goto { target: ref mut t }
|
||||
| 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))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn successors_mut(&mut self) -> SuccessorsMut<'_> {
|
||||
use self::TerminatorKind::*;
|
||||
match *self {
|
||||
Call {
|
||||
target: Some(ref mut t), unwind: UnwindAction::Cleanup(ref mut u), ..
|
||||
}
|
||||
| Yield { resume: ref mut t, drop: Some(ref mut u), .. }
|
||||
| Drop { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. }
|
||||
| Assert { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. }
|
||||
| FalseUnwind {
|
||||
real_target: ref mut t,
|
||||
unwind: UnwindAction::Cleanup(ref mut u),
|
||||
} => slice::from_mut(t).into_iter().chain(Some(u)),
|
||||
Goto { target: ref mut t }
|
||||
| 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]
|
||||
pub fn unwind(&self) -> Option<&UnwindAction> {
|
||||
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 {
|
||||
move || {
|
||||
// Use the global backtrace lock to synchronize this as it's a
|
||||
// requirement of the `backtrace` crate, and then actually resolve
|
||||
// everything.
|
||||
let _lock = lock();
|
||||
for frame in capture.frames.iter_mut() {
|
||||
let symbols = &mut frame.symbols;
|
||||
let frame = match &frame.frame {
|
||||
RawFrame::Actual(frame) => frame,
|
||||
#[cfg(test)]
|
||||
RawFrame::Fake => unimplemented!(),
|
||||
};
|
||||
unsafe {
|
||||
backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| {
|
||||
symbols.push(BacktraceSymbol {
|
||||
name: symbol.name().map(|m| m.as_bytes().to_vec()),
|
||||
filename: symbol.filename_raw().map(|b| match b {
|
||||
BytesOrWideString::Bytes(b) => BytesOrWide::Bytes(b.to_owned()),
|
||||
BytesOrWideString::Wide(b) => BytesOrWide::Wide(b.to_owned()),
|
||||
}),
|
||||
lineno: symbol.lineno(),
|
||||
colno: symbol.colno(),
|
||||
pub(super) fn lazy_resolve(mut capture: Capture) -> LazyResolve {
|
||||
move || {
|
||||
// Use the global backtrace lock to synchronize this as it's a
|
||||
// requirement of the `backtrace` crate, and then actually resolve
|
||||
// everything.
|
||||
let _lock = lock();
|
||||
for frame in capture.frames.iter_mut() {
|
||||
let symbols = &mut frame.symbols;
|
||||
let frame = match &frame.frame {
|
||||
RawFrame::Actual(frame) => frame,
|
||||
#[cfg(test)]
|
||||
RawFrame::Fake => unimplemented!(),
|
||||
};
|
||||
unsafe {
|
||||
backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| {
|
||||
symbols.push(BacktraceSymbol {
|
||||
name: symbol.name().map(|m| m.as_bytes().to_vec()),
|
||||
filename: symbol.filename_raw().map(|b| match b {
|
||||
BytesOrWideString::Bytes(b) => BytesOrWide::Bytes(b.to_owned()),
|
||||
BytesOrWideString::Wide(b) => BytesOrWide::Wide(b.to_owned()),
|
||||
}),
|
||||
lineno: symbol.lineno(),
|
||||
colno: symbol.colno(),
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
capture
|
||||
capture
|
||||
}
|
||||
}
|
||||
}
|
||||
use helper::*;
|
||||
|
||||
impl RawFrame {
|
||||
fn ip(&self) -> *mut c_void {
|
||||
|
@ -9,15 +9,18 @@
|
||||
|
||||
extern crate core;
|
||||
|
||||
pub type Type1 = impl Send;
|
||||
mod defining_module {
|
||||
pub type Type1 = impl Send;
|
||||
|
||||
pub fn foo()
|
||||
where
|
||||
Type1: 'static,
|
||||
{
|
||||
pub struct Foo<T, const N: usize>([T; N]);
|
||||
let _: Type1 = Foo([0; 32]);
|
||||
pub fn foo()
|
||||
where
|
||||
Type1: 'static,
|
||||
{
|
||||
pub struct Foo<T, const N: usize>([T; N]);
|
||||
let _: Type1 = Foo([0; 32]);
|
||||
}
|
||||
}
|
||||
use defining_module::*;
|
||||
|
||||
pub fn foo1(_: Type1) {}
|
||||
// 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) {}
|
||||
// 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: ![[TYPE2]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo3FooIu3i32Lu5usize32EES2_E"}
|
||||
// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo3FooIu3i32Lu5usize32EES2_S2_E"}
|
||||
// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo3FooIu3i32Lu5usize32EEE"}
|
||||
// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo3FooIu3i32Lu5usize32EES2_E"}
|
||||
// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo3FooIu3i32Lu5usize32EES2_S2_E"}
|
||||
|
@ -9,17 +9,22 @@
|
||||
|
||||
extern crate core;
|
||||
|
||||
pub type Type1 = impl Send;
|
||||
mod defining_module {
|
||||
|
||||
pub fn foo<'a>()
|
||||
where
|
||||
Type1: 'static,
|
||||
{
|
||||
pub struct Foo<'a>(&'a i32);
|
||||
pub struct Bar<'a, 'b>(&'a i32, &'b Foo<'b>);
|
||||
let _: Type1 = Bar;
|
||||
pub type Type1 = impl Send;
|
||||
|
||||
pub fn foo<'a>()
|
||||
where
|
||||
Type1: 'static,
|
||||
{
|
||||
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) {}
|
||||
// CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||
pub fn foo2(_: Type1, _: Type1) {}
|
||||
|
@ -9,45 +9,47 @@
|
||||
|
||||
extern crate core;
|
||||
|
||||
pub type Type1 = impl Send;
|
||||
pub type Type2 = impl Send;
|
||||
pub type Type3 = impl Send;
|
||||
pub type Type4 = impl Send;
|
||||
mod defining_module {
|
||||
pub type Type1 = impl Send;
|
||||
pub type Type2 = impl Send;
|
||||
pub type Type3 = impl Send;
|
||||
pub type Type4 = impl Send;
|
||||
|
||||
pub fn foo()
|
||||
where
|
||||
Type1: 'static,
|
||||
Type2: 'static,
|
||||
Type3: 'static,
|
||||
Type4: 'static,
|
||||
{
|
||||
// Type in extern path
|
||||
extern "C" {
|
||||
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
|
||||
pub fn foo()
|
||||
where
|
||||
Type1: 'static,
|
||||
Type2: 'static,
|
||||
Type4: 'static,
|
||||
{
|
||||
// Type in extern path
|
||||
extern "C" {
|
||||
fn bar();
|
||||
}
|
||||
};
|
||||
let _: Type1 = bar;
|
||||
|
||||
// Type in impl path
|
||||
struct Foo;
|
||||
impl Foo {
|
||||
fn bar(&self) {}
|
||||
// Type in closure path
|
||||
|| {
|
||||
pub struct Foo;
|
||||
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
|
||||
|
||||
@ -76,15 +78,15 @@ pub fn foo11(_: &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: ![[TYPE1]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo10{{[{}][{}]}}extern{{[}][}]}}3barEE"}
|
||||
// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo10{{[{}][{}]}}extern{{[}][}]}}3barES0_E"}
|
||||
// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo10{{[{}][{}]}}extern{{[}][}]}}3barES0_S0_E"}
|
||||
// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo11{{[{}][{}]}}closure{{[}][}]}}3FooEE"}
|
||||
// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_E"}
|
||||
// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_S0_E"}
|
||||
// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo12{{[{}][{}]}}constant{{[}][}]}}3FooEE"}
|
||||
// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_E"}
|
||||
// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_S0_E"}
|
||||
// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo8{{[{}][{}]}}impl{{[}][}]}}3barEE"}
|
||||
// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_E"}
|
||||
// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_S0_E"}
|
||||
// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo10{{[{}][{}]}}extern{{[}][}]}}3barEE"}
|
||||
// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo10{{[{}][{}]}}extern{{[}][}]}}3barES0_E"}
|
||||
// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo10{{[{}][{}]}}extern{{[}][}]}}3barES0_S0_E"}
|
||||
// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo11{{[{}][{}]}}closure{{[}][}]}}3FooEE"}
|
||||
// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_E"}
|
||||
// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_S0_E"}
|
||||
// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo12{{[{}][{}]}}constant{{[}][}]}}3FooEE"}
|
||||
// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_E"}
|
||||
// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_S0_E"}
|
||||
// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo8{{[{}][{}]}}impl{{[}][}]}}3barEE"}
|
||||
// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_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>() {}
|
||||
//~^ ERROR: `Foo` is forbidden as the type of a const generic parameter
|
||||
//~| ERROR: item does not constrain
|
||||
|
||||
fn main() {
|
||||
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
|
||||
--> $DIR/opaque_types.rs:11:11
|
||||
--> $DIR/opaque_types.rs:12:11
|
||||
|
|
||||
LL | type Foo = impl Sized;
|
||||
| ---------- the expected opaque type
|
||||
@ -22,27 +35,27 @@ note: ...which requires computing type of opaque `Foo::{opaque#0}`...
|
||||
LL | type Foo = impl Sized;
|
||||
| ^^^^^^^^^^
|
||||
note: ...which requires type-checking `main`...
|
||||
--> $DIR/opaque_types.rs:10:1
|
||||
--> $DIR/opaque_types.rs:11:1
|
||||
|
|
||||
LL | fn main() {
|
||||
| ^^^^^^^^^
|
||||
note: ...which requires evaluating type-level constant...
|
||||
--> $DIR/opaque_types.rs:11:11
|
||||
--> $DIR/opaque_types.rs:12:11
|
||||
|
|
||||
LL | foo::<42>();
|
||||
| ^^
|
||||
note: ...which requires const-evaluating + checking `main::{constant#0}`...
|
||||
--> $DIR/opaque_types.rs:11:11
|
||||
--> $DIR/opaque_types.rs:12:11
|
||||
|
|
||||
LL | foo::<42>();
|
||||
| ^^
|
||||
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>();
|
||||
| ^^
|
||||
note: ...which requires elaborating drops for `main::{constant#0}`...
|
||||
--> $DIR/opaque_types.rs:11:11
|
||||
--> $DIR/opaque_types.rs:12:11
|
||||
|
|
||||
LL | foo::<42>();
|
||||
| ^^
|
||||
@ -70,42 +83,42 @@ LL | type Foo = impl Sized;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
note: ...which requires type-checking `main`...
|
||||
--> $DIR/opaque_types.rs:10:1
|
||||
--> $DIR/opaque_types.rs:11:1
|
||||
|
|
||||
LL | fn main() {
|
||||
| ^^^^^^^^^
|
||||
note: ...which requires evaluating type-level constant...
|
||||
--> $DIR/opaque_types.rs:11:11
|
||||
--> $DIR/opaque_types.rs:12:11
|
||||
|
|
||||
LL | foo::<42>();
|
||||
| ^^
|
||||
note: ...which requires const-evaluating + checking `main::{constant#0}`...
|
||||
--> $DIR/opaque_types.rs:11:11
|
||||
--> $DIR/opaque_types.rs:12:11
|
||||
|
|
||||
LL | foo::<42>();
|
||||
| ^^
|
||||
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>();
|
||||
| ^^
|
||||
note: ...which requires elaborating drops for `main::{constant#0}`...
|
||||
--> $DIR/opaque_types.rs:11:11
|
||||
--> $DIR/opaque_types.rs:12:11
|
||||
|
|
||||
LL | foo::<42>();
|
||||
| ^^
|
||||
note: ...which requires borrow-checking `main::{constant#0}`...
|
||||
--> $DIR/opaque_types.rs:11:11
|
||||
--> $DIR/opaque_types.rs:12:11
|
||||
|
|
||||
LL | foo::<42>();
|
||||
| ^^
|
||||
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>();
|
||||
| ^^
|
||||
note: ...which requires const checking `main::{constant#0}`...
|
||||
--> $DIR/opaque_types.rs:11:11
|
||||
--> $DIR/opaque_types.rs:12:11
|
||||
|
|
||||
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
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0391.
|
||||
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() {
|
||||
async fn cb() {
|
||||
let a = Foo; //~ ERROR cannot find value `Foo` in this scope
|
||||
}
|
||||
mod helper {
|
||||
use super::*;
|
||||
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;
|
||||
// Check that statics are inhabited computes they layout.
|
||||
static POOL: Task<F> = Task::new();
|
||||
Task::spawn(&POOL, || cb());
|
||||
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
|
||||
--> $DIR/layout-error.rs:21:17
|
||||
--> $DIR/layout-error.rs:27:21
|
||||
|
|
||||
LL | let a = Foo;
|
||||
| ^^^ not found in this scope
|
||||
LL | let a = Foo;
|
||||
| ^^^ not found in this scope
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
@ -4,22 +4,23 @@
|
||||
// Regression test for #80998.
|
||||
//
|
||||
//@ aux-build:metadata-sufficient-for-layout.rs
|
||||
//@ check-pass
|
||||
|
||||
#![feature(type_alias_impl_trait, rustc_attrs)]
|
||||
#![feature(coroutine_trait)]
|
||||
|
||||
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 = ()>;
|
||||
|
||||
// Static queries the layout of the coroutine.
|
||||
static A: Option<F> = None;
|
||||
|
||||
fn f() -> F {
|
||||
metadata_sufficient_for_layout::g()
|
||||
fn f() -> F {
|
||||
metadata_sufficient_for_layout::g()
|
||||
}
|
||||
}
|
||||
|
||||
#[rustc_error]
|
||||
fn main() {} //~ ERROR
|
||||
// Static queries the layout of the coroutine.
|
||||
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;
|
||||
|
||||
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<'_> {
|
||||
async {}
|
||||
fn foo<'a>(_: &()) -> Fut<'_> {
|
||||
async {}
|
||||
}
|
||||
}
|
||||
use foo::*;
|
||||
|
||||
trait Test {
|
||||
fn hello();
|
||||
|
@ -11,9 +11,13 @@ fn test_closure() {
|
||||
closure(&opaque());
|
||||
}
|
||||
|
||||
type Opaque2 = impl Sized;
|
||||
type Opaque<'a> = Opaque2;
|
||||
fn define<'a>() -> Opaque<'a> {}
|
||||
mod helper {
|
||||
pub type Opaque2 = impl Sized;
|
||||
pub type Opaque<'a> = Opaque2;
|
||||
fn define<'a>() -> Opaque<'a> {}
|
||||
}
|
||||
|
||||
use helper::*;
|
||||
|
||||
fn test_tait(_: &Opaque<'_>) {
|
||||
None::<&'static Opaque<'_>>;
|
||||
|
@ -1,10 +1,8 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type FooArg<'a> = &'a dyn ToString;
|
||||
type FooRet = impl std::fmt::Debug;
|
||||
|
||||
type FooItem = Box<dyn Fn(FooArg) -> FooRet>;
|
||||
type Foo = impl Iterator<Item = FooItem>;
|
||||
|
||||
#[repr(C)]
|
||||
struct Bar(u8);
|
||||
@ -17,19 +15,26 @@ impl Iterator for Bar {
|
||||
}
|
||||
}
|
||||
|
||||
fn quux(st: FooArg) -> FooRet {
|
||||
Some(st.to_string())
|
||||
mod ret {
|
||||
pub type FooRet = impl std::fmt::Debug;
|
||||
pub fn quux(st: super::FooArg) -> FooRet {
|
||||
Some(st.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn ham() -> Foo {
|
||||
Bar(1)
|
||||
}
|
||||
|
||||
fn oof(_: Foo) -> impl std::fmt::Debug {
|
||||
let mut bar = ham();
|
||||
let func = bar.next().unwrap();
|
||||
return func(&"oof"); //~ ERROR opaque type's hidden type cannot be another opaque type
|
||||
use ret::*;
|
||||
mod foo {
|
||||
pub type Foo = impl Iterator<Item = super::FooItem>;
|
||||
pub fn ham() -> Foo {
|
||||
super::Bar(1)
|
||||
}
|
||||
pub fn oof(_: Foo) -> impl std::fmt::Debug {
|
||||
//~^ ERROR: item does not constrain `Foo::{opaque#0}`, but has it in its signature
|
||||
let mut bar = ham();
|
||||
let func = bar.next().unwrap();
|
||||
return func(&"oof");
|
||||
}
|
||||
}
|
||||
use foo::*;
|
||||
|
||||
fn main() {
|
||||
let _ = oof(ham());
|
||||
|
@ -1,19 +1,15 @@
|
||||
error: opaque type's hidden type cannot be another opaque type from the same scope
|
||||
--> $DIR/issue-70877.rs:31:12
|
||||
error: item does not constrain `Foo::{opaque#0}`, but has it in its signature
|
||||
--> $DIR/issue-70877.rs:30:12
|
||||
|
|
||||
LL | return func(&"oof");
|
||||
| ^^^^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope
|
||||
LL | pub fn oof(_: Foo) -> impl std::fmt::Debug {
|
||||
| ^^^
|
||||
|
|
||||
note: opaque type whose hidden type is being assigned
|
||||
--> $DIR/issue-70877.rs:28:19
|
||||
= 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-70877.rs:26:20
|
||||
|
|
||||
LL | fn oof(_: Foo) -> impl std::fmt::Debug {
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
note: opaque type being used as hidden type
|
||||
--> $DIR/issue-70877.rs:4:15
|
||||
|
|
||||
LL | type FooRet = impl std::fmt::Debug;
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
LL | pub type Foo = impl Iterator<Item = super::FooItem>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
@ -2,19 +2,20 @@
|
||||
|
||||
//@ check-pass
|
||||
|
||||
trait Foo<T> {}
|
||||
pub trait Foo<T> {}
|
||||
impl<T, U> Foo<T> for U {}
|
||||
|
||||
type Scope = impl Foo<()>;
|
||||
mod scope {
|
||||
pub type Scope = impl super::Foo<()>;
|
||||
|
||||
#[allow(unused)]
|
||||
fn infer_scope() -> Scope {
|
||||
()
|
||||
#[allow(unused)]
|
||||
fn infer_scope() -> Scope {
|
||||
()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn ice() -> impl Foo<Scope>
|
||||
{
|
||||
fn ice() -> impl Foo<scope::Scope> {
|
||||
loop {}
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>
|
||||
//~^ ERROR unconstrained opaque type
|
||||
|
||||
fn execute_transaction_fut<'f, F, O>(
|
||||
//~^ ERROR: item does not constrain
|
||||
f: F,
|
||||
) -> impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O>
|
||||
where
|
||||
@ -37,10 +38,12 @@ where
|
||||
|
||||
impl Context {
|
||||
async fn do_transaction<O>(
|
||||
//~^ ERROR: item does not constrain
|
||||
&self, f: impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O>
|
||||
) -> TransactionResult<O>
|
||||
{
|
||||
//~^ ERROR expected generic lifetime parameter, found `'_`
|
||||
//~| ERROR: item does not constrain
|
||||
let mut conn = Connection {};
|
||||
let mut transaction = TestTransaction { conn: &mut conn };
|
||||
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
|
||||
--> $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
|
||||
|
||||
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>>;
|
||||
| --- this generic parameter must be used with a generic lifetime parameter
|
||||
@ -16,19 +61,20 @@ LL | f
|
||||
| ^
|
||||
|
||||
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>>;
|
||||
| --- this generic parameter must be used with a generic lifetime parameter
|
||||
...
|
||||
LL | / {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | let mut conn = Connection {};
|
||||
LL | | let mut transaction = TestTransaction { conn: &mut conn };
|
||||
LL | | f(&mut transaction).await
|
||||
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`.
|
||||
|
@ -2,18 +2,23 @@
|
||||
|
||||
//@ 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;
|
||||
impl<'a> T for &'a S {
|
||||
type Item = &'a ();
|
||||
}
|
||||
|
||||
fn filter_positive<'a>() -> Alias<'a> {
|
||||
&S
|
||||
struct S;
|
||||
impl<'a> T for &'a S {
|
||||
type Item = &'a ();
|
||||
}
|
||||
|
||||
pub fn filter_positive<'a>() -> Alias<'a> {
|
||||
&S
|
||||
}
|
||||
}
|
||||
use helper::*;
|
||||
|
||||
fn with_positive(fun: impl Fn(Alias<'_>)) {
|
||||
fun(filter_positive());
|
||||
|
@ -6,20 +6,23 @@
|
||||
|
||||
use std::marker::Destruct;
|
||||
|
||||
trait T {
|
||||
type Item;
|
||||
}
|
||||
mod foo {
|
||||
trait T {
|
||||
type Item;
|
||||
}
|
||||
|
||||
type Alias<'a> = impl T<Item = &'a ()>;
|
||||
pub type Alias<'a> = impl T<Item = &'a ()>;
|
||||
|
||||
struct S;
|
||||
impl<'a> T for &'a S {
|
||||
type Item = &'a ();
|
||||
}
|
||||
struct S;
|
||||
impl<'a> T for &'a S {
|
||||
type Item = &'a ();
|
||||
}
|
||||
|
||||
const fn filter_positive<'a>() -> &'a Alias<'a> {
|
||||
&&S
|
||||
pub const fn filter_positive<'a>() -> &'a Alias<'a> {
|
||||
&&S
|
||||
}
|
||||
}
|
||||
use foo::*;
|
||||
|
||||
const fn with_positive<F: ~const for<'a> Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
|
||||
fun(filter_positive());
|
||||
|
@ -1,11 +1,11 @@
|
||||
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) {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
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());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -13,15 +13,15 @@ LL | fun(filter_positive());
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
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
|
||||
|
|
||||
LL + #![feature(effects)]
|
||||
|
|
||||
|
||||
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) {
|
||||
| ^^^ the destructor for this type cannot be evaluated in constant functions
|
||||
|
@ -2,7 +2,14 @@
|
||||
|
||||
//@ 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;
|
||||
|
||||
@ -12,8 +19,4 @@ impl PartialEq<(Foo, i32)> for Bar {
|
||||
}
|
||||
}
|
||||
|
||||
fn foo() -> Foo {
|
||||
Bar
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -9,6 +9,7 @@ mod a {
|
||||
impl PartialEq<(Bar, i32)> for Bar {
|
||||
fn eq(&self, _other: &(Foo, i32)) -> bool {
|
||||
//~^ ERROR: `eq` has an incompatible type for trait
|
||||
//~| ERROR: item does not constrain `a::Foo::{opaque#0}`
|
||||
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
|
||||
--> $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, _)) -> _`
|
||||
|
||||
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)>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -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
|
||||
|
||||
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)>;
|
||||
| -------------------------- the expected opaque type
|
||||
@ -44,11 +57,11 @@ LL | fn eq(&self, _other: &(Bar, i32)) -> bool {
|
||||
= note: expected signature `fn(&b::Bar, &(b::Foo, _)) -> _`
|
||||
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
|
||||
--> $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 {
|
||||
| ^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
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
|
||||
--> $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
|
||||
|
||||
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)
|
||||
| ^ 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;
|
||||
| ^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -9,7 +9,8 @@ type B = impl Foo;
|
||||
trait Foo {}
|
||||
|
||||
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)
|
||||
//[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)]
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
fn main() {
|
||||
//~^ ERROR: item does not constrain
|
||||
type Existential = impl Debug;
|
||||
|
||||
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>;
|
||||
}
|
||||
|
||||
trait F {}
|
||||
impl F for () {}
|
||||
type DummyT<T> = impl F;
|
||||
fn _dummy_t<T>() -> DummyT<T> {}
|
||||
mod f {
|
||||
pub trait F {}
|
||||
impl F for () {}
|
||||
pub type DummyT<T> = impl F;
|
||||
fn _dummy_t<T>() -> DummyT<T> {}
|
||||
}
|
||||
use f::*;
|
||||
|
||||
struct Phantom1<T>(PhantomData<T>);
|
||||
struct Phantom2<T>(PhantomData<T>);
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: fatal error triggered by #[rustc_error]
|
||||
--> $DIR/issue-75053.rs:46:1
|
||||
--> $DIR/issue-75053.rs:49:1
|
||||
|
|
||||
LL | fn main() {
|
||||
| ^^^^^^^^^
|
||||
|
@ -7,6 +7,7 @@ type Bar = impl Sized;
|
||||
impl Foo {
|
||||
fn foo(self: Bar) {}
|
||||
//~^ ERROR: invalid `self` parameter type: `Bar`
|
||||
//~| ERROR: item does not constrain
|
||||
}
|
||||
|
||||
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
|
||||
--> $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
|
||||
= 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`.
|
||||
|
@ -1,13 +1,21 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
#![allow(dead_code)]
|
||||
//@ check-pass
|
||||
use std::fmt::Debug;
|
||||
|
||||
type Foo = impl Debug;
|
||||
mod foo {
|
||||
use std::fmt::Debug;
|
||||
|
||||
fn foo1(mut x: Foo) {
|
||||
x = 22_u32;
|
||||
pub type Foo = impl Debug;
|
||||
|
||||
fn foo1(mut x: Foo) {
|
||||
x = 22_u32;
|
||||
}
|
||||
|
||||
pub fn foo_value() -> Foo {
|
||||
11_u32
|
||||
}
|
||||
}
|
||||
use foo::*;
|
||||
|
||||
fn foo2(mut x: Foo) {
|
||||
// no constraint on x
|
||||
@ -17,10 +25,6 @@ fn foo3(x: Foo) {
|
||||
println!("{:?}", x);
|
||||
}
|
||||
|
||||
fn foo_value() -> Foo {
|
||||
11_u32
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo3(foo_value());
|
||||
}
|
||||
|
@ -2,18 +2,23 @@
|
||||
|
||||
//@ 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;
|
||||
impl<'a> T for &'a S {
|
||||
type Item = &'a ();
|
||||
}
|
||||
|
||||
fn filter_positive<'a>() -> Alias<'a> {
|
||||
&S
|
||||
struct S;
|
||||
impl<'a> T for &'a S {
|
||||
type Item = &'a ();
|
||||
}
|
||||
|
||||
pub fn filter_positive<'a>() -> Alias<'a> {
|
||||
&S
|
||||
}
|
||||
}
|
||||
use helper::*;
|
||||
|
||||
fn with_positive(fun: impl Fn(Alias<'_>)) {
|
||||
fun(filter_positive());
|
||||
|
@ -3,12 +3,15 @@
|
||||
|
||||
#![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> {
|
||||
t
|
||||
//~^ ERROR the trait bound `T: Clone` is not satisfied
|
||||
fn f<T: Clone>(t: T) -> X<T> {
|
||||
t
|
||||
//~^ ERROR the trait bound `T: Clone` is not satisfied
|
||||
}
|
||||
}
|
||||
use foo::X;
|
||||
|
||||
fn g<T>(o: Option<X<T>>) -> Option<X<T>> {
|
||||
o.clone()
|
||||
|
@ -1,13 +1,13 @@
|
||||
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
|
||||
| ^ the trait `Clone` is not implemented for `T`
|
||||
LL | t
|
||||
| ^ the trait `Clone` is not implemented for `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
|
||||
|
||||
|
@ -6,7 +6,14 @@
|
||||
|
||||
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
|
||||
where
|
||||
@ -16,9 +23,6 @@ where
|
||||
_: &'a (),
|
||||
_: &mut dyn FnMut(Emplacable<WithEmplacableForFn<'a>>) -> R,
|
||||
) -> R {
|
||||
fn _constrain(_: &mut ()) -> WithEmplacableForFn<'_> {
|
||||
()
|
||||
}
|
||||
loop {}
|
||||
}
|
||||
|
||||
|
@ -4,20 +4,24 @@
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
trait Anything {}
|
||||
impl<T> Anything for T {}
|
||||
type Input = impl Anything;
|
||||
mod foo {
|
||||
pub trait 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) {
|
||||
f(i);
|
||||
}
|
||||
|
||||
fn bop(_: Input) {
|
||||
run(
|
||||
|x: u32| {
|
||||
println!("{x}");
|
||||
},
|
||||
0,
|
||||
);
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -2,20 +2,28 @@
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
trait Foo {
|
||||
// This was reachable in https://github.com/rust-lang/rust/issues/100800
|
||||
fn foo(&self) {
|
||||
unreachable!()
|
||||
mod foo {
|
||||
pub trait Foo {
|
||||
// This was reachable in https://github.com/rust-lang/rust/issues/100800
|
||||
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) {
|
||||
f(i)
|
||||
}
|
||||
@ -23,10 +31,4 @@ fn run2<F: FnOnce(B)>(f: F, i: B) {
|
||||
f(i)
|
||||
}
|
||||
|
||||
fn bop() -> Input {
|
||||
run1(|x: B| x.foo(), B);
|
||||
run2(|x: B| x.foo(), B);
|
||||
panic!()
|
||||
}
|
||||
|
||||
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
|
||||
--> $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`
|
||||
|
||||
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>() {
|
||||
//~^ 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)]
|
||||
let x: u32 = N;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ mod lifetime_params {
|
||||
fn defining(s: &str) -> Ty<'_> { s }
|
||||
fn execute(ty: Ty<'_>) -> &str { todo!() }
|
||||
//~^ 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;
|
||||
//~^ 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 execute(ty: Ty<'_>) -> &str { ty() }
|
||||
//~^ 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
|
||||
|
@ -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: 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
|
||||
--> $DIR/constrain_inputs.rs:9:35
|
||||
--> $DIR/constrain_inputs.rs:10:35
|
||||
|
|
||||
LL | type BadFnSig = fn(Ty<'_>) -> &str;
|
||||
| ^^^^
|
||||
@ -17,7 +30,7 @@ LL | type BadFnSig = fn(Ty<'_>) -> &str;
|
||||
= 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
|
||||
--> $DIR/constrain_inputs.rs:11:42
|
||||
--> $DIR/constrain_inputs.rs:12:42
|
||||
|
|
||||
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
|
||||
|
||||
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() }
|
||||
| ^^^^
|
||||
@ -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: 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
|
||||
--> $DIR/constrain_inputs.rs:27:37
|
||||
--> $DIR/constrain_inputs.rs:29:37
|
||||
|
|
||||
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
|
||||
|
||||
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;
|
||||
| ^^^^
|
||||
@ -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: 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.
|
||||
For more information about an error, try `rustc --explain E0581`.
|
||||
|
@ -3,10 +3,12 @@
|
||||
|
||||
#![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;
|
||||
|
||||
fn foo() -> Debuggable {
|
||||
0u32
|
||||
}
|
||||
|
@ -23,9 +23,11 @@ impl<F: for<'a> Fn(&'a ()) -> StateWidget<'a>> Widget<()> for StatefulWidget<F>
|
||||
type 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<()> {
|
||||
//~^ ERROR item does not constrain
|
||||
StatefulWidget(build)
|
||||
//~^ 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
|
||||
--> $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 ()>;
|
||||
| ------------------- the expected opaque type
|
||||
@ -11,7 +37,7 @@ LL | new_stateful_widget(|_| ()).make_state();
|
||||
found unit type `()`
|
||||
|
||||
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 ()>;
|
||||
| -- 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)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0792.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
|
@ -17,10 +17,12 @@ async fn operation(_: &mut ()) -> () {
|
||||
}
|
||||
|
||||
async fn call<F>(_f: F)
|
||||
//~^ ERROR item does not constrain
|
||||
where
|
||||
for<'any> F: FnMut(&'any mut ()) -> FutNothing<'any>,
|
||||
{
|
||||
//~^ ERROR: expected generic lifetime parameter, found `'any`
|
||||
//~| ERROR item does not constrain
|
||||
}
|
||||
|
||||
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
|
||||
--> $DIR/hkl_forbidden4.rs:10:23
|
||||
|
|
||||
@ -16,13 +45,14 @@ LL | call(operation).await
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
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 = ()>;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
...
|
||||
LL | / {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
@ -38,6 +68,6 @@ note: previous use here
|
||||
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`.
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
|
||||
trait MyIndex<T> {
|
||||
type O;
|
||||
fn my_index(self) -> Self::O;
|
||||
@ -16,7 +15,6 @@ trait MyFrom<T>: Sized {
|
||||
fn my_from(value: T) -> Result<Self, Self::Error>;
|
||||
}
|
||||
|
||||
|
||||
trait F {}
|
||||
impl F for () {}
|
||||
type DummyT<T> = impl F;
|
||||
@ -28,6 +26,7 @@ struct Scope<T>(Phantom2<DummyT<T>>);
|
||||
|
||||
impl<T> Scope<T> {
|
||||
fn new() -> Self {
|
||||
//~^ ERROR item does not constrain
|
||||
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
|
||||
type O = T;
|
||||
fn my_index(self) -> Self::O {
|
||||
//~^ ERROR item does not constrain
|
||||
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
|
||||
--> $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> {
|
||||
| ^ 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`.
|
||||
|
@ -1,7 +1,11 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type WithLifetime<'a> = impl Equals<SelfType = ()>;
|
||||
fn _defining_use<'a>() -> WithLifetime<'a> {}
|
||||
mod foo {
|
||||
use super::Equals;
|
||||
pub type WithLifetime<'a> = impl Equals<SelfType = ()>;
|
||||
fn _defining_use<'a>() -> WithLifetime<'a> {}
|
||||
}
|
||||
use foo::WithLifetime;
|
||||
|
||||
trait Convert<'a> {
|
||||
type Witness;
|
||||
|
@ -1,5 +1,5 @@
|
||||
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 () {
|
||||
| -- lifetime `'a` defined here
|
||||
|
@ -2,9 +2,17 @@
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type Ty<'a, A> = impl Sized + 'a;
|
||||
fn defining<'a, A>() -> Ty<'a, A> {}
|
||||
fn assert_static<T: 'static>() {}
|
||||
fn test<'a, A>() where Ty<'a, A>: 'static, { assert_static::<Ty<'a, A>>() }
|
||||
mod helper {
|
||||
pub type Ty<'a, A> = impl Sized + 'a;
|
||||
fn defining<'a, A>() -> 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() {}
|
||||
|
@ -1,7 +1,11 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type WithLifetime<T> = impl Equals<SelfType = ()>;
|
||||
fn _defining_use<T>() -> WithLifetime<T> {}
|
||||
mod foo {
|
||||
use super::Equals;
|
||||
pub type WithLifetime<T> = impl Equals<SelfType = ()>;
|
||||
fn _defining_use<T>() -> WithLifetime<T> {}
|
||||
}
|
||||
use foo::WithLifetime;
|
||||
|
||||
trait Convert<'a> {
|
||||
type Witness;
|
||||
@ -12,7 +16,6 @@ impl<'a> Convert<'a> for () {
|
||||
type Witness = WithLifetime<&'a ()>;
|
||||
|
||||
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
|
||||
// of the `&'b WithLifetime<&'a ()>` argument
|
||||
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
|
||||
--> $DIR/implied_bounds_from_types.rs:18:9
|
||||
--> $DIR/implied_bounds_from_types.rs:21:9
|
||||
|
|
||||
LL | impl<'a> Convert<'a> for () {
|
||||
| -- lifetime `'a` defined here
|
||||
@ -24,6 +12,5 @@ LL | x
|
||||
|
|
||||
= 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)]
|
||||
|
||||
mod test_lifetime_param {
|
||||
type Ty<'a> = impl Sized;
|
||||
fn defining(a: &str) -> Ty<'_> { a }
|
||||
fn assert_static<'a: 'static>() {}
|
||||
fn test<'a>() where Ty<'a>: 'static { assert_static::<'a>() }
|
||||
pub type Ty<'a> = impl Sized;
|
||||
fn defining(a: &str) -> Ty<'_> {
|
||||
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
|
||||
}
|
||||
|
||||
mod test_higher_kinded_lifetime_param {
|
||||
type Ty<'a> = impl Sized;
|
||||
fn defining(a: &str) -> Ty<'_> { a }
|
||||
fn assert_static<'a: 'static>() {}
|
||||
fn test<'a>() where for<'b> Ty<'b>: 'a { assert_static::<'a>() }
|
||||
pub type Ty<'a> = impl Sized + 'a;
|
||||
fn defining(a: &str) -> Ty<'_> {
|
||||
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
|
||||
}
|
||||
|
||||
mod test_higher_kinded_lifetime_param2 {
|
||||
fn assert_static<'a: 'static>() {}
|
||||
fn test<'a>() { assert_static::<'a>() }
|
||||
//~^ ERROR: lifetime may not live long enough
|
||||
fn test<'a>() {
|
||||
assert_static::<'a>()
|
||||
//~^ ERROR: lifetime may not live long enough
|
||||
}
|
||||
}
|
||||
|
||||
mod test_type_param {
|
||||
type Ty<A> = impl Sized;
|
||||
fn defining<A>(s: A) -> Ty<A> { s }
|
||||
fn assert_static<A: 'static>() {}
|
||||
fn test<A>() where Ty<A>: 'static { assert_static::<A>() }
|
||||
pub type Ty<A> = impl Sized;
|
||||
fn defining<A>(s: A) -> Ty<A> {
|
||||
s
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
mod test_implied_from_fn_sig {
|
||||
type Opaque<T: 'static> = impl Sized;
|
||||
fn defining<T: 'static>() -> Opaque<T> {}
|
||||
mod foo {
|
||||
pub type Opaque<T: 'static> = impl Sized;
|
||||
fn defining<T: 'static>() -> Opaque<T> {}
|
||||
}
|
||||
fn assert_static<T: 'static>() {}
|
||||
fn test<T>(_: Opaque<T>) { assert_static::<T>(); }
|
||||
|
||||
fn test<T>(_: foo::Opaque<T>) {
|
||||
assert_static::<T>();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,36 +1,42 @@
|
||||
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>() }
|
||||
| -- lifetime `'a` defined here ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
LL | fn test_lifetime_param_test<'a>()
|
||||
| -- lifetime `'a` defined here
|
||||
...
|
||||
LL | test_lifetime_param::assert_static::<'a>()
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
|
||||
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>() }
|
||||
| -- lifetime `'a` defined here ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
LL | fn test_higher_kinded_lifetime_param_test<'a>()
|
||||
| -- 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
|
||||
--> $DIR/implied_lifetime_wf_check3.rs:21:21
|
||||
--> $DIR/implied_lifetime_wf_check3.rs:36:9
|
||||
|
|
||||
LL | fn test<'a>() { assert_static::<'a>() }
|
||||
| -- ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
| |
|
||||
| lifetime `'a` defined here
|
||||
LL | fn test<'a>() {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | assert_static::<'a>()
|
||||
| ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
|
||||
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>() }
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| the parameter type `A` must be valid for the static lifetime...
|
||||
| ...so that the type `A` will meet its required lifetime bounds
|
||||
LL | test_type_param::assert_static::<A>()
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| the parameter type `A` must be valid for the static lifetime...
|
||||
| ...so that the type `A` will meet its required lifetime bounds
|
||||
|
|
||||
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
|
||||
|
||||
|
@ -1,11 +1,20 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
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
|
||||
fn defining<A: 'static>(s: A) -> Ty<A> { s }
|
||||
fn assert_static<A: 'static>() {}
|
||||
fn test<A>() where Ty<A>: 'static { assert_static::<A>() }
|
||||
fn defining<A: 'static>(s: A) -> Ty<A> {
|
||||
s
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -1,30 +1,30 @@
|
||||
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;
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| the parameter type `A` must be valid for the static lifetime...
|
||||
| ...so that the type `A` will meet its required lifetime bounds
|
||||
LL | pub type Ty<A> = impl Sized + 'static;
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| the parameter type `A` must be valid for the static lifetime...
|
||||
| ...so that the type `A` will meet its required lifetime bounds
|
||||
|
|
||||
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
|
||||
--> $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>() }
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| the parameter type `A` must be valid for the static lifetime...
|
||||
| ...so that the type `A` will meet its required lifetime bounds
|
||||
LL | assert_static::<A>()
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| the parameter type `A` must be valid for the static lifetime...
|
||||
| ...so that the type `A` will meet its required lifetime bounds
|
||||
|
|
||||
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
|
||||
|
||||
|
@ -2,17 +2,21 @@
|
||||
|
||||
//@ check-pass
|
||||
|
||||
trait Trait {}
|
||||
mod foo {
|
||||
pub trait Trait {}
|
||||
|
||||
type TAIT = impl Trait;
|
||||
pub type TAIT = impl Trait;
|
||||
|
||||
struct Concrete;
|
||||
impl Trait for Concrete {}
|
||||
pub struct Concrete;
|
||||
impl Trait for Concrete {}
|
||||
|
||||
fn tait() -> TAIT {
|
||||
Concrete
|
||||
pub fn tait() -> TAIT {
|
||||
Concrete
|
||||
}
|
||||
}
|
||||
|
||||
use foo::*;
|
||||
|
||||
trait OuterTrait {
|
||||
type Item;
|
||||
}
|
||||
@ -24,9 +28,7 @@ impl<T> OuterTrait for Dummy<T> {
|
||||
}
|
||||
|
||||
fn tait_and_impl_trait() -> impl OuterTrait<Item = (TAIT, impl Trait)> {
|
||||
Dummy {
|
||||
t: (tait(), Concrete),
|
||||
}
|
||||
Dummy { t: (tait(), Concrete) }
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
//~^ ERROR: item does not constrain `ReturnType
|
||||
fn inner(val: &u32) -> ReturnType {
|
||||
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 `'_`
|
||||
--> $DIR/issue-109054.rs:18:9
|
||||
--> $DIR/issue-109054.rs:19:9
|
||||
|
|
||||
LL | type ReturnType<'a> = impl std::future::Future<Output = u32> + 'a;
|
||||
| -- 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
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0792`.
|
||||
|
@ -1,7 +1,14 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
#![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 {
|
||||
x: Bug<u8, ()>,
|
||||
@ -9,11 +16,6 @@ union Moo {
|
||||
}
|
||||
|
||||
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() {
|
||||
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
|
||||
--> $DIR/issue-53092.rs:15:5
|
||||
--> $DIR/issue-53092.rs:8:9
|
||||
|
|
||||
LL | |x| x.into()
|
||||
| ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U`
|
||||
LL | |x| x.into()
|
||||
| ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U`
|
||||
|
|
||||
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> {
|
||||
| ^^^^^^^ required by this bound in `make_bug`
|
||||
LL | fn make_bug<T, U: From<T>>() -> Bug<T, U> {
|
||||
| ^^^^^^^ required by this bound in `make_bug`
|
||||
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 an error, try `rustc --explain E0277`.
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
@ -1,10 +1,13 @@
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type Foo = impl Fn() -> usize;
|
||||
const fn bar() -> Foo {
|
||||
|| 0usize
|
||||
mod foo {
|
||||
pub type Foo = impl Fn() -> usize;
|
||||
pub const fn bar() -> Foo {
|
||||
|| 0usize
|
||||
}
|
||||
}
|
||||
use foo::*;
|
||||
const BAZR: Foo = bar();
|
||||
|
||||
#[rustc_error]
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: fatal error triggered by #[rustc_error]
|
||||
--> $DIR/issue-53096.rs:11:1
|
||||
--> $DIR/issue-53096.rs:14:1
|
||||
|
|
||||
LL | fn main() {}
|
||||
| ^^^^^^^^^
|
||||
|
@ -2,14 +2,16 @@
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type A = impl Iterator;
|
||||
mod helper {
|
||||
pub type A = impl Iterator;
|
||||
|
||||
fn def_a() -> A {
|
||||
0..1
|
||||
pub fn def_a() -> A {
|
||||
0..1
|
||||
}
|
||||
}
|
||||
|
||||
pub fn use_a() {
|
||||
def_a().map(|x| x);
|
||||
helper::def_a().map(|x| x);
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,6 +1,13 @@
|
||||
#![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;
|
||||
|
||||
@ -9,7 +16,3 @@ fn main() {
|
||||
//~^ ERROR
|
||||
unsafe { TEST = Some(foo()) }
|
||||
}
|
||||
|
||||
fn foo() -> Debuggable {
|
||||
0u32
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: fatal error triggered by #[rustc_error]
|
||||
--> $DIR/issue-60407.rs:8:1
|
||||
--> $DIR/issue-60407.rs:15:1
|
||||
|
|
||||
LL | fn main() {
|
||||
| ^^^^^^^^^
|
||||
|
@ -1,5 +1,4 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
//@ check-pass
|
||||
|
||||
pub trait Foo {}
|
||||
|
||||
@ -39,6 +38,7 @@ impl Baz for () {
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
#![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;
|
||||
// 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
|
||||
fn bop(_: T) {
|
||||
super::take(|| {});
|
||||
super::take(|| {});
|
||||
}
|
||||
}
|
||||
use foo::*;
|
||||
|
||||
fn take(_: fn() -> T) {}
|
||||
|
||||
fn bop(_: T) {
|
||||
take(|| {});
|
||||
take(|| {});
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -15,10 +15,13 @@ trait MyFrom<T>: Sized {
|
||||
}
|
||||
|
||||
/* MCVE starts here */
|
||||
trait F {}
|
||||
impl F for () {}
|
||||
type DummyT<T> = impl F;
|
||||
fn _dummy_t<T>() -> DummyT<T> {}
|
||||
mod f {
|
||||
pub trait F {}
|
||||
impl F for () {}
|
||||
pub type DummyT<T> = impl F;
|
||||
fn _dummy_t<T>() -> DummyT<T> {}
|
||||
}
|
||||
use f::DummyT;
|
||||
|
||||
struct Phantom1<T>(PhantomData<T>);
|
||||
struct Phantom2<T>(PhantomData<T>);
|
||||
|
@ -3,18 +3,24 @@
|
||||
|
||||
#![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;
|
||||
impl<'a> T for &'a S {
|
||||
type Item = &'a ();
|
||||
struct S;
|
||||
impl<'a> T for &'a S {
|
||||
type Item = &'a ();
|
||||
}
|
||||
|
||||
pub fn filter_positive<'a>() -> Alias<'a> {
|
||||
&S
|
||||
}
|
||||
}
|
||||
|
||||
fn filter_positive<'a>() -> Alias<'a> {
|
||||
&S
|
||||
}
|
||||
use foo::*;
|
||||
|
||||
fn with_positive(fun: impl Fn(Alias<'_>)) {
|
||||
fun(filter_positive());
|
||||
|
@ -7,11 +7,18 @@
|
||||
//@ check-pass
|
||||
#![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 {
|
||||
fn test(self);
|
||||
}
|
||||
|
||||
|
||||
impl Test for define::F {
|
||||
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, _>`
|
||||
--> $DIR/issue-84660-unsoundness.rs:28:1
|
||||
--> $DIR/issue-84660-unsoundness.rs:29:1
|
||||
|
|
||||
LL | impl<In, Out> Trait<Bar, In> for Out {
|
||||
| ------------------------------------ first implementation here
|
||||
@ -7,6 +20,6 @@ LL | impl<In, Out> Trait<Bar, In> for Out {
|
||||
LL | impl<In, Out> Trait<(), In> for Out {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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`.
|
||||
|
@ -4,12 +4,13 @@ error[E0284]: type annotations needed: cannot satisfy `<Out as Trait<Bar, In>>::
|
||||
LL | fn convert(_i: In) -> Self::Out {
|
||||
| _____________________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | unreachable!();
|
||||
LL | | }
|
||||
| |_____^ cannot satisfy `<Out as Trait<Bar, In>>::Out == ()`
|
||||
|
||||
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 {
|
||||
| ------------------------------------ first implementation here
|
||||
|
@ -21,6 +21,7 @@ impl<In, Out> Trait<Bar, In> for Out {
|
||||
type Out = Out;
|
||||
fn convert(_i: In) -> Self::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!();
|
||||
}
|
||||
}
|
||||
|
@ -6,12 +6,13 @@ use std::fmt::Debug;
|
||||
type FooX = impl Debug;
|
||||
//~^ ERROR unconstrained opaque type
|
||||
|
||||
trait Foo<A> { }
|
||||
trait Foo<A> {}
|
||||
|
||||
impl Foo<FooX> for () { }
|
||||
impl Foo<FooX> for () {}
|
||||
|
||||
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
|
||||
--> $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
|
||||
|
||||
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 {}
|
||||
|
||||
fn bar() -> Bar {
|
||||
//~^ ERROR: item does not constrain
|
||||
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`
|
||||
--> $DIR/nested.rs:15:22
|
||||
--> $DIR/nested.rs:16:22
|
||||
|
|
||||
LL | println!("{:?}", bar());
|
||||
| ^^^^^ `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`
|
||||
= 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`.
|
||||
|
@ -11,6 +11,7 @@ mod my_mod {
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
--> $DIR/nested_type_alias_impl_trait.rs:14:9
|
||||
--> $DIR/nested_type_alias_impl_trait.rs:15:9
|
||||
|
|
||||
LL | get_foo()
|
||||
| ^^^^^^^^^ 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;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
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'
|
||||
pub fn bar(x: Foo) -> Foo {
|
||||
//~^ ERROR: item does not constrain `Foo::{opaque#0}`
|
||||
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
|
||||
--> $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
|
||||
|
||||
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,) {
|
||||
#[inline]
|
||||
fn get(&self) -> u32 { self.0 }
|
||||
fn get(&self) -> u32 {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tr1() -> impl Tr {
|
||||
(32,)
|
||||
}
|
||||
|
||||
pub fn tr2() -> impl Tr {
|
||||
struct Inner {
|
||||
x: X,
|
||||
}
|
||||
type X = impl Tr;
|
||||
impl Tr for Inner {
|
||||
fn get(&self) -> u32 {
|
||||
self.x.get()
|
||||
}
|
||||
}
|
||||
|
||||
Inner {
|
||||
x: tr1(),
|
||||
struct Inner {
|
||||
x: helper::X,
|
||||
}
|
||||
impl Tr for Inner {
|
||||
fn get(&self) -> u32 {
|
||||
self.x.get()
|
||||
}
|
||||
}
|
||||
|
||||
mod helper {
|
||||
pub use super::*;
|
||||
pub type X = impl Tr;
|
||||
|
||||
pub fn tr2() -> impl Tr
|
||||
where
|
||||
X:,
|
||||
{
|
||||
Inner { x: tr1() }
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,11 @@
|
||||
//@ check-pass
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type Ty<'a> = impl Sized + 'a;
|
||||
fn define<'a>() -> Ty<'a> {}
|
||||
mod tait {
|
||||
pub type Ty<'a> = impl Sized + 'a;
|
||||
fn define<'a>() -> Ty<'a> {}
|
||||
}
|
||||
use tait::Ty;
|
||||
|
||||
// Ty<'^0>: 'static
|
||||
fn test1(_: &'static fn(Ty<'_>)) {}
|
||||
@ -15,4 +18,4 @@ fn test2() {
|
||||
None::<&fn(Ty<'_>)>;
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
fn main() {}
|
||||
|
@ -9,26 +9,29 @@ struct A;
|
||||
impl Test for A {}
|
||||
|
||||
struct B<T> {
|
||||
inner: T,
|
||||
inner: T,
|
||||
}
|
||||
|
||||
impl<T: Test> Test for B<T> {}
|
||||
|
||||
type TestImpl = impl Test;
|
||||
mod helper {
|
||||
use super::*;
|
||||
pub type TestImpl = impl Test;
|
||||
|
||||
fn test() -> TestImpl {
|
||||
A
|
||||
pub fn test() -> TestImpl {
|
||||
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> {
|
||||
Some(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 make_option() -> Option<helper::TestImpl> {
|
||||
Some(helper::test())
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,14 +1,14 @@
|
||||
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 })
|
||||
| ^^^^^^^^^^^^^^^^^ expected `A`, got `B<TestImpl>`
|
||||
LL | Some(B { inner })
|
||||
| ^^^^^^^^^^^^^^^^^ expected `A`, got `B<TestImpl>`
|
||||
|
|
||||
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
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user