about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs4
-rw-r--r--compiler/rustc_error_messages/locales/en-US/metadata.ftl2
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs20
-rw-r--r--compiler/rustc_hir_analysis/src/check/expr.rs12
-rw-r--r--compiler/rustc_metadata/src/errors.rs36
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs2
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs4
-rw-r--r--compiler/rustc_resolve/src/late.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs29
-rw-r--r--library/std/src/sys/unix/thread.rs10
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version2
-rw-r--r--src/librustdoc/clean/mod.rs3
-rw-r--r--src/test/rustdoc-gui/unsafe-fn.goml53
-rw-r--r--src/test/rustdoc-ui/issue-102986.rs4
-rw-r--r--src/test/rustdoc-ui/issue-102986.stderr14
-rw-r--r--src/test/ui/native-library-link-flags/suggest-libname-only-1.rs9
-rw-r--r--src/test/ui/native-library-link-flags/suggest-libname-only-1.stderr6
-rw-r--r--src/test/ui/native-library-link-flags/suggest-libname-only-2.rs9
-rw-r--r--src/test/ui/native-library-link-flags/suggest-libname-only-2.stderr6
-rw-r--r--src/test/ui/object-safety/issue-102933.rs25
-rw-r--r--src/test/ui/resolve/issue-102946.rs7
-rw-r--r--src/test/ui/resolve/issue-102946.stderr26
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/issue-102985.rs11
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/issue-102985.stderr26
-rw-r--r--src/test/ui/type-alias-impl-trait/closure_parent_substs.rs65
-rw-r--r--src/test/ui/type-alias-impl-trait/closure_wf_outlives.rs65
-rw-r--r--src/test/ui/type-alias-impl-trait/closure_wf_outlives.stderr64
-rw-r--r--src/test/ui/type/type-check/assignment-in-if.rs6
-rw-r--r--src/test/ui/type/type-check/assignment-in-if.stderr19
29 files changed, 483 insertions, 58 deletions
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 80ca412b32a..22a61774e8c 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -909,8 +909,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                     return;
                 }
 
