mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
Use subtyping instead of equality, since method resolution also uses subtyping
This commit is contained in:
parent
e23ae72ac7
commit
94f549502f
@ -750,16 +750,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
/// Resolves an associated value path into a base type and associated constant, or method
|
/// Resolves an associated value path into a base type and associated constant, or method
|
||||||
/// resolution. The newly resolved definition is written into `type_dependent_defs`.
|
/// resolution. The newly resolved definition is written into `type_dependent_defs`.
|
||||||
|
#[instrument(level = "trace", skip(self), ret)]
|
||||||
pub fn resolve_ty_and_res_fully_qualified_call(
|
pub fn resolve_ty_and_res_fully_qualified_call(
|
||||||
&self,
|
&self,
|
||||||
qpath: &'tcx QPath<'tcx>,
|
qpath: &'tcx QPath<'tcx>,
|
||||||
hir_id: HirId,
|
hir_id: HirId,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> (Res, Option<LoweredTy<'tcx>>, &'tcx [hir::PathSegment<'tcx>]) {
|
) -> (Res, Option<LoweredTy<'tcx>>, &'tcx [hir::PathSegment<'tcx>]) {
|
||||||
debug!(
|
|
||||||
"resolve_ty_and_res_fully_qualified_call: qpath={:?} hir_id={:?} span={:?}",
|
|
||||||
qpath, hir_id, span
|
|
||||||
);
|
|
||||||
let (ty, qself, item_segment) = match *qpath {
|
let (ty, qself, item_segment) = match *qpath {
|
||||||
QPath::Resolved(ref opt_qself, path) => {
|
QPath::Resolved(ref opt_qself, path) => {
|
||||||
return (
|
return (
|
||||||
@ -1417,10 +1414,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// This also occurs for an enum variant on a type alias.
|
// This also occurs for an enum variant on a type alias.
|
||||||
let impl_ty = self.normalize(span, tcx.type_of(impl_def_id).instantiate(tcx, args));
|
let impl_ty = self.normalize(span, tcx.type_of(impl_def_id).instantiate(tcx, args));
|
||||||
let self_ty = self.normalize(span, self_ty);
|
let self_ty = self.normalize(span, self_ty);
|
||||||
match self.at(&self.misc(span), self.param_env).eq(
|
match self.at(&self.misc(span), self.param_env).sub(
|
||||||
DefineOpaqueTypes::Yes,
|
DefineOpaqueTypes::Yes,
|
||||||
impl_ty,
|
|
||||||
self_ty,
|
self_ty,
|
||||||
|
impl_ty,
|
||||||
) {
|
) {
|
||||||
Ok(ok) => self.register_infer_ok_obligations(ok),
|
Ok(ok) => self.register_infer_ok_obligations(ok),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
//@ known-bug: rust-lang/rust#126062
|
|
||||||
struct Fail<T>(Fail);
|
|
||||||
impl<T> Fail<i32> {
|
|
||||||
const C: () = panic!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn f<T>() {
|
|
||||||
if false {
|
|
||||||
let _val = &Fail::<T>::C;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,10 @@
|
|||||||
|
struct Fail<T>;
|
||||||
|
//~^ ERROR: type parameter `T` is never used
|
||||||
|
|
||||||
|
impl Fail<i32> {
|
||||||
|
const C: () = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
Fail::<()>::C
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
error[E0392]: type parameter `T` is never used
|
||||||
|
--> $DIR/wrong-projection-self-ty-invalid-bivariant-arg.rs:1:13
|
||||||
|
|
|
||||||
|
LL | struct Fail<T>;
|
||||||
|
| ^ unused type parameter
|
||||||
|
|
|
||||||
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
|
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0392`.
|
@ -0,0 +1,17 @@
|
|||||||
|
trait Proj {
|
||||||
|
type Assoc;
|
||||||
|
}
|
||||||
|
impl<T> Proj for T {
|
||||||
|
type Assoc = T;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Fail<T: Proj<Assoc = U>, U>(T);
|
||||||
|
|
||||||
|
impl Fail<i32, i32> {
|
||||||
|
const C: () = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
Fail::<i32, u32>::C
|
||||||
|
//~^ ERROR: type mismatch
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
error[E0271]: type mismatch resolving `<i32 as Proj>::Assoc == u32`
|
||||||
|
--> $DIR/wrong-projection-self-ty-invalid-bivariant-arg2.rs:15:5
|
||||||
|
|
|
||||||
|
LL | Fail::<i32, u32>::C
|
||||||
|
| ^^^^^^^^^^^^^^^^ type mismatch resolving `<i32 as Proj>::Assoc == u32`
|
||||||
|
|
|
||||||
|
note: expected this to be `u32`
|
||||||
|
--> $DIR/wrong-projection-self-ty-invalid-bivariant-arg2.rs:5:18
|
||||||
|
|
|
||||||
|
LL | type Assoc = T;
|
||||||
|
| ^
|
||||||
|
note: required by a bound in `Fail`
|
||||||
|
--> $DIR/wrong-projection-self-ty-invalid-bivariant-arg2.rs:8:21
|
||||||
|
|
|
||||||
|
LL | struct Fail<T: Proj<Assoc = U>, U>(T);
|
||||||
|
| ^^^^^^^^^ required by this bound in `Fail`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0271`.
|
@ -0,0 +1,11 @@
|
|||||||
|
error[E0277]: the trait bound `(): std::error::Error` is not satisfied
|
||||||
|
--> $DIR/coerce-issue-49593-box-never.rs:19:5
|
||||||
|
|
|
||||||
|
LL | Box::<_ /* ! */>::new(x)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
|
||||||
|
|
|
||||||
|
= note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
@ -1,13 +1,13 @@
|
|||||||
error[E0277]: the trait bound `(): std::error::Error` is not satisfied
|
error[E0277]: the trait bound `(): std::error::Error` is not satisfied
|
||||||
--> $DIR/coerce-issue-49593-box-never.rs:18:53
|
--> $DIR/coerce-issue-49593-box-never.rs:19:5
|
||||||
|
|
|
|
||||||
LL | /* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x)
|
LL | Box::<_ /* ! */>::new(x)
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
|
||||||
|
|
|
|
||||||
= note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>`
|
= note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>`
|
||||||
|
|
||||||
error[E0277]: the trait bound `(): std::error::Error` is not satisfied
|
error[E0277]: the trait bound `(): std::error::Error` is not satisfied
|
||||||
--> $DIR/coerce-issue-49593-box-never.rs:23:49
|
--> $DIR/coerce-issue-49593-box-never.rs:24:49
|
||||||
|
|
|
|
||||||
LL | /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x)
|
LL | /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x)
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
//@ revisions: nofallback fallback
|
//@ revisions: nofallback fallback
|
||||||
//@ ignore-windows - the number of `Error` impls is platform-dependent
|
//@ ignore-windows - the number of `Error` impls is platform-dependent
|
||||||
//@[fallback] check-pass
|
//@check-fail
|
||||||
//@[nofallback] check-fail
|
|
||||||
|
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![cfg_attr(fallback, feature(never_type_fallback))]
|
#![cfg_attr(fallback, feature(never_type_fallback))]
|
||||||
@ -15,8 +14,10 @@ fn raw_ptr_box<T>(t: T) -> *mut T {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn foo(x: !) -> Box<dyn Error> {
|
fn foo(x: !) -> Box<dyn Error> {
|
||||||
/* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x)
|
// Subtyping during method resolution will generate new inference vars and
|
||||||
//[nofallback]~^ ERROR trait bound `(): std::error::Error` is not satisfied
|
// subtype them. Thus fallback will not fall back to `!`, but `()` instead.
|
||||||
|
Box::<_ /* ! */>::new(x)
|
||||||
|
//~^ ERROR trait bound `(): std::error::Error` is not satisfied
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo_raw_ptr(x: !) -> *mut dyn Error {
|
fn foo_raw_ptr(x: !) -> *mut dyn Error {
|
||||||
|
@ -15,7 +15,7 @@ note: required by a bound in `Mask::<T, N>::splat`
|
|||||||
--> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL
|
--> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL
|
||||||
help: consider giving `y` an explicit type, where the type for type parameter `T` is specified
|
help: consider giving `y` an explicit type, where the type for type parameter `T` is specified
|
||||||
|
|
|
|
||||||
LL | let y: Mask<_, N> = Mask::<_, _>::splat(false);
|
LL | let y: Mask<T, N> = Mask::<_, _>::splat(false);
|
||||||
| ++++++++++++
|
| ++++++++++++
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
@ -2,7 +2,7 @@ error[E0282]: type annotations needed
|
|||||||
--> $DIR/type-alias-indirect.rs:14:5
|
--> $DIR/type-alias-indirect.rs:14:5
|
||||||
|
|
|
|
||||||
LL | IndirectAlias::new();
|
LL | IndirectAlias::new();
|
||||||
| ^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias`
|
| ^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
@ -2,19 +2,19 @@ error[E0282]: type annotations needed
|
|||||||
--> $DIR/type-alias.rs:12:5
|
--> $DIR/type-alias.rs:12:5
|
||||||
|
|
|
|
||||||
LL | DirectAlias::new()
|
LL | DirectAlias::new()
|
||||||
| ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
|
| ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `DirectAlias`
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
error[E0282]: type annotations needed
|
||||||
--> $DIR/type-alias.rs:18:5
|
--> $DIR/type-alias.rs:18:5
|
||||||
|
|
|
|
||||||
LL | IndirectAlias::new();
|
LL | IndirectAlias::new();
|
||||||
| ^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias`
|
| ^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias`
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
error[E0282]: type annotations needed
|
||||||
--> $DIR/type-alias.rs:32:5
|
--> $DIR/type-alias.rs:32:5
|
||||||
|
|
|
|
||||||
LL | DirectButWithDefaultAlias::new();
|
LL | DirectButWithDefaultAlias::new();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `DirectButWithDefaultAlias`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ fn main() {
|
|||||||
let fp = BufWriter::new(fp);
|
let fp = BufWriter::new(fp);
|
||||||
//~^ ERROR the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
|
//~^ ERROR the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
|
||||||
//~| ERROR the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
|
//~| ERROR the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
|
||||||
|
//~| ERROR the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
|
||||||
|
|
||||||
writeln!(fp, "hello world").unwrap(); //~ ERROR the method
|
writeln!(fp, "hello world").unwrap(); //~ ERROR the method
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,16 @@ LL | let fp = BufWriter::new(fp);
|
|||||||
note: required by a bound in `BufWriter::<W>::new`
|
note: required by a bound in `BufWriter::<W>::new`
|
||||||
--> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL
|
--> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
|
||||||
|
--> $DIR/mut-borrow-needed-by-trait.rs:17:14
|
||||||
|
|
|
||||||
|
LL | let fp = BufWriter::new(fp);
|
||||||
|
| ^^^^^^^^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write`
|
||||||
|
|
|
||||||
|
= note: `std::io::Write` is implemented for `&mut dyn std::io::Write`, but not for `&dyn std::io::Write`
|
||||||
|
note: required by a bound in `BufWriter`
|
||||||
|
--> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL
|
||||||
|
|
||||||
error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
|
error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
|
||||||
--> $DIR/mut-borrow-needed-by-trait.rs:17:14
|
--> $DIR/mut-borrow-needed-by-trait.rs:17:14
|
||||||
|
|
|
|
||||||
@ -21,13 +31,13 @@ note: required by a bound in `BufWriter`
|
|||||||
--> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL
|
--> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL
|
||||||
|
|
||||||
error[E0599]: the method `write_fmt` exists for struct `BufWriter<&dyn Write>`, but its trait bounds were not satisfied
|
error[E0599]: the method `write_fmt` exists for struct `BufWriter<&dyn Write>`, but its trait bounds were not satisfied
|
||||||
--> $DIR/mut-borrow-needed-by-trait.rs:21:14
|
--> $DIR/mut-borrow-needed-by-trait.rs:22:14
|
||||||
|
|
|
|
||||||
LL | writeln!(fp, "hello world").unwrap();
|
LL | writeln!(fp, "hello world").unwrap();
|
||||||
| ---------^^---------------- method cannot be called on `BufWriter<&dyn Write>` due to unsatisfied trait bounds
|
| ---------^^---------------- method cannot be called on `BufWriter<&dyn Write>` due to unsatisfied trait bounds
|
||||||
|
|
|
|
||||||
note: must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method
|
note: must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method
|
||||||
--> $DIR/mut-borrow-needed-by-trait.rs:21:14
|
--> $DIR/mut-borrow-needed-by-trait.rs:22:14
|
||||||
|
|
|
|
||||||
LL | writeln!(fp, "hello world").unwrap();
|
LL | writeln!(fp, "hello world").unwrap();
|
||||||
| ^^
|
| ^^
|
||||||
@ -35,7 +45,7 @@ LL | writeln!(fp, "hello world").unwrap();
|
|||||||
`&dyn std::io::Write: std::io::Write`
|
`&dyn std::io::Write: std::io::Write`
|
||||||
which is required by `BufWriter<&dyn std::io::Write>: std::io::Write`
|
which is required by `BufWriter<&dyn std::io::Write>: std::io::Write`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0599.
|
Some errors have detailed explanations: E0277, E0599.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
Loading…
Reference in New Issue
Block a user