Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 5 pull requests #116636

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1623,12 +1623,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
.lower_generic_params(bound_generic_params, hir::GenericParamSource::Binder),
bounded_ty: self
.lower_ty(bounded_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
bounds: self.arena.alloc_from_iter(bounds.iter().map(|bound| {
self.lower_param_bound(
bound,
&ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
)
})),
bounds: self.lower_param_bounds(
bounds,
&ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
),
span: self.lower_span(*span),
origin: PredicateOrigin::WhereClause,
}),
Expand Down
20 changes: 13 additions & 7 deletions compiler/rustc_hir_typeck/src/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// closure sooner rather than later, so first examine the expected
// type, and see if can glean a closure kind from there.
let (expected_sig, expected_kind) = match expected.to_option(self) {
Some(ty) => self.deduce_closure_signature(ty),
Some(ty) => {
self.deduce_closure_signature(self.try_structurally_resolve_type(expr_span, ty))
}
None => (None, None),
};
let body = self.tcx.hir().body(closure.body);
Expand Down Expand Up @@ -688,8 +690,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span_bug!(self.tcx.def_span(expr_def_id), "async fn generator outside of a fn")
});

let closure_span = self.tcx.def_span(expr_def_id);
let ret_ty = ret_coercion.borrow().expected_ty();
let ret_ty = self.inh.infcx.shallow_resolve(ret_ty);
let ret_ty = self.try_structurally_resolve_type(closure_span, ret_ty);

let get_future_output = |predicate: ty::Predicate<'tcx>, span| {
// Search for a pending obligation like
Expand All @@ -711,8 +714,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
};

let span = self.tcx.def_span(expr_def_id);

let output_ty = match *ret_ty.kind() {
ty::Infer(ty::TyVar(ret_vid)) => {
self.obligations_for_self_ty(ret_vid).find_map(|obligation| {
Expand All @@ -726,17 +727,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.find_map(|(p, s)| get_future_output(p.as_predicate(), s))?,
ty::Error(_) => return None,
_ => span_bug!(
span,
closure_span,
"async fn generator return type not an inference variable: {ret_ty}"
),
};

let output_ty = self.normalize(span, output_ty);
let output_ty = self.normalize(closure_span, output_ty);

// async fn that have opaque types in their return type need to redo the conversion to inference variables
// as they fetch the still opaque version from the signature.
let InferOk { value: output_ty, obligations } = self
.replace_opaque_types_with_inference_vars(output_ty, body_def_id, span, self.param_env);
.replace_opaque_types_with_inference_vars(
output_ty,
body_def_id,
closure_span,
self.param_env,
);
self.register_predicates(obligations);

Some(output_ty)
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/equate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
// performing trait matching (which then performs equality
// unification).

relate::relate_args(self, a_arg, b_arg)
relate::relate_args_invariantly(self, a_arg, b_arg)
}

fn relate_with_variance<T: Relate<'tcx>>(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/generalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ where
// Avoid fetching the variance if we are in an invariant
// context; no need, and it can induce dependency cycles
// (e.g., #41849).
relate::relate_args(self, a_subst, b_subst)
relate::relate_args_invariantly(self, a_subst, b_subst)
} else {
let tcx = self.tcx();
let opt_variances = tcx.variances_of(item_def_id);
Expand Down
65 changes: 24 additions & 41 deletions compiler/rustc_middle/src/ty/relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::ty::error::{ExpectedFound, TypeError};
use crate::ty::{self, Expr, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable};
use crate::ty::{GenericArg, GenericArgKind, GenericArgsRef};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_target::spec::abi;
use std::iter;
Expand Down Expand Up @@ -134,7 +135,7 @@ pub fn relate_type_and_mut<'tcx, R: TypeRelation<'tcx>>(
}

#[inline]
pub fn relate_args<'tcx, R: TypeRelation<'tcx>>(
pub fn relate_args_invariantly<'tcx, R: TypeRelation<'tcx>>(
relation: &mut R,
a_arg: GenericArgsRef<'tcx>,
b_arg: GenericArgsRef<'tcx>,
Expand Down Expand Up @@ -273,7 +274,20 @@ impl<'tcx> Relate<'tcx> for ty::AliasTy<'tcx> {
if a.def_id != b.def_id {
Err(TypeError::ProjectionMismatched(expected_found(relation, a.def_id, b.def_id)))
} else {
let args = relation.relate(a.args, b.args)?;
let args = match relation.tcx().def_kind(a.def_id) {
DefKind::OpaqueTy => relate_args_with_variances(
relation,
a.def_id,
relation.tcx().variances_of(a.def_id),
a.args,
b.args,
false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
)?,
DefKind::AssocTy | DefKind::AssocConst | DefKind::TyAlias => {
relate_args_invariantly(relation, a.args, b.args)?
}
def => bug!("unknown alias DefKind: {def:?}"),
};
Ok(relation.tcx().mk_alias_ty(a.def_id, args))
}
}
Expand Down Expand Up @@ -315,7 +329,7 @@ impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> {
if a.def_id != b.def_id {
Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id)))
} else {
let args = relate_args(relation, a.args, b.args)?;
let args = relate_args_invariantly(relation, a.args, b.args)?;
Ok(ty::TraitRef::new(relation.tcx(), a.def_id, args))
}
}
Expand All @@ -331,7 +345,7 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> {
if a.def_id != b.def_id {
Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id)))
} else {
let args = relate_args(relation, a.args, b.args)?;
let args = relate_args_invariantly(relation, a.args, b.args)?;
Ok(ty::ExistentialTraitRef { def_id: a.def_id, args })
}
}
Expand Down Expand Up @@ -449,7 +463,7 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
// All Generator types with the same id represent
// the (anonymous) type of the same generator expression. So
// all of their regions should be equated.
let args = relation.relate(a_args, b_args)?;
let args = relate_args_invariantly(relation, a_args, b_args)?;
Ok(Ty::new_generator(tcx, a_id, args, movability))
}

