about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2023-10-30 15:54:08 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2023-10-30 16:11:52 +0000
commitff3a818554a26c56c1ad0381307eed938b5bbbc5 (patch)
treec7acd686cc3b0cbfedd562117f7fa8355b8938b3
parent6d1fc53cf4f61b0dce5fc84cebae3b9fb8a45436 (diff)
downloadrust-ff3a818554a26c56c1ad0381307eed938b5bbbc5.tar.gz
rust-ff3a818554a26c56c1ad0381307eed938b5bbbc5.zip
Poison check_well_formed if method receivers are invalid to prevent typeck from running on it
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs35
-rw-r--r--tests/ui/self/arbitrary-self-from-method-substs.default.stderr13
-rw-r--r--tests/ui/self/arbitrary-self-from-method-substs.feature.stderr (renamed from tests/ui/self/arbitrary-self-from-method-substs.stderr)2
-rw-r--r--tests/ui/self/arbitrary-self-from-method-substs.rs8
4 files changed, 41 insertions, 17 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 3f31ce7aa58..046983e90f7 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -94,7 +94,7 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
     f: F,
 ) -> Result<(), ErrorGuaranteed>
 where
-    F: for<'a> FnOnce(&WfCheckingCtxt<'a, 'tcx>),
+    F: for<'a> FnOnce(&WfCheckingCtxt<'a, 'tcx>) -> Result<(), ErrorGuaranteed>,
 {
     let param_env = tcx.param_env(body_def_id);
     let infcx = &tcx.infer_ctxt().build();
@@ -105,7 +105,7 @@ where
     if !tcx.features().trivial_bounds {
         wfcx.check_false_global_bounds()
     }
-    f(&mut wfcx);
+    f(&mut wfcx)?;
 
     let assumed_wf_types = wfcx.ocx.assumed_wf_types_and_report_errors(param_env, body_def_id)?;
 
@@ -875,6 +875,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
                         ty,
                         trait_def_id,
                     );
+                    Ok(())
                 })
             } else {
                 let mut diag = match ty.kind() {
@@ -961,6 +962,7 @@ fn check_associated_item(
                 let ty = tcx.type_of(item.def_id).instantiate_identity();
                 let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
                 wfcx.register_wf_obligation(span, loc, ty.into());
+                Ok(())
             }
             ty::AssocKind::Fn => {
                 let sig = tcx.fn_sig(item.def_id).instantiate_identity();
@@ -972,7 +974,7 @@ fn check_associated_item(
                     hir_sig.decl,
                     item.def_id.expect_local(),
                 );
-                check_method_receiver(wfcx, hir_sig, item, self_ty);
+                check_method_receiver(wfcx, hir_sig, item, self_ty)
             }
             ty::AssocKind::Type => {
                 if let ty::AssocItemContainer::TraitContainer = item.container {
@@ -983,6 +985,7 @@ fn check_associated_item(
                     let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
                     wfcx.register_wf_obligation(span, loc, ty.into());
                 }
+                Ok(())
             }
         }
     })
@@ -1097,6 +1100,7 @@ fn check_type_defn<'tcx>(
         }
 
         check_where_clauses(wfcx, item.span, item.owner_id.def_id);
+        Ok(())
     })
 }
 
@@ -1121,7 +1125,8 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) -> Result<(), ErrorGuarant
     }
 
     let res = enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| {
-        check_where_clauses(wfcx, item.span, def_id)
+        check_where_clauses(wfcx, item.span, def_id);
+        Ok(())
     });
 
     // Only check traits, don't check trait aliases
@@ -1164,6 +1169,7 @@ fn check_item_fn(
     enter_wf_checking_ctxt(tcx, span, def_id, |wfcx| {
         let sig = tcx.fn_sig(def_id).instantiate_identity();
         check_fn_or_method(wfcx, ident.span, sig, decl, def_id);
+        Ok(())
     })
 }
 
@@ -1218,6 +1224,7 @@ fn check_item_type(
                 tcx.require_lang_item(LangItem::Sync, Some(ty_span)),
             );
         }
+        Ok(())
     })
 }
 
@@ -1276,6 +1283,7 @@ fn check_impl<'tcx>(
         }
 
         check_where_clauses(wfcx, item.span, item.owner_id.def_id);
+        Ok(())
     })
 }
 
@@ -1548,11 +1556,11 @@ fn check_method_receiver<'tcx>(
     fn_sig: &hir::FnSig<'_>,
     method: ty::AssocItem,
     self_ty: Ty<'tcx>,