-                let is_intrinsic = tcx.is_intrinsic(callee);
-
                 if !tcx.is_const_fn_raw(callee) {
                     if !tcx.is_const_default_method(callee) {
                         // To get to here we must have already found a const impl for the
@@ -970,7 +968,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                     // We do not use `const` modifiers for intrinsic "functions", as intrinsics are
                     // `extern` functions, and these have no way to get marked `const`. So instead we
                     // use `rustc_const_(un)stable` attributes to mean that the intrinsic is `const`
-                    if self.ccx.is_const_stable_const_fn() || is_intrinsic {
+                    if self.ccx.is_const_stable_const_fn() || tcx.is_intrinsic(callee) {
                         self.check_op(ops::FnCallUnstable(callee, None));
                         return;
                     }
diff --git a/compiler/rustc_error_messages/locales/en-US/metadata.ftl b/compiler/rustc_error_messages/locales/en-US/metadata.ftl
index d27100c56af..08e553d9f15 100644
--- a/compiler/rustc_error_messages/locales/en-US/metadata.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/metadata.ftl
@@ -165,6 +165,8 @@ metadata_failed_write_error =
 metadata_missing_native_library =
     could not find native static library `{$libname}`, perhaps an -L flag is missing?
 
+metadata_only_provide_library_name = only provide the library name `{$suggested_name}`, not the full filename
+
 metadata_failed_create_tempdir =
     couldn't create a temp dir: {$err}
 
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 7cee9779c5f..c3583eeb430 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -732,8 +732,6 @@ fn check_opaque_meets_bounds<'tcx>(
     span: Span,
     origin: &hir::OpaqueTyOrigin,
 ) {
-    let hidden_type = tcx.bound_type_of(def_id.to_def_id()).subst(tcx, substs);
-
     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
     let defining_use_anchor = match *origin {
         hir::OpaqueTyOrigin::FnReturn(did) | hir::OpaqueTyOrigin::AsyncFn(did) => did,
@@ -748,14 +746,26 @@ fn check_opaque_meets_bounds<'tcx>(
     let ocx = ObligationCtxt::new(&infcx);
     let opaque_ty = tcx.mk_opaque(def_id.to_def_id(), substs);
 
+    // `ReErased` regions appear in the "parent_substs" of closures/generators.
+    // We're ignoring them here and replacing them with fresh region variables.
+    // See tests in ui/type-alias-impl-trait/closure_{parent_substs,wf_outlives}.rs.
+    //
+    // FIXME: Consider wrapping the hidden type in an existential `Binder` and instantiating it
+    // here rather than using ReErased.
+    let hidden_ty = tcx.bound_type_of(def_id.to_def_id()).subst(tcx, substs);
+    let hidden_ty = tcx.fold_regions(hidden_ty, |re, _dbi| match re.kind() {
+        ty::ReErased => infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)),
+        _ => re,
+    });
+
     let misc_cause = traits::ObligationCause::misc(span, hir_id);
 
-    match infcx.at(&misc_cause, param_env).eq(opaque_ty, hidden_type) {
+    match infcx.at(&misc_cause, param_env).eq(opaque_ty, hidden_ty) {
         Ok(infer_ok) => ocx.register_infer_ok_obligations(infer_ok),
         Err(ty_err) => {
             tcx.sess.delay_span_bug(
                 span,
-                &format!("could not unify `{hidden_type}` with revealed type:\n{ty_err}"),
+                &format!("could not unify `{hidden_ty}` with revealed type:\n{ty_err}"),
             );
         }
     }
@@ -764,7 +774,7 @@ fn check_opaque_meets_bounds<'tcx>(
     // Defining use functions may have more bounds than the opaque type, which is ok, as long as the
     // hidden type is well formed even without those bounds.
     let predicate =
-        ty::Binder::dummy(ty::PredicateKind::WellFormed(hidden_type.into())).to_predicate(tcx);
+        ty::Binder::dummy(ty::PredicateKind::WellFormed(hidden_ty.into())).to_predicate(tcx);
     ocx.register_obligation(Obligation::new(misc_cause, param_env, predicate));
 
     // Check that all obligations are satisfied by the implementation's
diff --git a/compiler/rustc_hir_analysis/src/check/expr.rs b/compiler/rustc_hir_analysis/src/check/expr.rs
index 375c13d922b..34c25784597 100644
--- a/compiler/rustc_hir_analysis/src/check/expr.rs
+++ b/compiler/rustc_hir_analysis/src/check/expr.rs
@@ -1051,8 +1051,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 rhs_expr,
             ) = lhs.kind
             {
+                // if x == 1 && y == 2 { .. }
+                //                 +
                 let actual_lhs_ty = self.check_expr(&rhs_expr);
                 (Applicability::MaybeIncorrect, self.can_coerce(rhs_ty, actual_lhs_ty))
+            } else if let ExprKind::Binary(
+                Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. },
+                lhs_expr,
+                _,
+            ) = rhs.kind
+            {
+                // if x == 1 && y == 2 { .. }
+                //       +
+                let actual_rhs_ty = self.check_expr(&lhs_expr);
+                (Applicability::MaybeIncorrect, self.can_coerce(actual_rhs_ty, lhs_ty))
             } else {
                 (Applicability::MaybeIncorrect, false)
             };
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs
index 1cd550644bf..dbfa22aaff0 100644
--- a/compiler/rustc_metadata/src/errors.rs
+++ b/compiler/rustc_metadata/src/errors.rs
@@ -372,7 +372,41 @@ pub struct FailedWriteError {
 #[derive(Diagnostic)]
 #[diag(metadata::missing_native_library)]
 pub struct MissingNativeLibrary<'a> {
-    pub libname: &'a str,
+    libname: &'a str,
+    #[subdiagnostic]
+    suggest_name: Option<SuggestLibraryName<'a>>,
+}
+
+impl<'a> MissingNativeLibrary<'a> {
+    pub fn new(libname: &'a str, verbatim: bool) -> Self {
+        // if it looks like the user has provided a complete filename rather just the bare lib name,
+        // then provide a note that they might want to try trimming the name
+        let suggested_name = if !verbatim {
+            if let Some(libname) = libname.strip_prefix("lib") && let Some(libname) = libname.strip_suffix(".a") {
+                // this is a unix style filename so trim prefix & suffix
+                Some(libname)
+            } else if let Some(libname) = libname.strip_suffix(".lib") {
+                // this is a Windows style filename so just trim the suffix
+                Some(libname)
+            } else {
+                None
+            }
+        } else {
+            None
+        };
+
+        Self {
+            libname,
+            suggest_name: suggested_name
+                .map(|suggested_name| SuggestLibraryName { suggested_name }),
+        }
+    }
+}
+
+#[derive(Subdiagnostic)]
+#[help(metadata::only_provide_library_name)]
+pub struct SuggestLibraryName<'a> {
+    suggested_name: &'a str,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index 9abb5c74895..676c67bad82 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -52,7 +52,7 @@ pub fn find_native_static_library(
         }
     }
 