Expand All @@ -459,15 +473,15 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
// All GeneratorWitness types with the same id represent
// the (anonymous) type of the same generator expression. So
// all of their regions should be equated.
let args = relation.relate(a_args, b_args)?;
let args = relate_args_invariantly(relation, a_args, b_args)?;
Ok(Ty::new_generator_witness(tcx, a_id, args))
}

(&ty::Closure(a_id, a_args), &ty::Closure(b_id, b_args)) if a_id == b_id => {
// All Closure types with the same id represent
// the (anonymous) type of the same closure expression. So
// all of their regions should be equated.
let args = relation.relate(a_args, b_args)?;
let args = relate_args_invariantly(relation, a_args, b_args)?;
Ok(Ty::new_closure(tcx, a_id, &args))
}

Expand Down Expand Up @@ -536,24 +550,6 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
Ok(Ty::new_fn_ptr(tcx, fty))
}

// The args of opaque types may not all be invariant, so we have
// to treat them separately from other aliases.
(
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, args: a_args, .. }),
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, args: b_args, .. }),
) if a_def_id == b_def_id => {
let opt_variances = tcx.variances_of(a_def_id);
let args = relate_args_with_variances(
relation,
a_def_id,
opt_variances,
a_args,
b_args,
false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
)?;
Ok(Ty::new_opaque(tcx, a_def_id, args))
}

// Alias tend to mostly already be handled downstream due to normalization.
(&ty::Alias(a_kind, a_data), &ty::Alias(b_kind, b_data)) => {
let alias_ty = relation.relate(a_data, b_data)?;
Expand Down Expand Up @@ -709,7 +705,7 @@ impl<'tcx> Relate<'tcx> for ty::ClosureArgs<'tcx> {
a: ty::ClosureArgs<'tcx>,
b: ty::ClosureArgs<'tcx>,
) -> RelateResult<'tcx, ty::ClosureArgs<'tcx>> {
let args = relate_args(relation, a.args, b.args)?;
let args = relate_args_invariantly(relation, a.args, b.args)?;
Ok(ty::ClosureArgs { args })
}
}
Expand All @@ -720,7 +716,7 @@ impl<'tcx> Relate<'tcx> for ty::GeneratorArgs<'tcx> {
a: ty::GeneratorArgs<'tcx>,
b: ty::GeneratorArgs<'tcx>,
) -> RelateResult<'tcx, ty::GeneratorArgs<'tcx>> {
let args = relate_args(relation, a.args, b.args)?;
let args = relate_args_invariantly(relation, a.args, b.args)?;
Ok(ty::GeneratorArgs { args })
}
}
Expand All @@ -731,7 +727,7 @@ impl<'tcx> Relate<'tcx> for GenericArgsRef<'tcx> {
a: GenericArgsRef<'tcx>,
b: GenericArgsRef<'tcx>,
) -> RelateResult<'tcx, GenericArgsRef<'tcx>> {
relate_args(relation, a, b)
relate_args_invariantly(relation, a, b)
}
}

Expand Down Expand Up @@ -835,19 +831,6 @@ impl<'tcx> Relate<'tcx> for Term<'tcx> {
}
}

impl<'tcx> Relate<'tcx> for ty::ProjectionPredicate<'tcx> {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: ty::ProjectionPredicate<'tcx>,
b: ty::ProjectionPredicate<'tcx>,
) -> RelateResult<'tcx, ty::ProjectionPredicate<'tcx>> {
Ok(ty::ProjectionPredicate {
projection_ty: relation.relate(a.projection_ty, b.projection_ty)?,
term: relation.relate(a.term, b.term)?,
})
}
}

