about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-08-25 18:07:00 +0000
committerMichael Goulet <michael@errs.io>2023-08-25 19:05:38 +0000
commit055452864e7fbb0cf15864160087d10030dc7260 (patch)
tree8381cf1e8193e73881fc5ac7d3fb5cb0343d84c0
parent296c7a683cb7faafea3dd6905860cdeeae13598e (diff)
downloadrust-055452864e7fbb0cf15864160087d10030dc7260.tar.gz
rust-055452864e7fbb0cf15864160087d10030dc7260.zip
Walk through full path in point_at_path_if_possible
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs52
-rw-r--r--tests/ui/const-generics/exhaustive-value.stderr4
-rw-r--r--tests/ui/generic-const-items/unsatisfied-bounds.stderr4
-rw-r--r--tests/ui/trait-bounds/enum-unit-variant-trait-bound.rs6
-rw-r--r--tests/ui/trait-bounds/enum-unit-variant-trait-bound.stderr13
-rw-r--r--tests/ui/traits/suggest-where-clause.stderr12
6 files changed, 57 insertions, 34 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
index c44d12e61e3..1861f141eed 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
@@ -1,6 +1,6 @@
 use crate::FnCtxt;
 use rustc_hir as hir;
-use rustc_hir::def::Res;
+use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_infer::{infer::type_variable::TypeVariableOriginKind, traits::ObligationCauseCode};
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
@@ -133,15 +133,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
                     }
                 }
-                // Notably, we only point to params that are local to the
-                // item we're checking, since those are the ones we are able
-                // to look in the final `hir::PathSegment` for. Everything else
-                // would require a deeper search into the `qpath` than I think
-                // is worthwhile.
-                if let Some(param_to_point_at) = param_to_point_at
-                    && self.point_at_path_if_possible(error, def_id, param_to_point_at, qpath)
+
+                for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
+                    .into_iter()
+                    .flatten()
                 {
-                    return true;
+                    if self.point_at_path_if_possible(error, def_id, param, qpath) {
+                        return true;
+                    }
                 }
             }
             hir::ExprKind::MethodCall(segment, receiver, args, ..) => {
@@ -168,10 +167,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
             }
             hir::ExprKind::Struct(qpath, fields, ..) => {
-                if let Res::Def(
-                    hir::def::DefKind::Struct | hir::def::DefKind::Variant,
-                    variant_def_id,
-                ) = self.typeck_results.borrow().qpath_res(qpath, hir_id)
+                if let Res::Def(DefKind::Struct | DefKind::Variant, variant_def_id) =
+                    self.typeck_results.borrow().qpath_res(qpath, hir_id)
                 {
                     for param in
                         [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
@@ -193,10 +190,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
                     }
                 }
-                if let Some(param_to_point_at) = param_to_point_at
-                    && self.point_at_path_if_possible(error, def_id, param_to_point_at, qpath)
+
+                for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
+                    .into_iter()
+                    .flatten()
                 {
-                    return true;
+                    if self.point_at_path_if_possible(error, def_id, param, qpath) {
+                        return true;
+                    }
                 }
             }
             _ => {}