-    sess.emit_fatal(MissingNativeLibrary { libname: name });
+    sess.emit_fatal(MissingNativeLibrary::new(name, verbatim.unwrap_or(false)));
 }
 
 fn find_bundled_library(
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index c0607a102a9..66354196b4e 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -637,7 +637,9 @@ pub trait PrettyPrinter<'tcx>:
                 p!(print_def_path(def_id, &[]));
             }
             ty::Projection(ref data) => {
-                if self.tcx().def_kind(data.item_def_id) == DefKind::ImplTraitPlaceholder {
+                if !(self.tcx().sess.verbose() || NO_QUERIES.with(|q| q.get()))
+                    && self.tcx().def_kind(data.item_def_id) == DefKind::ImplTraitPlaceholder
+                {
                     return self.pretty_print_opaque_impl_type(data.item_def_id, data.substs);
                 } else {
                     p!(print(data))
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 776c8ad528c..cc877e2fd30 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1969,7 +1969,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     None
                 }
             })
-            .map(|res| res.expect_full_res())
+            .and_then(|res| res.full_res())
             .filter(|res| {
                 // Permit the types that unambiguously always
                 // result in the same type constructor being used
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index 1afa04007b8..545524f63a7 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -581,17 +581,24 @@ fn object_ty_for_trait<'tcx>(
     });
     debug!(?trait_predicate);
 
-    let elaborated_predicates = elaborate_trait_ref(tcx, trait_ref).filter_map(|obligation| {
-        debug!(?obligation);
-        let pred = obligation.predicate.to_opt_poly_projection_pred()?;
-        Some(pred.map_bound(|p| {
-            ty::ExistentialPredicate::Projection(ty::ExistentialProjection {
-                item_def_id: p.projection_ty.item_def_id,
-                substs: p.projection_ty.substs,
-                term: p.term,
-            })
-        }))
-    });
+    let mut elaborated_predicates: Vec<_> = elaborate_trait_ref(tcx, trait_ref)
+        .filter_map(|obligation| {
+            debug!(?obligation);
+            let pred = obligation.predicate.to_opt_poly_projection_pred()?;
+            Some(pred.map_bound(|p| {
+                ty::ExistentialPredicate::Projection(ty::ExistentialProjection {
+                    item_def_id: p.projection_ty.item_def_id,
+                    substs: p.projection_ty.substs,
+                    term: p.term,
+                })
+            }))
+        })
+        .collect();
+    // NOTE: Since #37965, the existential predicates list has depended on the
+    // list of predicates to be sorted. This is mostly to enforce that the primary
+    // predicate comes first.
+    elaborated_predicates.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
+    elaborated_predicates.dedup();
 
     let existential_predicates = tcx
         .mk_poly_existential_predicates(iter::once(trait_predicate).chain(elaborated_predicates));
diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs
index 7df4add8ce1..42ac6fcd8bf 100644
--- a/library/std/src/sys/unix/thread.rs
+++ b/library/std/src/sys/unix/thread.rs
@@ -766,6 +766,16 @@ pub mod guard {
             const GUARD_PAGES: usize = 1;
             let guard = guardaddr..guardaddr + GUARD_PAGES * page_size;
             Some(guard)
+        } else if cfg!(target_os = "openbsd") {
+            // OpenBSD stack already includes a guard page, and stack is
+            // immutable.
+            //
+            // We'll just note where we expect rlimit to start
+            // faulting, so our handler can report "stack overflow", and
+            // trust that the kernel's own stack guard will work.
+            let stackptr = get_stack_start_aligned()?;
+            let stackaddr = stackptr.addr();
+            Some(stackaddr - page_size..stackaddr)
         } else {
             // Reallocate the last page of the stack.
             // This ensures SIGBUS will be raised on
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
index e96a87111cb..d61567cd134 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
@@ -1 +1 @@
-0.12.2
\ No newline at end of file
+0.12.3
\ No newline at end of file
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 8d556a962d9..7f82dfbd3d6 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1543,8 +1543,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
         }
         TyKind::BareFn(barefn) => BareFunction(Box::new(clean_bare_fn_ty(barefn, cx))),
         // Rustdoc handles `TyKind::Err`s by turning them into `Type::Infer`s.
-        TyKind::Infer | TyKind::Err => Infer,
-        TyKind::Typeof(..) => panic!("unimplemented type {:?}", ty.kind),
+        TyKind::Infer | TyKind::Err | TyKind::Typeof(..) => Infer,
     }
 }
 
diff --git a/src/test/rustdoc-gui/unsafe-fn.goml b/src/test/rustdoc-gui/unsafe-fn.goml
index 94f128db72e..5e43b85fce0 100644
--- a/src/test/rustdoc-gui/unsafe-fn.goml
+++ b/src/test/rustdoc-gui/unsafe-fn.goml
@@ -1,37 +1,28 @@
+// Check position and color of the `<sup>` for unsafe elements.
 goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
-
-compare-elements-property: (
-	"//a[@title='test_docs::safe_fn fn']/..",
-	"//a[@title='test_docs::unsafe_fn fn']/..",
-	["clientHeight"]
-)
-
 // If the text isn't displayed, the browser doesn't compute color style correctly...
 show-text: true
 
-// Set the theme to dark.
-local-storage: {"rustdoc-theme": "dark", "rustdoc-preferred-dark-theme": "dark", "rustdoc-use-system-theme": "false"}
-// We reload the page so the local storage settings are being used.
-reload:
-
-assert-css: (".item-left sup", {
-	"color": "rgb(221, 221, 221)"
-})
-
-// Set the theme to ayu.
-local-storage: {"rustdoc-theme": "ayu", "rustdoc-preferred-dark-theme": "ayu", "rustdoc-use-system-theme": "false"}
-// We reload the page so the local storage settings are being used.
-reload:
-
-assert-css: (".item-left sup", {
-	"color": "rgb(197, 197, 197)"
-})
+compare-elements-property: (
+    "//a[@title='test_docs::safe_fn fn']/..",
+    "//a[@title='test_docs::unsafe_fn fn']/..",
+    ["clientHeight"]
+)
 
-// Set the theme to light.
-local-storage: {"rustdoc-theme": "light", "rustdoc-preferred-dark-theme": "light", "rustdoc-use-system-theme": "false"}
-// We reload the page so the local storage settings are being used.
-reload:
+define-function: (
+    "sup-check",
+    // `theme` is the theme being tested.
+    // `color` is the expected color of the `<sup>` element.
+    (theme, color),
+    [
+        // Set the theme.
+        ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
+        // We reload the page so the local storage settings are being used.
+        ("reload"),
+        ("assert-css", (".item-left sup", {"color": |color|})),
+    ],
+)
 
