mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
Make mir borrowck's use of opaque types independent of the typeck query's result
This commit is contained in:
parent
d693a98f4e
commit
6d76002baf
@ -70,6 +70,10 @@ where
|
||||
pub fn iter_mut(&mut self) -> impl Iterator<Item = (&K, &mut V)> {
|
||||
self.into_iter()
|
||||
}
|
||||
|
||||
pub fn retain(&mut self, f: impl Fn(&(K, V)) -> bool) {
|
||||
self.0.retain(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> Default for VecMap<K, V> {
|
||||
|
@ -26,7 +26,7 @@ use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::adjustment::PointerCast;
|
||||
use rustc_middle::ty::cast::CastTy;
|
||||
use rustc_middle::ty::fold::TypeFoldable;
|
||||
use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef, UserSubsts};
|
||||
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef, UserSubsts};
|
||||
use rustc_middle::ty::{
|
||||
self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, OpaqueTypeKey, RegionVid,
|
||||
ToPredicate, Ty, TyCtxt, UserType, UserTypeAnnotationIndex, WithConstness,
|
||||
@ -60,7 +60,6 @@ use crate::borrow_check::{
|
||||
LivenessValues, PlaceholderIndex, PlaceholderIndices, RegionValueElements,
|
||||
},
|
||||
region_infer::{ClosureRegionRequirementsExt, TypeTest},
|
||||
renumber,
|
||||
type_check::free_region_relations::{CreateResult, UniversalRegionRelations},
|
||||
universal_regions::{DefiningTy, UniversalRegions},
|
||||
Upvar,
|
||||
@ -180,7 +179,66 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
||||
liveness::generate(&mut cx, body, elements, flow_inits, move_data, location_table);
|
||||
|
||||
translate_outlives_facts(&mut cx);
|
||||
cx.opaque_type_values
|
||||
let mut opaque_type_values = cx.opaque_type_values;
|
||||
|
||||
for (_, revealed_ty) in &mut opaque_type_values {
|
||||
// FIXME(oli-obk): Instead of looping, implement a visitor like
|
||||
// FullTypeResolver. We can't use FullTypeResolver here, as that will
|
||||
// resolve lifetimes lexically, which it can't because we didn't do old
|
||||
// borrowck stuff. We want to use MIR borrowck information instead.
|
||||
|
||||
while revealed_ty.has_infer_types_or_consts() {
|
||||
let prev = *revealed_ty;
|
||||
trace!(prev=?prev.kind());
|
||||
let type_resolved = infcx.shallow_resolve(prev);
|
||||
trace!(type_resolved=?type_resolved.kind());
|
||||
if prev == type_resolved {
|
||||
infcx.tcx.sess.delay_span_bug(
|
||||
body.span,
|
||||
&format!("could not resolve {:#?}", type_resolved.kind()),
|
||||
);
|
||||
*revealed_ty = infcx.tcx.ty_error();
|
||||
break;
|
||||
}
|
||||
*revealed_ty = type_resolved;
|
||||
}
|
||||
}
|
||||
|
||||
opaque_type_values.retain(|(opaque_type_key, resolved_ty)| {
|
||||
let concrete_is_opaque = if let ty::Opaque(def_id, _) = resolved_ty.kind() {
|
||||
*def_id == opaque_type_key.def_id
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if concrete_is_opaque {
|
||||
// We're using an opaque `impl Trait` type without
|
||||
// 'revealing' it. For example, code like this:
|
||||
//
|
||||
// type Foo = impl Debug;
|
||||
// fn foo1() -> Foo { ... }
|
||||
// fn foo2() -> Foo { foo1() }
|
||||
//
|
||||
// In `foo2`, we're not revealing the type of `Foo` - we're
|
||||
// just treating it as the opaque type.
|
||||
//
|
||||
// When this occurs, we do *not* want to try to equate
|
||||
// the concrete type with the underlying defining type
|
||||
// of the opaque type - this will always fail, since
|
||||
// the defining type of an opaque type is always
|
||||
// some other type (e.g. not itself)
|
||||
// Essentially, none of the normal obligations apply here -
|
||||
// we're just passing around some unknown opaque type,
|
||||
// without actually looking at the underlying type it
|
||||
// gets 'revealed' into
|
||||
debug!(
|
||||
"eq_opaque_type_and_type: non-defining use of {:?}",
|
||||
opaque_type_key.def_id,
|
||||
);
|
||||
}
|
||||
!concrete_is_opaque
|
||||
});
|
||||
opaque_type_values
|
||||
},
|
||||
);
|
||||
|
||||
@ -1240,13 +1298,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
|
||||
let infcx = self.infcx;
|
||||
let tcx = infcx.tcx;
|
||||
let param_env = self.param_env;
|
||||
let body = self.body;
|
||||
let mir_def_id = body.source.def_id().expect_local();
|
||||
|
||||
// the "concrete opaque types" maps
|
||||
let concrete_opaque_types = &tcx.typeck(mir_def_id).concrete_opaque_types;
|
||||
let mut opaque_type_values = VecMap::new();
|
||||
|
||||
debug!("eq_opaque_type_and_type: mir_def_id={:?}", mir_def_id);
|
||||
@ -1296,88 +1351,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
.eq(output_ty, revealed_ty)?,
|
||||
);
|
||||
|
||||
// For each opaque type `Foo<T>` inferred by this value, we want to equate
|
||||
// the inference variable `?T` with the revealed type that was computed
|
||||
// earlier by type check.
|
||||
for &(opaque_type_key, opaque_decl) in &opaque_type_map {
|
||||
let resolved_ty = infcx.resolve_vars_if_possible(opaque_decl.concrete_ty);
|
||||
let concrete_is_opaque = if let ty::Opaque(def_id, _) = resolved_ty.kind() {
|
||||
*def_id == opaque_type_key.def_id
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
// The revealed type computed by the earlier phase of type check.
|
||||
// In our example, this would be `(U, u32)`. Note that this references
|
||||
// the type parameter `U` from the definition of `Foo`.
|
||||
let concrete_ty = match concrete_opaque_types
|
||||
.get_by(|(key, _)| key.def_id == opaque_type_key.def_id)
|
||||
{
|
||||
None => {
|
||||
if !concrete_is_opaque {
|
||||
tcx.sess.delay_span_bug(
|
||||
body.span,
|
||||
&format!(
|
||||
"Non-defining use of {:?} with revealed type",
|
||||
opaque_type_key.def_id,
|
||||
),
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
Some(concrete_ty) => concrete_ty,
|
||||
};
|
||||
debug!("concrete_ty = {:?}", concrete_ty);
|
||||
|
||||
// Apply the substitution, in this case `[U -> T]`, so that the
|
||||
// concrete type becomes `Foo<(T, u32)>`
|
||||
let subst_opaque_defn_ty = concrete_ty.subst(tcx, opaque_type_key.substs);
|
||||
|
||||
// "Renumber" this, meaning that we replace all the regions
|
||||
// with fresh inference variables. Not relevant to our example.
|
||||
let renumbered_opaque_defn_ty =
|
||||
renumber::renumber_regions(infcx, subst_opaque_defn_ty);
|
||||
|
||||
debug!(
|
||||
"eq_opaque_type_and_type: concrete_ty={:?}={:?} opaque_defn_ty={:?}",
|
||||
concrete_ty, resolved_ty, renumbered_opaque_defn_ty,
|
||||
);
|
||||
|
||||
if !concrete_is_opaque {
|
||||
// Equate the instantiated opaque type `opaque_decl.concrete_ty` (`?T`,
|
||||
// in our example) with the renumbered version that we took from
|
||||
// the type check results (`Foo<(T, u32)>`).
|
||||
obligations.add(
|
||||
infcx
|
||||
.at(&ObligationCause::dummy(), param_env)
|
||||
.eq(opaque_decl.concrete_ty, renumbered_opaque_defn_ty)?,
|
||||
);
|
||||
opaque_type_values.insert(opaque_type_key, renumbered_opaque_defn_ty);
|
||||
} else {
|
||||
// We're using an opaque `impl Trait` type without
|
||||
// 'revealing' it. For example, code like this:
|
||||
//
|
||||
// type Foo = impl Debug;
|
||||
// fn foo1() -> Foo { ... }
|
||||
// fn foo2() -> Foo { foo1() }
|
||||
//
|
||||
// In `foo2`, we're not revealing the type of `Foo` - we're
|
||||
// just treating it as the opaque type.
|
||||
//
|
||||
// When this occurs, we do *not* want to try to equate
|
||||
// the concrete type with the underlying defining type
|
||||
// of the opaque type - this will always fail, since
|
||||
// the defining type of an opaque type is always
|
||||
// some other type (e.g. not itself)
|
||||
// Essentially, none of the normal obligations apply here -
|
||||
// we're just passing around some unknown opaque type,
|
||||
// without actually looking at the underlying type it
|
||||
// gets 'revealed' into
|
||||
debug!(
|
||||
"eq_opaque_type_and_type: non-defining use of {:?}",
|
||||
opaque_type_key.def_id,
|
||||
);
|
||||
}
|
||||
opaque_type_values.insert(opaque_type_key, opaque_decl.concrete_ty);
|
||||
}
|
||||
|
||||
debug!("eq_opaque_type_and_type: equated");
|
||||
|
@ -29,7 +29,6 @@ impl Bar for AssocNoCopy {
|
||||
impl Thing for AssocNoCopy {
|
||||
type Out = Box<dyn Bar<Assoc: Copy>>;
|
||||
//~^ ERROR the trait bound `String: Copy` is not satisfied
|
||||
//~| ERROR the trait bound `String: Copy` is not satisfied
|
||||
|
||||
fn func() -> Self::Out {
|
||||
Box::new(AssocNoCopy)
|
||||
|
@ -4,12 +4,6 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
|
||||
LL | type Out = Box<dyn Bar<Assoc: Copy>>;
|
||||
| ^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
|
||||
|
||||
error[E0277]: the trait bound `String: Copy` is not satisfied
|
||||
--> $DIR/assoc-type-eq-with-dyn-atb-fail.rs:30:28
|
||||
|
|
||||
LL | type Out = Box<dyn Bar<Assoc: Copy>>;
|
||||
| ^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
@ -12,7 +12,6 @@ fn main() {
|
||||
fn cycle1() -> impl Clone {
|
||||
//~^ ERROR cycle detected
|
||||
send(cycle2().clone());
|
||||
//~^ ERROR cannot be sent between threads safely
|
||||
|
||||
Rc::new(Cell::new(5))
|
||||
}
|
||||
|
@ -36,37 +36,37 @@ LL | fn cycle1() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`...
|
||||
note: ...which requires computing type of `cycle2::{opaque#0}`...
|
||||
--> $DIR/auto-trait-leak.rs:20:16
|
||||
--> $DIR/auto-trait-leak.rs:19:16
|
||||
|
|
||||
LL | fn cycle2() -> impl Clone {
|
||||
| ^^^^^^^^^^
|
||||
note: ...which requires borrow-checking `cycle2`...
|
||||
--> $DIR/auto-trait-leak.rs:20:1
|
||||
--> $DIR/auto-trait-leak.rs:19:1
|
||||
|
|
||||
LL | fn cycle2() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires processing `cycle2`...
|
||||
--> $DIR/auto-trait-leak.rs:20:1
|
||||
--> $DIR/auto-trait-leak.rs:19:1
|
||||
|
|
||||
LL | fn cycle2() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires processing MIR for `cycle2`...
|
||||
--> $DIR/auto-trait-leak.rs:20:1
|
||||
--> $DIR/auto-trait-leak.rs:19:1
|
||||
|
|
||||
LL | fn cycle2() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires unsafety-checking `cycle2`...
|
||||
--> $DIR/auto-trait-leak.rs:20:1
|
||||
--> $DIR/auto-trait-leak.rs:19:1
|
||||
|
|
||||
LL | fn cycle2() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires building MIR for `cycle2`...
|
||||
--> $DIR/auto-trait-leak.rs:20:1
|
||||
--> $DIR/auto-trait-leak.rs:19:1
|
||||
|
|
||||
LL | fn cycle2() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires type-checking `cycle2`...
|
||||
--> $DIR/auto-trait-leak.rs:20:1
|
||||
--> $DIR/auto-trait-leak.rs:19:1
|
||||
|
|
||||
LL | fn cycle2() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -84,22 +84,6 @@ LL | | Rc::new(String::from("foo"))
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error[E0277]: `Rc<String>` cannot be sent between threads safely
|
||||
--> $DIR/auto-trait-leak.rs:14:5
|
||||
|
|
||||
LL | fn send<T: Send>(_: T) {}
|
||||
| ---- required by this bound in `send`
|
||||
...
|
||||
LL | send(cycle2().clone());
|
||||
| ^^^^ `Rc<String>` cannot be sent between threads safely
|
||||
...
|
||||
LL | fn cycle2() -> impl Clone {
|
||||
| ---------- within this `impl Clone`
|
||||
|
|
||||
= help: within `impl Clone`, the trait `Send` is not implemented for `Rc<String>`
|
||||
= note: required because it appears within the type `impl Clone`
|
||||
error: aborting due to previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0391.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
For more information about this error, try `rustc --explain E0391`.
|
||||
|
@ -36,16 +36,7 @@ LL | type WrongGeneric<T> = impl 'static;
|
||||
LL | fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
|
||||
| - help: consider adding an explicit lifetime bound...: `T: 'static`
|
||||
|
||||
error[E0310]: the parameter type `T` may not live long enough
|
||||
--> $DIR/generic_type_does_not_live_long_enough.rs:12:24
|
||||
|
|
||||
LL | type WrongGeneric<T> = impl 'static;
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider adding an explicit lifetime bound `T: 'static`...
|
||||
= note: ...so that the type `T` will meet its required lifetime bounds
|
||||
|
||||
error: aborting due to 4 previous errors; 1 warning emitted
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0308, E0310.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
|
@ -27,16 +27,7 @@ LL | type WrongGeneric<T> = impl 'static;
|
||||
LL | fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
|
||||
| - help: consider adding an explicit lifetime bound...: `T: 'static`
|
||||
|
||||
error[E0310]: the parameter type `T` may not live long enough
|
||||
--> $DIR/generic_type_does_not_live_long_enough.rs:12:24
|
||||
|
|
||||
LL | type WrongGeneric<T> = impl 'static;
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider adding an explicit lifetime bound `T: 'static`...
|
||||
= note: ...so that the type `T` will meet its required lifetime bounds
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0310.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
|
@ -11,7 +11,6 @@ fn main() {
|
||||
|
||||
type WrongGeneric<T> = impl 'static;
|
||||
//~^ ERROR the parameter type `T` may not live long enough
|
||||
//~| ERROR the parameter type `T` may not live long enough
|
||||
//~| ERROR: at least one trait must be specified
|
||||
|
||||
fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
|
||||
|
@ -16,52 +16,5 @@ LL | type Bar = impl Baz<Self, Self>;
|
||||
= note: closure with signature `fn(&'2 X) -> &X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
|
||||
= note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-57611-trait-alias.rs:20:16
|
||||
|
|
||||
LL | type Bar = impl Baz<Self, Self>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
||||
|
|
||||
= note: expected type `for<'r> Fn<(&'r X,)>`
|
||||
found type `Fn<(&'<empty> X,)>`
|
||||
note: this closure does not fulfill the lifetime requirements
|
||||
--> $DIR/issue-57611-trait-alias.rs:28:9
|
||||
|
|
||||
LL | |x| x
|
||||
| ^^^^^
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
error: implementation of `FnOnce` is not general enough
|
||||
--> $DIR/issue-57611-trait-alias.rs:20:16
|
||||
|
|
||||
LL | type Bar = impl Baz<Self, Self>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
||||
|
|
||||
= note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
|
||||
= note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-57611-trait-alias.rs:20:16
|
||||
|
|
||||
LL | type Bar = impl Baz<Self, Self>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
||||
|
|
||||
= note: expected type `for<'r> Fn<(&'r X,)>`
|
||||
found type `Fn<(&'<empty> X,)>`
|
||||
note: this closure does not fulfill the lifetime requirements
|
||||
--> $DIR/issue-57611-trait-alias.rs:28:9
|
||||
|
|
||||
LL | |x| x
|
||||
| ^^^^^
|
||||
|
||||
error: implementation of `FnOnce` is not general enough
|
||||
--> $DIR/issue-57611-trait-alias.rs:20:16
|
||||
|
|
||||
LL | type Bar = impl Baz<Self, Self>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
||||
|
|
||||
= note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
|
||||
= note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
|
||||
|
||||
error: aborting due to 5 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
@ -7,52 +7,5 @@ LL | type Bar = impl Baz<Self, Self>;
|
||||
= note: closure with signature `fn(&'2 X) -> &X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
|
||||
= note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-57611-trait-alias.rs:20:16
|
||||
|
|
||||
LL | type Bar = impl Baz<Self, Self>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
||||
|
|
||||
= note: expected type `for<'r> Fn<(&'r X,)>`
|
||||
found type `Fn<(&'<empty> X,)>`
|
||||
note: this closure does not fulfill the lifetime requirements
|
||||
--> $DIR/issue-57611-trait-alias.rs:28:9
|
||||
|
|
||||
LL | |x| x
|
||||
| ^^^^^
|
||||
error: aborting due to previous error
|
||||
|
||||
error: implementation of `FnOnce` is not general enough
|
||||
--> $DIR/issue-57611-trait-alias.rs:20:16
|
||||
|
|
||||
LL | type Bar = impl Baz<Self, Self>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
||||
|
|
||||
= note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
|
||||
= note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-57611-trait-alias.rs:20:16
|
||||
|
|
||||
LL | type Bar = impl Baz<Self, Self>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
||||
|
|
||||
= note: expected type `for<'r> Fn<(&'r X,)>`
|
||||
found type `Fn<(&'<empty> X,)>`
|
||||
note: this closure does not fulfill the lifetime requirements
|
||||
--> $DIR/issue-57611-trait-alias.rs:28:9
|
||||
|
|
||||
LL | |x| x
|
||||
| ^^^^^
|
||||
|
||||
error: implementation of `FnOnce` is not general enough
|
||||
--> $DIR/issue-57611-trait-alias.rs:20:16
|
||||
|
|
||||
LL | type Bar = impl Baz<Self, Self>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
||||
|
|
||||
= note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
|
||||
= note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
@ -19,10 +19,6 @@ struct X;
|
||||
impl Foo for X {
|
||||
type Bar = impl Baz<Self, Self>;
|
||||
//~^ ERROR implementation of `FnOnce` is not general enough
|
||||
//~| ERROR implementation of `FnOnce` is not general enough
|
||||
//~| ERROR implementation of `FnOnce` is not general enough
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR mismatched types
|
||||
|
||||
fn bar(&self) -> Self::Bar {
|
||||
|x| x
|
||||
|
@ -9,7 +9,6 @@ trait Bug {
|
||||
impl Bug for &() {
|
||||
type Item = impl Bug; //~ ERROR `impl Trait` in type aliases is unstable
|
||||
//~^ ERROR the trait bound `(): Bug` is not satisfied
|
||||
//~^^ ERROR the trait bound `(): Bug` is not satisfied
|
||||
|
||||
const FUN: fn() -> Self::Item = || ();
|
||||
//~^ ERROR type alias impl trait is not permitted here
|
||||
|
@ -8,7 +8,7 @@ LL | type Item = impl Bug;
|
||||
= help: add `#![feature(min_type_alias_impl_trait)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: type alias impl trait is not permitted here
|
||||
--> $DIR/issue-60371.rs:14:40
|
||||
--> $DIR/issue-60371.rs:13:40
|
||||
|
|
||||
LL | const FUN: fn() -> Self::Item = || ();
|
||||
| ^
|
||||
@ -25,16 +25,7 @@ LL | type Item = impl Bug;
|
||||
= help: the following implementations were found:
|
||||
<&() as Bug>
|
||||
|
||||
error[E0277]: the trait bound `(): Bug` is not satisfied
|
||||
--> $DIR/issue-60371.rs:10:17
|
||||
|
|
||||
LL | type Item = impl Bug;
|
||||
| ^^^^^^^^ the trait `Bug` is not implemented for `()`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<&() as Bug>
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0658.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
19
src/test/ui/type-alias-impl-trait/issue-74761-2.rs
Normal file
19
src/test/ui/type-alias-impl-trait/issue-74761-2.rs
Normal file
@ -0,0 +1,19 @@
|
||||
#![feature(member_constraints)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
//~^ WARN incomplete
|
||||
|
||||
pub trait A {
|
||||
type B;
|
||||
fn f(&self) -> Self::B;
|
||||
}
|
||||
impl<'a, 'b> A for () {
|
||||
//~^ ERROR the lifetime parameter `'a` is not constrained
|
||||
//~| ERROR the lifetime parameter `'b` is not constrained
|
||||
type B = impl core::fmt::Debug;
|
||||
//~^ ERROR is unstable
|
||||
|
||||
|
||||
fn f(&self) -> Self::B {}
|
||||
}
|
||||
|
||||
fn main() {}
|
34
src/test/ui/type-alias-impl-trait/issue-74761-2.stderr
Normal file
34
src/test/ui/type-alias-impl-trait/issue-74761-2.stderr
Normal file
@ -0,0 +1,34 @@
|
||||
error[E0658]: `impl Trait` in type aliases is unstable
|
||||
--> $DIR/issue-74761-2.rs:12:14
|
||||
|
|
||||
LL | type B = impl core::fmt::Debug;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
|
||||
= help: add `#![feature(min_type_alias_impl_trait)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/issue-74761-2.rs:2:12
|
||||
|
|
||||
LL | #![feature(type_alias_impl_trait)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
|
||||
|
||||
error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
|
||||
--> $DIR/issue-74761-2.rs:9:6
|
||||
|
|
||||
LL | impl<'a, 'b> A for () {
|
||||
| ^^ unconstrained lifetime parameter
|
||||
|
||||
error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates
|
||||
--> $DIR/issue-74761-2.rs:9:10
|
||||
|
|
||||
LL | impl<'a, 'b> A for () {
|
||||
| ^^ unconstrained lifetime parameter
|
||||
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0207, E0658.
|
||||
For more information about an error, try `rustc --explain E0207`.
|
@ -5,9 +5,9 @@
|
||||
#![feature(min_type_alias_impl_trait)]
|
||||
|
||||
type X<A: ToString + Clone, B: ToString + Clone> = impl ToString;
|
||||
//~^ ERROR could not find defining uses
|
||||
|
||||
fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
|
||||
//~^ ERROR concrete type differs from previous defining opaque type
|
||||
(a.clone(), a)
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,14 @@
|
||||
error: could not find defining uses
|
||||
--> $DIR/multiple-def-uses-in-one-fn2.rs:7:52
|
||||
error: concrete type differs from previous defining opaque type use
|
||||
--> $DIR/multiple-def-uses-in-one-fn2.rs:9:1
|
||||
|
|
||||
LL | type X<A: ToString + Clone, B: ToString + Clone> = impl ToString;
|
||||
| ^^^^^^^^^^^^^
|
||||
LL | fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `A`, got `B`
|
||||
|
|
||||
note: previous use here
|
||||
--> $DIR/multiple-def-uses-in-one-fn2.rs:9:1
|
||||
|
|
||||
LL | fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -11,6 +11,7 @@ fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>)
|
||||
}
|
||||
|
||||
fn g<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) {
|
||||
//~^ ERROR concrete type differs from previous defining opaque type
|
||||
(a, b)
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/multiple-def-uses-in-one-fn3.rs:14:9
|
||||
--> $DIR/multiple-def-uses-in-one-fn3.rs:15:9
|
||||
|
|
||||
LL | fn g<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) {
|
||||
| - - found type parameter
|
||||
| |
|
||||
| expected type parameter
|
||||
LL |
|
||||
LL | (a, b)
|
||||
| ^ expected type parameter `A`, found type parameter `B`
|
||||
|
|
||||
@ -13,6 +14,18 @@ LL | (a, b)
|
||||
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
|
||||
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
|
||||
|
||||
error: aborting due to previous error
|
||||
error: concrete type differs from previous defining opaque type use
|
||||
--> $DIR/multiple-def-uses-in-one-fn3.rs:13:1
|
||||
|
|
||||
LL | fn g<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `A`, got `[type error]`
|
||||
|
|
||||
note: previous use here
|
||||
--> $DIR/multiple-def-uses-in-one-fn3.rs:9:1
|
||||
|
|
||||
LL | fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
Loading…
Reference in New Issue
Block a user