///////////////////////////////////////////////////////////////////////////
// Error handling

Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,13 @@ impl<'tcx> ConstToPat<'tcx> {
// All branches above emitted an error. Don't print any more lints.
// The pattern we return is irrelevant since we errored.
return Box::new(Pat { span: self.span, ty: cv.ty(), kind: PatKind::Wild });
} else if let ty::Adt(..) = cv.ty().kind() && matches!(cv, mir::Const::Val(..)) {
// This branch is only entered when the current `cv` is `mir::Const::Val`.
// This is because `mir::Const::ty` has already been handled by `Self::recur`
// and the invalid types may be ignored.
let err = TypeNotStructural { span: self.span, non_sm_ty };
self.tcx().sess.emit_err(err);
return Box::new(Pat { span: self.span, ty: cv.ty(), kind: PatKind::Wild });
} else if !self.saw_const_match_lint.get() {
if let Some(mir_structural_match_violation) = mir_structural_match_violation {
match non_sm_ty.kind() {
Expand Down
11 changes: 9 additions & 2 deletions src/librustdoc/formats/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,16 +221,23 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
_ => self.cache.stripped_mod,
};

#[inline]
fn is_from_private_dep(tcx: TyCtxt<'_>, cache: &Cache, def_id: DefId) -> bool {
let krate = def_id.krate;

cache.masked_crates.contains(&krate) || tcx.is_private_dep(krate)
}

// If the impl is from a masked crate or references something from a
// masked crate then remove it completely.
if let clean::ImplItem(ref i) = *item.kind &&
(self.cache.masked_crates.contains(&item.item_id.krate())
|| i.trait_
.as_ref()
.map_or(false, |t| self.cache.masked_crates.contains(&t.def_id().krate))
.map_or(false, |t| is_from_private_dep(self.tcx, self.cache, t.def_id()))
|| i.for_
.def_id(self.cache)
.map_or(false, |d| self.cache.masked_crates.contains(&d.krate)))
.map_or(false, |d| is_from_private_dep(self.tcx, self.cache, d)))
{
return None;
}
Expand Down
15 changes: 15 additions & 0 deletions tests/rustdoc-js/auxiliary/equivalent.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use std::borrow::Borrow;

pub trait Equivalent<K: ?Sized> {
fn equivalent(&self, key: &K) -> bool;
}

impl<Q: ?Sized, K: ?Sized> Equivalent<K> for Q
where
Q: Eq,
K: Borrow<Q>,
{
fn equivalent(&self, key: &K) -> bool {
PartialEq::eq(self, key.borrow())
}
}
9 changes: 9 additions & 0 deletions tests/rustdoc-js/search-non-local-trait-impl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// exact-check

// This test ensures that methods from blanket impls of not available foreign traits
// don't show up in the search results.

const EXPECTED = {
'query': 'equivalent',
'others': [],
};
8 changes: 8 additions & 0 deletions tests/rustdoc-js/search-non-local-trait-impl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// aux-crate:priv:equivalent=equivalent.rs
// compile-flags: -Zunstable-options --extern equivalent
// edition:2018

extern crate equivalent;

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct LayoutError;
14 changes: 14 additions & 0 deletions tests/ui/impl-trait/in-trait/opaque-variances.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// check-pass
// compile-flags: -Ztrait-solver=next

fn foo<'a: 'a>(x: &'a Vec<i32>) -> impl Sized {
()
}

fn main() {
// in NLL, we want to make sure that the `'a` subst of `foo` does not get
// related between `x` and the RHS of the assignment. That would require
// that the temp is live for the lifetime of the variable `x`, which of
// course is not necessary since `'a` is not captured by the RPIT.
let x = foo(&Vec::new());
}
8 changes: 8 additions & 0 deletions tests/ui/pattern/issue-115599.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const CONST_STRING: String = String::new();

fn main() {
let empty_str = String::from("");
if let CONST_STRING = empty_str {}
//~^ ERROR to use a constant of type `Vec<u8>` in a pattern, `Vec<u8>` must be annotated with `#[derive(PartialEq, Eq)]`
//~| WARN irrefutable `if let` pattern
}
21 changes: 21 additions & 0 deletions tests/ui/pattern/issue-115599.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error: to use a constant of type `Vec<u8>` in a pattern, `Vec<u8>` must be annotated with `#[derive(PartialEq, Eq)]`
--> $DIR/issue-115599.rs:5:12
|
LL | if let CONST_STRING = empty_str {}
| ^^^^^^^^^^^^
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details

warning: irrefutable `if let` pattern
--> $DIR/issue-115599.rs:5:8
|
LL | if let CONST_STRING = empty_str {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this pattern will always match, so the `if let` is useless
= help: consider replacing the `if let` with a `let`
= note: `#[warn(irrefutable_let_patterns)]` on by default

error: aborting due to previous error; 1 warning emitted

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// compile-flags: -Ztrait-solver=next
// check-pass

#![feature(return_position_impl_trait_in_trait)]

trait Foo {
fn test() -> impl Fn(u32) -> u32 {
|x| x.count_ones()
}
}

fn main() {}
11 changes: 11 additions & 0 deletions tests/ui/traits/new-solver/normalize-async-closure-in-trait.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// compile-flags: -Ztrait-solver=next
// check-pass
// edition:2021

#![feature(async_fn_in_trait)]

trait Foo {
async fn bar() {}
}

fn main() {}
Loading