-assert-css: (".item-left sup", {
-	"color": "rgb(0, 0, 0)"
-})
+call-function: ("sup-check", ("dark", "rgb(221, 221, 221)"))
+call-function: ("sup-check", ("ayu", "rgb(197, 197, 197)"))
+call-function: ("sup-check", ("light", "rgb(0, 0, 0)"))
diff --git a/src/test/rustdoc-ui/issue-102986.rs b/src/test/rustdoc-ui/issue-102986.rs
new file mode 100644
index 00000000000..001784ac285
--- /dev/null
+++ b/src/test/rustdoc-ui/issue-102986.rs
@@ -0,0 +1,4 @@
+struct Struct {
+    y: (typeof("hey"),),
+    //~^ `typeof` is a reserved keyword but unimplemented
+}
diff --git a/src/test/rustdoc-ui/issue-102986.stderr b/src/test/rustdoc-ui/issue-102986.stderr
new file mode 100644
index 00000000000..3a573726c97
--- /dev/null
+++ b/src/test/rustdoc-ui/issue-102986.stderr
@@ -0,0 +1,14 @@
+error[E0516]: `typeof` is a reserved keyword but unimplemented
+  --> $DIR/issue-102986.rs:2:9
+   |
+LL |     y: (typeof("hey"),),
+   |         ^^^^^^^^^^^^^ reserved keyword
+   |
+help: consider replacing `typeof(...)` with an actual type
+   |
+LL |     y: (&'static str,),
+   |         ~~~~~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0516`.
diff --git a/src/test/ui/native-library-link-flags/suggest-libname-only-1.rs b/src/test/ui/native-library-link-flags/suggest-libname-only-1.rs
new file mode 100644
index 00000000000..abf988a7c1e
--- /dev/null
+++ b/src/test/ui/native-library-link-flags/suggest-libname-only-1.rs
@@ -0,0 +1,9 @@
+// build-fail
+// compile-flags: --crate-type rlib
+// error-pattern: could not find native static library `libfoo.a`
+// error-pattern: only provide the library name `foo`, not the full filename
+
+#[link(name = "libfoo.a", kind = "static")]
+extern { }
+
+pub fn main() { }
diff --git a/src/test/ui/native-library-link-flags/suggest-libname-only-1.stderr b/src/test/ui/native-library-link-flags/suggest-libname-only-1.stderr
new file mode 100644
index 00000000000..64d0a9077ed
--- /dev/null
+++ b/src/test/ui/native-library-link-flags/suggest-libname-only-1.stderr
@@ -0,0 +1,6 @@
+error: could not find native static library `libfoo.a`, perhaps an -L flag is missing?
+   |
+   = help: only provide the library name `foo`, not the full filename
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/native-library-link-flags/suggest-libname-only-2.rs b/src/test/ui/native-library-link-flags/suggest-libname-only-2.rs
new file mode 100644
index 00000000000..dfa70e56db7
--- /dev/null
+++ b/src/test/ui/native-library-link-flags/suggest-libname-only-2.rs
@@ -0,0 +1,9 @@
+// build-fail
+// compile-flags: --crate-type rlib
+// error-pattern: could not find native static library `bar.lib`
+// error-pattern: only provide the library name `bar`, not the full filename
+
+#[link(name = "bar.lib", kind = "static")]
+extern { }
+
+pub fn main() { }
diff --git a/src/test/ui/native-library-link-flags/suggest-libname-only-2.stderr b/src/test/ui/native-library-link-flags/suggest-libname-only-2.stderr
new file mode 100644
index 00000000000..e166af9ed8f
--- /dev/null
+++ b/src/test/ui/native-library-link-flags/suggest-libname-only-2.stderr
@@ -0,0 +1,6 @@
+error: could not find native static library `bar.lib`, perhaps an -L flag is missing?
+   |
+   = help: only provide the library name `bar`, not the full filename
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/object-safety/issue-102933.rs b/src/test/ui/object-safety/issue-102933.rs
new file mode 100644
index 00000000000..843391cffb2
--- /dev/null
+++ b/src/test/ui/object-safety/issue-102933.rs
@@ -0,0 +1,25 @@
+// check-pass
+
+use std::future::Future;
+
+pub trait Service {
+    type Response;
+    type Future: Future<Output = Self::Response>;
+}
+
+pub trait A1: Service<Response = i32> {}
+
+pub trait A2: Service<Future = Box<dyn Future<Output = i32>>> + A1 {
+    fn foo(&self) {}
+}
+
+pub trait B1: Service<Future = Box<dyn Future<Output = i32>>> {}
+
+pub trait B2: Service<Response = i32> + B1 {
+    fn foo(&self) {}
+}
+
+fn main() {
+    let x: &dyn A2 = todo!();
+    let x: &dyn B2 = todo!();
+}
diff --git a/src/test/ui/resolve/issue-102946.rs b/src/test/ui/resolve/issue-102946.rs
new file mode 100644
index 00000000000..c6feca6f32f
--- /dev/null
+++ b/src/test/ui/resolve/issue-102946.rs
@@ -0,0 +1,7 @@
+impl Error for str::Utf8Error {
+    //~^ ERROR cannot find trait `Error` in this scope
+    //~| ERROR ambiguous associated type
+    fn description(&self)  {}
+}
+
+fn main() {}
diff --git a/src/test/ui/resolve/issue-102946.stderr b/src/test/ui/resolve/issue-102946.stderr
new file mode 100644
index 00000000000..65be0258e6d
--- /dev/null
+++ b/src/test/ui/resolve/issue-102946.stderr
@@ -0,0 +1,26 @@
+error[E0405]: cannot find trait `Error` in this scope
+  --> $DIR/issue-102946.rs:1:6
+   |
+LL | impl Error for str::Utf8Error {
+   |      ^^^^^ not found in this scope
+   |
+help: consider importing this trait
+   |
+LL | use std::error::Error;
+   |
+
+error[E0223]: ambiguous associated type
+  --> $DIR/issue-102946.rs:1:16
+   |
+LL | impl Error for str::Utf8Error {
+   |                ^^^^^^^^^^^^^^
+   |
+help: you are looking for the module in `std`, not the primitive type
+   |
+LL | impl Error for std::str::Utf8Error {
+   |                +++++
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0223, E0405.
+For more information about an error, try `rustc --explain E0223`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/issue-102985.rs b/src/test/ui/rfc-2632-const-trait-impl/issue-102985.rs
new file mode 100644
index 00000000000..e0df7200384
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/issue-102985.rs
@@ -0,0 +1,11 @@
+#![feature(const_trait_impl)]
+
+struct Bug {
+    inner: [(); match || 1 {
+        n => n(),
+        //~^ ERROR the trait bound
+        //~| ERROR cannot call non-const fn `Bug::inner::{constant#0}::{closure#0}` in constants
+    }],
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/issue-102985.stderr b/src/test/ui/rfc-2632-const-trait-impl/issue-102985.stderr
new file mode 100644
index 00000000000..14d87e7cdc6
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/issue-102985.stderr
@@ -0,0 +1,26 @@
+error[E0277]: the trait bound `[closure@$DIR/issue-102985.rs:4:23: 4:25]: ~const Fn<()>` is not satisfied
+  --> $DIR/issue-102985.rs:5:14
+   |
+LL |         n => n(),
+   |              ^^^ expected an `Fn<()>` closure, found `[closure@$DIR/issue-102985.rs:4:23: 4:25]`
+   |
+   = help: the trait `~const Fn<()>` is not implemented for closure `[closure@$DIR/issue-102985.rs:4:23: 4:25]`
+note: the trait `Fn<()>` is implemented for `[closure@$DIR/issue-102985.rs:4:23: 4:25]`, but that implementation is not `const`
+  --> $DIR/issue-102985.rs:5:14
+   |
+LL |         n => n(),
+   |              ^^^
+   = note: wrap the `[closure@$DIR/issue-102985.rs:4:23: 4:25]` in a closure with no arguments: `|| { /* code */ }`
+
+error[E0015]: cannot call non-const fn `Bug::inner::{constant#0}::{closure#0}` in constants
+  --> $DIR/issue-102985.rs:5:14
+   |
+LL |         n => n(),
+   |              ^^^
+   |
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0015, E0277.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/src/test/ui/type-alias-impl-trait/closure_parent_substs.rs b/src/test/ui/type-alias-impl-trait/closure_parent_substs.rs
new file mode 100644
index 00000000000..475f4724ff2
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/closure_parent_substs.rs
@@ -0,0 +1,65 @@
+// When WF checking the hidden type in the ParamEnv of the opaque type,
+// one complication arises when the hidden type is a closure/generator:
+// the "parent_substs" of the type may reference lifetime parameters
+// not present in the opaque type.
+// These region parameters are not really useful in this check.
+// So here we ignore them and replace them with fresh region variables.
+
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+// Basic test
+mod test1 {
+    // Hidden type = Closure['_#0r]
+    type Opaque = impl Sized;
+
+    fn define<'a: 'a>() -> Opaque {
+        || {}
+    }
+}
+
+// the region vars cannot both be equal to `'static` or `'empty`
+mod test2 {
+    trait Trait {}
+
+    // Hidden type = Closure['a, '_#0r, '_#1r]
+    // Constraints = [('_#0r: 'a), ('a: '_#1r)]
+    type Opaque<'a>
+    where
+        &'a (): Trait,
+    = impl Sized + 'a;
+
+    fn define<'a, 'x, 'y>() -> Opaque<'a>
+    where
+        &'a (): Trait,
+        'x: 'a,
+        'a: 'y,
+    {
+        || {}
+    }
+}
+
+// the region var cannot be equal to `'a` or `'b`
+mod test3 {
+    trait Trait {}
+
+    // Hidden type = Closure['a, 'b, '_#0r]
+    // Constraints = [('_#0r: 'a), ('_#0r: 'b)]
+    type Opaque<'a, 'b>
+    where
+        (&'a (), &'b ()): Trait,
+    = impl Sized + 'a + 'b;
+
+    fn define<'a, 'b, 'x>() -> Opaque<'a, 'b>
+    where
+        (&'a (), &'b ()): Trait,
+        'x: 'a,
+        'x: 'b,
+    {
+        || {}
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/closure_wf_outlives.rs b/src/test/ui/type-alias-impl-trait/closure_wf_outlives.rs
new file mode 100644
index 00000000000..53974dbb36b
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/closure_wf_outlives.rs
@@ -0,0 +1,65 @@
+// If the hidden type is a closure, we require the "outlives" bounds that appear on the
+// defining site to also appear on the opaque type.
+//
+// It's not clear if this is the desired behavior but at least
+// it's consistent and has no back-compat risk.
+
+// check-fail
+
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+// requires `'a: 'b` bound
+mod test1 {
+    type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+    //~^ ERROR lifetime bound not satisfied
+
+    fn define<'a, 'b>() -> Opaque<'a, 'b>
+    where
+        'a: 'b,
+    {
+        || {}
+    }
+}
+
+// Same as the above but through indirection `'x`
+mod test2 {
+    type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+    //~^ ERROR cannot infer an appropriate lifetime
+
+    fn define<'a, 'b, 'x>() -> Opaque<'a, 'b>
+    where
+        'a: 'x,
+        'x: 'b,
+    {
+        || {}
+    }
+}
+
+// fixed version of the above
+mod test2_fixed {
+    type Opaque<'a: 'b, 'b> = impl Sized + 'a + 'b;
+
+    fn define<'a, 'b, 'x>() -> Opaque<'a, 'b>
+    where
+        'a: 'x,
+        'x: 'b,
+    {
+        || {}
+    }
+}
+
+// requires `T: 'static`
+mod test3 {
+    type Opaque<T> = impl Sized;
+    //~^ ERROR the parameter type `T` may not live long enough
+
+    fn define<T>() -> Opaque<T>
+    where
+        T: 'static,
+    {
+        || {}
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/closure_wf_outlives.stderr b/src/test/ui/type-alias-impl-trait/closure_wf_outlives.stderr
new file mode 100644
index 00000000000..ae6462bb62c
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/closure_wf_outlives.stderr
@@ -0,0 +1,64 @@
+error[E0478]: lifetime bound not satisfied
+  --> $DIR/closure_wf_outlives.rs:14:27
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                           ^^^^^^^^^^^^^^^^^^^^
+   |
+note: lifetime parameter instantiated with the lifetime `'a` as defined here
+  --> $DIR/closure_wf_outlives.rs:14:17
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                 ^^
+note: but lifetime parameter must outlive the lifetime `'b` as defined here
+  --> $DIR/closure_wf_outlives.rs:14:21
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                     ^^
+
+error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
+  --> $DIR/closure_wf_outlives.rs:27:27
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                           ^^^^^^^^^^^^^^^^^^^^
+   |
+note: first, the lifetime cannot outlive the lifetime `'a` as defined here...
+  --> $DIR/closure_wf_outlives.rs:27:17
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                 ^^
+note: ...so that the declared lifetime parameter bounds are satisfied
+  --> $DIR/closure_wf_outlives.rs:27:27
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                           ^^^^^^^^^^^^^^^^^^^^
+note: but, the lifetime must be valid for the lifetime `'b` as defined here...
+  --> $DIR/closure_wf_outlives.rs:27:21
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                     ^^
+note: ...so that the declared lifetime parameter bounds are satisfied
+  --> $DIR/closure_wf_outlives.rs:27:27
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                           ^^^^^^^^^^^^^^^^^^^^
+
+error[E0310]: the parameter type `T` may not live long enough
+  --> $DIR/closure_wf_outlives.rs:54:22
+   |
+LL |     type Opaque<T> = impl Sized;
+   |                      ^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
+   |
+note: ...that is required by this bound
+  --> $DIR/closure_wf_outlives.rs:59:12
+   |
+LL |         T: 'static,
+   |            ^^^^^^^
+help: consider adding an explicit lifetime bound...
+   |
+LL |     type Opaque<T: 'static> = impl Sized;
+   |                  +++++++++
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0310, E0478, E0495.
+For more information about an error, try `rustc --explain E0310`.
diff --git a/src/test/ui/type/type-check/assignment-in-if.rs b/src/test/ui/type/type-check/assignment-in-if.rs
index 3a7845096fd..ada250df246 100644
--- a/src/test/ui/type/type-check/assignment-in-if.rs
+++ b/src/test/ui/type/type-check/assignment-in-if.rs
@@ -53,4 +53,10 @@ fn main() {
         //~| ERROR mismatched types
         println!("{}", x);
     }
+
+    if x = 1 && x == 1 {
+        //~^ ERROR mismatched types
+        //~| ERROR mismatched types
+        println!("{}", x);
+    }
 }
diff --git a/src/test/ui/type/type-check/assignment-in-if.stderr b/src/test/ui/type/type-check/assignment-in-if.stderr
index 166f2293777..8ab08e25e30 100644
--- a/src/test/ui/type/type-check/assignment-in-if.stderr
+++ b/src/test/ui/type/type-check/assignment-in-if.stderr
@@ -104,6 +104,23 @@ help: you might have meant to compare for equality
 LL |     if x == x && x == x && x == x {
    |                               +
 
-error: aborting due to 11 previous errors
+error[E0308]: mismatched types
+  --> $DIR/assignment-in-if.rs:57:12
+   |
+LL |     if x = 1 && x == 1 {
+   |            ^ expected `bool`, found integer
+
+error[E0308]: mismatched types
+  --> $DIR/assignment-in-if.rs:57:8
+   |
+LL |     if x = 1 && x == 1 {
+   |        ^^^^^^^^^^^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to compare for equality
+   |
+LL |     if x == 1 && x == 1 {
+   |           +
+
+error: aborting due to 13 previous errors
 
 For more information about this error, try `rustc --explain E0308`.