about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs14
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs7
-rw-r--r--compiler/rustc_traits/src/codegen.rs11
-rw-r--r--tests/ui/traits/negative-bounds/negative-sized.rs8
-rw-r--r--tests/ui/traits/negative-bounds/negative-sized.stderr15
5 files changed, 31 insertions, 24 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs
index 18971c47831..22eeb285b37 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs
@@ -21,19 +21,9 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
 
         if let ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term)) =
             key.value.predicate.kind().skip_binder()
+            && term.is_trivially_wf(tcx)
         {
-            match term.as_type()?.kind() {
-                ty::Param(_)
-                | ty::Bool
-                | ty::Char
-                | ty::Int(_)
-                | ty::Float(_)
-                | ty::Str
-                | ty::Uint(_) => {
-                    return Some(());
-                }
-                _ => {}
-            }
+            return Some(());
         }
 
         None
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index a05bae53566..141454bfe37 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -368,16 +368,17 @@ pub fn sizedness_fast_path<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
     // Proving `Sized`/`MetaSized`, very often on "obviously sized" types like
     // `&T`, accounts for about 60% percentage of the predicates we have to prove. No need to
     // canonicalize and all that for such cases.
-    if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_ref)) =
+    if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) =
         predicate.kind().skip_binder()
+        && trait_pred.polarity == ty::PredicatePolarity::Positive
     {
-        let sizedness = match tcx.as_lang_item(trait_ref.def_id()) {
+        let sizedness = match tcx.as_lang_item(trait_pred.def_id()) {
             Some(LangItem::Sized) => SizedTraitKind::Sized,
             Some(LangItem::MetaSized) => SizedTraitKind::MetaSized,
             _ => return false,
         };
 
-        if trait_ref.self_ty().has_trivial_sizedness(tcx, sizedness) {
+        if trait_pred.self_ty().has_trivial_sizedness(tcx, sizedness) {
             debug!("fast path -- trivial sizedness");
             return true;
         }
diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs
index 9d144010561..7dd3c59edd0 100644
--- a/compiler/rustc_traits/src/codegen.rs
+++ b/compiler/rustc_traits/src/codegen.rs
@@ -6,11 +6,11 @@
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::bug;
 use rustc_middle::traits::CodegenObligationError;
-use rustc_middle::ty::{self, PseudoCanonicalInput, TyCtxt, TypeVisitableExt, Upcast};
+use rustc_middle::ty::{self, PseudoCanonicalInput, TyCtxt, TypeVisitableExt};
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
 use rustc_trait_selection::traits::{
     ImplSource, Obligation, ObligationCause, ObligationCtxt, ScrubbedTraitError, SelectionContext,
-    SelectionError, sizedness_fast_path,
+    SelectionError,
 };
 use tracing::debug;
 
@@ -34,13 +34,6 @@ pub(crate) fn codegen_select_candidate<'tcx>(
     let (infcx, param_env) = tcx.infer_ctxt().ignoring_regions().build_with_typing_env(typing_env);
     let mut selcx = SelectionContext::new(&infcx);
 
-    if sizedness_fast_path(tcx, trait_ref.upcast(tcx)) {
-        return Ok(&*tcx.arena.alloc(ImplSource::Builtin(
-            ty::solve::BuiltinImplSource::Trivial,
-            Default::default(),
-        )));
-    }
-
     let obligation_cause = ObligationCause::dummy();
     let obligation = Obligation::new(tcx, obligation_cause, param_env, trait_ref);
 
diff --git a/tests/ui/traits/negative-bounds/negative-sized.rs b/tests/ui/traits/negative-bounds/negative-sized.rs
new file mode 100644
index 00000000000..18369c78427
--- /dev/null
+++ b/tests/ui/traits/negative-bounds/negative-sized.rs
@@ -0,0 +1,8 @@
+#![feature(negative_bounds)]
+
+fn foo<T: !Sized>() {}
+
+fn main() {
+    foo::<()>();
+    //~^ ERROR the trait bound `(): !Sized` is not satisfied
+}
diff --git a/tests/ui/traits/negative-bounds/negative-sized.stderr b/tests/ui/traits/negative-bounds/negative-sized.stderr
new file mode 100644
index 00000000000..143933803b8
--- /dev/null
+++ b/tests/ui/traits/negative-bounds/negative-sized.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `(): !Sized` is not satisfied
+  --> $DIR/negative-sized.rs:6:11
+   |
+LL |     foo::<()>();
+   |           ^^ the trait bound `(): !Sized` is not satisfied
+   |
+note: required by a bound in `foo`
+  --> $DIR/negative-sized.rs:3:11
+   |
+LL | fn foo<T: !Sized>() {}
+   |           ^^^^^^ required by this bound in `foo`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.