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 80ca412b32ac6..22a61774e8cf7 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_hir_analysis/src/check/expr.rs b/compiler/rustc_hir_analysis/src/check/expr.rs index 375c13d922bc7..34c257845971e 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_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index c0607a102a90e..66354196b4e51 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 776c8ad528c0f..cc877e2fd30ca 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 1afa04007b8a1..545524f63a7bc 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 7df4add8ce112..42ac6fcd8bf36 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/test/ui/object-safety/issue-102933.rs b/src/test/ui/object-safety/issue-102933.rs new file mode 100644 index 0000000000000..843391cffb273 --- /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; +} + +pub trait A1: Service {} + +pub trait A2: Service>> + A1 { + fn foo(&self) {} +} + +pub trait B1: Service>> {} + +pub trait B2: Service + 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 0000000000000..c6feca6f32f60 --- /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 0000000000000..65be0258e6dba --- /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 0000000000000..e0df72003844c --- /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 0000000000000..14d87e7cdc64a --- /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/type-check/assignment-in-if.rs b/src/test/ui/type/type-check/assignment-in-if.rs index 3a7845096fd24..ada250df24695 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 166f229377768..8ab08e25e3092 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`.