@@ -214,10 +215,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) -> bool {
         match qpath {
             hir::QPath::Resolved(_, path) => {
-                if let Some(segment) = path.segments.last()
-                    && self.point_at_generic_if_possible(error, def_id, param, segment)
-                {
-                    return true;
+                for segment in path.segments.iter().rev() {
+                    if let Res::Def(kind, def_id) = segment.res
+                        && !matches!(kind, DefKind::Mod | DefKind::ForeignMod)
+                        && self.point_at_generic_if_possible(error, def_id, param, segment)
+                    {
+                        return true;
+                    }
                 }
             }
             hir::QPath::TypeRelative(_, segment) => {
@@ -618,14 +622,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             };
 
             let variant_def_id = match expr_struct_def_kind {
-                hir::def::DefKind::Struct => {
+                DefKind::Struct => {
                     if in_ty_adt.did() != expr_struct_def_id {
                         // FIXME: Deal with type aliases?
                         return Err(expr);
                     }
                     expr_struct_def_id
                 }
-                hir::def::DefKind::Variant => {
+                DefKind::Variant => {
                     // If this is a variant, its parent is the type definition.
                     if in_ty_adt.did() != self.tcx.parent(expr_struct_def_id) {
                         // FIXME: Deal with type aliases?
@@ -727,14 +731,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             };
 
             let variant_def_id = match expr_struct_def_kind {
-                hir::def::DefKind::Ctor(hir::def::CtorOf::Struct, hir::def::CtorKind::Fn) => {
+                DefKind::Ctor(hir::def::CtorOf::Struct, hir::def::CtorKind::Fn) => {
                     if in_ty_adt.did() != self.tcx.parent(expr_ctor_def_id) {
                         // FIXME: Deal with type aliases?
                         return Err(expr);
                     }
                     self.tcx.parent(expr_ctor_def_id)
                 }
-                hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, hir::def::CtorKind::Fn) => {
+                DefKind::Ctor(hir::def::CtorOf::Variant, hir::def::CtorKind::Fn) => {
                     // For a typical enum like
                     // `enum Blah<T> { Variant(T) }`
                     // we get the following resolutions:
diff --git a/tests/ui/const-generics/exhaustive-value.stderr b/tests/ui/const-generics/exhaustive-value.stderr
index 4a26e09772d..0828f7896dc 100644
--- a/tests/ui/const-generics/exhaustive-value.stderr
+++ b/tests/ui/const-generics/exhaustive-value.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `(): Foo<N>` is not satisfied
-  --> $DIR/exhaustive-value.rs:262:5
+  --> $DIR/exhaustive-value.rs:262:16
    |
 LL |     <() as Foo<N>>::test()
-   |     ^^^^^^^^^^^^^^^^^^^^ the trait `Foo<N>` is not implemented for `()`
+   |                ^ the trait `Foo<N>` is not implemented for `()`
    |
    = help: the following other types implement trait `Foo<N>`:
              <() as Foo<0>>
diff --git a/tests/ui/generic-const-items/unsatisfied-bounds.stderr b/tests/ui/generic-const-items/unsatisfied-bounds.stderr
index 1fda460372a..2cee53431a4 100644
--- a/tests/ui/generic-const-items/unsatisfied-bounds.stderr
+++ b/tests/ui/generic-const-items/unsatisfied-bounds.stderr
@@ -27,10 +27,10 @@ LL |     Infallible: From<T>;
    |                 ^^^^^^^ required by this bound in `K`
 
 error[E0277]: the trait bound `Vec<u8>: Copy` is not satisfied
-  --> $DIR/unsatisfied-bounds.rs:32:13
+  --> $DIR/unsatisfied-bounds.rs:32:26
    |
 LL |     let _ = <() as Trait<Vec<u8>>>::A;
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Vec<u8>`
+   |                          ^^^^^^^ the trait `Copy` is not implemented for `Vec<u8>`
    |
 note: required by a bound in `Trait::A`
   --> $DIR/unsatisfied-bounds.rs:17:12
diff --git a/tests/ui/trait-bounds/enum-unit-variant-trait-bound.rs b/tests/ui/trait-bounds/enum-unit-variant-trait-bound.rs
new file mode 100644
index 00000000000..91525bc90c4
--- /dev/null
+++ b/tests/ui/trait-bounds/enum-unit-variant-trait-bound.rs
@@ -0,0 +1,6 @@
+// Regression test for one part of issue #105306.
+
+fn main() {
+    let _ = Option::<[u8]>::None;
+    //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
+}
diff --git a/tests/ui/trait-bounds/enum-unit-variant-trait-bound.stderr b/tests/ui/trait-bounds/enum-unit-variant-trait-bound.stderr
new file mode 100644
index 00000000000..32f6b00b20c
--- /dev/null
+++ b/tests/ui/trait-bounds/enum-unit-variant-trait-bound.stderr
@@ -0,0 +1,13 @@
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/enum-unit-variant-trait-bound.rs:4:22
+   |
+LL |     let _ = Option::<[u8]>::None;
+   |                      ^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+note: required by a bound in `None`
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/suggest-where-clause.stderr b/tests/ui/traits/suggest-where-clause.stderr
index f3a4c689033..5a539884873 100644
--- a/tests/ui/traits/suggest-where-clause.stderr
+++ b/tests/ui/traits/suggest-where-clause.stderr
@@ -38,10 +38,10 @@ LL + fn check<T: Iterator, U>() {
    |
 
 error[E0277]: the trait bound `u64: From<T>` is not satisfied
-  --> $DIR/suggest-where-clause.rs:15:5
+  --> $DIR/suggest-where-clause.rs:15:18
    |
 LL |     <u64 as From<T>>::from;
-   |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `From<T>` is not implemented for `u64`
+   |                  ^ the trait `From<T>` is not implemented for `u64`
    |
 help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
    |
@@ -49,10 +49,10 @@ LL | fn check<T: Iterator, U: ?Sized>() where u64: From<T> {
    |                                    ++++++++++++++++++
 
 error[E0277]: the trait bound `u64: From<<T as Iterator>::Item>` is not satisfied
-  --> $DIR/suggest-where-clause.rs:18:5
+  --> $DIR/suggest-where-clause.rs:18:18
    |
 LL |     <u64 as From<<T as Iterator>::Item>>::from;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<<T as Iterator>::Item>` is not implemented for `u64`
+   |                  ^^^^^^^^^^^^^^^^^^^^^ the trait `From<<T as Iterator>::Item>` is not implemented for `u64`
    |
 help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
    |
@@ -60,10 +60,10 @@ LL | fn check<T: Iterator, U: ?Sized>() where u64: From<<T as Iterator>::Item> {
    |                                    ++++++++++++++++++++++++++++++++++++++
 
 error[E0277]: the trait bound `Misc<_>: From<T>` is not satisfied
-  --> $DIR/suggest-where-clause.rs:23:5
+  --> $DIR/suggest-where-clause.rs:23:22
    |
 LL |     <Misc<_> as From<T>>::from;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<T>` is not implemented for `Misc<_>`
+   |                      ^ the trait `From<T>` is not implemented for `Misc<_>`
 
 error[E0277]: the size for values of type `[T]` cannot be known at compilation time
   --> $DIR/suggest-where-clause.rs:28:20