-) {
+) -> Result<(), ErrorGuaranteed> {
     let tcx = wfcx.tcx();
 
     if !method.fn_has_self_parameter {
-        return;
+        return Ok(());
     }
 
     let span = fn_sig.decl.inputs[0].span;
@@ -1571,11 +1579,11 @@ fn check_method_receiver<'tcx>(
     if tcx.features().arbitrary_self_types {
         if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, true) {
             // Report error; `arbitrary_self_types` was enabled.
-            e0307(tcx, span, receiver_ty);
+            return Err(e0307(tcx, span, receiver_ty));
         }
     } else {
         if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, false) {
-            if receiver_is_valid(wfcx, span, receiver_ty, self_ty, true) {
+            return Err(if receiver_is_valid(wfcx, span, receiver_ty, self_ty, true) {
                 // Report error; would have worked with `arbitrary_self_types`.
                 feature_err(
                     &tcx.sess.parse_sess,
@@ -1587,16 +1595,17 @@ fn check_method_receiver<'tcx>(
                     ),
                 )
                 .help(HELP_FOR_SELF_TYPE)
-                .emit();
+                .emit()
             } else {
                 // Report error; would not have worked with `arbitrary_self_types`.
-                e0307(tcx, span, receiver_ty);
-            }
+                e0307(tcx, span, receiver_ty)
+            });
         }
     }
+    Ok(())
 }
 
-fn e0307(tcx: TyCtxt<'_>, span: Span, receiver_ty: Ty<'_>) {
+fn e0307(tcx: TyCtxt<'_>, span: Span, receiver_ty: Ty<'_>) -> ErrorGuaranteed {
     struct_span_err!(
         tcx.sess.diagnostic(),
         span,
@@ -1605,7 +1614,7 @@ fn e0307(tcx: TyCtxt<'_>, span: Span, receiver_ty: Ty<'_>) {
     )
     .note("type of `self` must be `Self` or a type that dereferences to it")
     .help(HELP_FOR_SELF_TYPE)
-    .emit();
+    .emit()
 }
 
 /// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
diff --git a/tests/ui/self/arbitrary-self-from-method-substs.default.stderr b/tests/ui/self/arbitrary-self-from-method-substs.default.stderr
new file mode 100644
index 00000000000..cbf5e6c541a
--- /dev/null
+++ b/tests/ui/self/arbitrary-self-from-method-substs.default.stderr
@@ -0,0 +1,13 @@
+error[E0658]: `R` cannot be used as the type of `self` without the `arbitrary_self_types` feature
+  --> $DIR/arbitrary-self-from-method-substs.rs:8:43
+   |
+LL |     fn get<R: Deref<Target = Self>>(self: R) -> u32 {
+   |                                           ^
+   |
+   = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
+   = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
+   = 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 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/self/arbitrary-self-from-method-substs.stderr b/tests/ui/self/arbitrary-self-from-method-substs.feature.stderr
index 6c252fadf46..7378d53c373 100644
--- a/tests/ui/self/arbitrary-self-from-method-substs.stderr
+++ b/tests/ui/self/arbitrary-self-from-method-substs.feature.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/arbitrary-self-from-method-substs.rs:14:5
+  --> $DIR/arbitrary-self-from-method-substs.rs:16:5
    |
 LL |     foo.get::<&Foo>();
    |     ^^^ expected `&Foo`, found `Foo`
diff --git a/tests/ui/self/arbitrary-self-from-method-substs.rs b/tests/ui/self/arbitrary-self-from-method-substs.rs
index 0f911a20842..004445dc327 100644
--- a/tests/ui/self/arbitrary-self-from-method-substs.rs
+++ b/tests/ui/self/arbitrary-self-from-method-substs.rs
@@ -1,10 +1,12 @@
-#![feature(arbitrary_self_types)]
+// revisions: default feature
+#![cfg_attr(feature, feature(arbitrary_self_types))]
 
 use std::ops::Deref;
 
 struct Foo(u32);
 impl Foo {
-    fn get<R: Deref<Target=Self>>(self: R) -> u32 {
+    fn get<R: Deref<Target = Self>>(self: R) -> u32 {
+        //[default]~^ ERROR: `R` cannot be used as the type of `self`
         self.0
     }
 }
@@ -12,5 +14,5 @@ impl Foo {
 fn main() {
     let mut foo = Foo(1);
     foo.get::<&Foo>();
-    //~^ ERROR mismatched types
+    //[feature]~^ ERROR mismatched types
 }