Skip to content

Commit

Permalink
Auto merge of rust-lang#120466 - Dylan-DPC:rollup-v0or19a, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 9 pull requests

Successful merges:

 - rust-lang#116677 (References refer to allocated objects)
 - rust-lang#118625 (Improve handling of expressions in patterns)
 - rust-lang#120266 (Improve documentation for [A]Rc::into_inner)
 - rust-lang#120373 (Adjust Behaviour of `read_dir` and `ReadDir` in Windows Implementation: Check Whether Path to Search In Exists)
 - rust-lang#120390 (Borrow check inline const patterns)
 - rust-lang#120420 (Stop using derivative in rustc_pattern_analysis)
 - rust-lang#120428 (hir: Two preparatory changes for rust-lang#120206)
 - rust-lang#120453 (Fix incorrect comment in normalize_newlines)
 - rust-lang#120462 (Clean dead code)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jan 29, 2024
2 parents fb4bca0 + c70c4cc commit 9ee33fb
Show file tree
Hide file tree
Showing 62 changed files with 1,281 additions and 159 deletions.
1 change: 0 additions & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4342,7 +4342,6 @@ dependencies = [
name = "rustc_pattern_analysis"
version = "0.0.0"
dependencies = [
"derivative",
"rustc-hash",
"rustc_apfloat",
"rustc_arena",
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
ExprKind::Let(pat, scrutinee, span, is_recovered) => {
hir::ExprKind::Let(self.arena.alloc(hir::Let {
hir_id: self.next_id(),
span: self.lower_span(*span),
pat: self.lower_pat(pat),
ty: None,
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2305,7 +2305,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
match c.value.kind {
ExprKind::Underscore => {
if self.tcx.features().generic_arg_infer {
hir::ArrayLen::Infer(self.lower_node_id(c.id), self.lower_span(c.value.span))
hir::ArrayLen::Infer(hir::InferArg {
hir_id: self.lower_node_id(c.id),
span: self.lower_span(c.value.span),
})
} else {
feature_err(
&self.tcx.sess,
Expand Down
64 changes: 56 additions & 8 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1099,10 +1099,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
#[instrument(skip(self), level = "debug")]
fn check_user_type_annotations(&mut self) {
debug!(?self.user_type_annotations);
let tcx = self.tcx();
for user_annotation in self.user_type_annotations {
let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation;
let annotation = self.instantiate_canonical_with_fresh_inference_vars(span, user_ty);
self.ascribe_user_type(inferred_ty, annotation, span);
if let ty::UserType::TypeOf(def, args) = annotation
&& let DefKind::InlineConst = tcx.def_kind(def)
{
self.check_inline_const(inferred_ty, def.expect_local(), args, span);
} else {
self.ascribe_user_type(inferred_ty, annotation, span);
}
}
}

Expand Down Expand Up @@ -1195,6 +1202,36 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
Ok(())
}

fn check_inline_const(
&mut self,
inferred_ty: Ty<'tcx>,
def_id: LocalDefId,
args: UserArgs<'tcx>,
span: Span,
) {
assert!(args.user_self_ty.is_none());
let tcx = self.tcx();
let const_ty = tcx.type_of(def_id).instantiate(tcx, args.args);
if let Err(terr) =
self.eq_types(const_ty, inferred_ty, Locations::All(span), ConstraintCategory::Boring)
{
span_bug!(
span,
"bad inline const pattern: ({:?} = {:?}) {:?}",
const_ty,
inferred_ty,
terr
);
}
let args = self.infcx.resolve_vars_if_possible(args.args);
let predicates = self.prove_closure_bounds(tcx, def_id, args, Locations::All(span));
self.normalize_and_prove_instantiated_predicates(
def_id.to_def_id(),
predicates,
Locations::All(span),
);
}

fn tcx(&self) -> TyCtxt<'tcx> {
self.infcx.tcx
}
Expand Down Expand Up @@ -1851,7 +1888,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let def_id = uv.def;
if tcx.def_kind(def_id) == DefKind::InlineConst {
let def_id = def_id.expect_local();
let predicates = self.prove_closure_bounds(tcx, def_id, uv.args, location);
let predicates = self.prove_closure_bounds(
tcx,
def_id,
uv.args,
location.to_locations(),
);
self.normalize_and_prove_instantiated_predicates(
def_id.to_def_id(),
predicates,
Expand Down Expand Up @@ -2654,9 +2696,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// desugaring. A closure gets desugared to a struct, and
// these extra requirements are basically like where
// clauses on the struct.
AggregateKind::Closure(def_id, args) | AggregateKind::Coroutine(def_id, args) => {
(def_id, self.prove_closure_bounds(tcx, def_id.expect_local(), args, location))
}
AggregateKind::Closure(def_id, args) | AggregateKind::Coroutine(def_id, args) => (
def_id,
self.prove_closure_bounds(
tcx,
def_id.expect_local(),
args,
location.to_locations(),
),
),

AggregateKind::Array(_) | AggregateKind::Tuple => {
(CRATE_DEF_ID.to_def_id(), ty::InstantiatedPredicates::empty())
Expand All @@ -2675,7 +2723,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
args: GenericArgsRef<'tcx>,
location: Location,
locations: Locations,
) -> ty::InstantiatedPredicates<'tcx> {
if let Some(closure_requirements) = &tcx.mir_borrowck(def_id).closure_requirements {
constraint_conversion::ConstraintConversion::new(
Expand All @@ -2684,7 +2732,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
self.region_bound_pairs,
self.implicit_region_bound,
self.param_env,
location.to_locations(),
locations,
DUMMY_SP, // irrelevant; will be overridden.
ConstraintCategory::Boring, // same as above.
self.borrowck_context.constraints,
Expand All @@ -2710,7 +2758,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
if let Err(_) = self.eq_args(
typeck_root_args,
parent_args,
location.to_locations(),
locations,
ConstraintCategory::BoringNoLocation,
) {
span_mirbug!(
Expand Down
9 changes: 5 additions & 4 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1273,7 +1273,6 @@ pub struct Arm<'hir> {
/// desugaring to if-let. Only let-else supports the type annotation at present.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Let<'hir> {
pub hir_id: HirId,
pub span: Span,
pub pat: &'hir Pat<'hir>,
pub ty: Option<&'hir Ty<'hir>>,
Expand Down Expand Up @@ -1532,14 +1531,16 @@ pub type Lit = Spanned<LitKind>;

#[derive(Copy, Clone, Debug, HashStable_Generic)]
pub enum ArrayLen {
Infer(HirId, Span),
Infer(InferArg),
Body(AnonConst),
}

impl ArrayLen {
pub fn hir_id(&self) -> HirId {
match self {
&ArrayLen::Infer(hir_id, _) | &ArrayLen::Body(AnonConst { hir_id, .. }) => hir_id,
ArrayLen::Infer(InferArg { hir_id, .. }) | ArrayLen::Body(AnonConst { hir_id, .. }) => {
*hir_id
}
}
}
}
Expand Down Expand Up @@ -2424,7 +2425,7 @@ impl<'hir> Ty<'hir> {
TyKind::Infer => true,
TyKind::Slice(ty) => ty.is_suggestable_infer_ty(),
TyKind::Array(ty, length) => {
ty.is_suggestable_infer_ty() || matches!(length, ArrayLen::Infer(_, _))
ty.is_suggestable_infer_ty() || matches!(length, ArrayLen::Infer(..))
}
TyKind::Tup(tys) => tys.iter().any(Self::is_suggestable_infer_ty),
TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty) => mut_ty.ty.is_suggestable_infer_ty(),
Expand Down
20 changes: 7 additions & 13 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,9 +341,6 @@ pub trait Visitor<'v>: Sized {
fn visit_expr(&mut self, ex: &'v Expr<'v>) {
walk_expr(self, ex)
}
fn visit_let_expr(&mut self, lex: &'v Let<'v>) {
walk_let_expr(self, lex)
}
fn visit_expr_field(&mut self, field: &'v ExprField<'v>) {
walk_expr_field(self, field)
}
Expand Down Expand Up @@ -672,7 +669,7 @@ pub fn walk_pat_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v PatField<'

pub fn walk_array_len<'v, V: Visitor<'v>>(visitor: &mut V, len: &'v ArrayLen) {
match len {
&ArrayLen::Infer(hir_id, _span) => visitor.visit_id(hir_id),
ArrayLen::Infer(InferArg { hir_id, span: _ }) => visitor.visit_id(*hir_id),
ArrayLen::Body(c) => visitor.visit_anon_const(c),
}
}
Expand Down Expand Up @@ -729,7 +726,12 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
ExprKind::DropTemps(ref subexpression) => {
visitor.visit_expr(subexpression);
}
ExprKind::Let(ref let_expr) => visitor.visit_let_expr(let_expr),
ExprKind::Let(Let { span: _, pat, ty, init, is_recovered: _ }) => {
// match the visit order in walk_local
visitor.visit_expr(init);
visitor.visit_pat(pat);
walk_list!(visitor, visit_ty, ty);
}
ExprKind::If(ref cond, ref then, ref else_opt) => {
visitor.visit_expr(cond);
visitor.visit_expr(then);
Expand Down Expand Up @@ -806,14 +808,6 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
}
}

pub fn walk_let_expr<'v, V: Visitor<'v>>(visitor: &mut V, let_expr: &'v Let<'v>) {
// match the visit order in walk_local
visitor.visit_expr(let_expr.init);
visitor.visit_id(let_expr.hir_id);
visitor.visit_pat(let_expr.pat);
walk_list!(visitor, visit_ty, let_expr.ty);
}

pub fn walk_expr_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v ExprField<'v>) {
visitor.visit_id(field.hir_id);
visitor.visit_ident(field.ident);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2529,7 +2529,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
hir::TyKind::Array(ty, length) => {
let length = match length {
&hir::ArrayLen::Infer(_, span) => self.ct_infer(tcx.types.usize, None, span),
hir::ArrayLen::Infer(inf) => self.ct_infer(tcx.types.usize, None, inf.span),
hir::ArrayLen::Body(constant) => {
ty::Const::from_anon_const(tcx, constant.def_id)
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ impl<'v> Visitor<'v> for HirPlaceholderCollector {
}
}
fn visit_array_length(&mut self, length: &'v hir::ArrayLen) {
if let &hir::ArrayLen::Infer(_, span) = length {
self.0.push(span);
if let hir::ArrayLen::Infer(inf) = length {
self.0.push(inf.span);
}
intravisit::walk_array_len(self, length)
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -956,7 +956,7 @@ impl<'a> State<'a> {

fn print_array_length(&mut self, len: &hir::ArrayLen) {
match len {
hir::ArrayLen::Infer(_, _) => self.word("_"),
hir::ArrayLen::Infer(..) => self.word("_"),
hir::ArrayLen::Body(ct) => self.print_anon_const(ct),
}
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
ExprKind::Ret(ref expr_opt) => self.check_expr_return(expr_opt.as_deref(), expr),
ExprKind::Become(call) => self.check_expr_become(call, expr),
ExprKind::Let(let_expr) => self.check_expr_let(let_expr),
ExprKind::Let(let_expr) => self.check_expr_let(let_expr, expr.hir_id),
ExprKind::Loop(body, _, source, _) => {
self.check_expr_loop(body, source, expected, expr)
}
Expand Down Expand Up @@ -1259,12 +1259,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

pub(super) fn check_expr_let(&self, let_expr: &'tcx hir::Let<'tcx>) -> Ty<'tcx> {
pub(super) fn check_expr_let(&self, let_expr: &'tcx hir::Let<'tcx>, hir_id: HirId) -> Ty<'tcx> {
// for let statements, this is done in check_stmt
let init = let_expr.init;
self.warn_if_unreachable(init.hir_id, init.span, "block in `let` expression");
// otherwise check exactly as a let statement
self.check_decl(let_expr.into());
self.check_decl((let_expr, hir_id).into());
// but return a bool, for this is a boolean expression
if let Some(error_guaranteed) = let_expr.is_recovered {
self.set_tainted_by_errors(error_guaranteed);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

pub fn array_length_to_const(&self, length: &hir::ArrayLen) -> ty::Const<'tcx> {
match length {
&hir::ArrayLen::Infer(_, span) => self.ct_infer(self.tcx.types.usize, None, span),
hir::ArrayLen::Infer(inf) => self.ct_infer(self.tcx.types.usize, None, inf.span),
hir::ArrayLen::Body(anon_const) => {
let span = self.tcx.def_span(anon_const.def_id);
let c = ty::Const::from_anon_const(self.tcx, anon_const.def_id);
Expand Down
14 changes: 8 additions & 6 deletions compiler/rustc_hir_typeck/src/gather_locals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ impl<'a> From<&'a hir::Local<'a>> for Declaration<'a> {
}
}

impl<'a> From<&'a hir::Let<'a>> for Declaration<'a> {
fn from(let_expr: &'a hir::Let<'a>) -> Self {
let hir::Let { hir_id, pat, ty, span, init, is_recovered: _ } = *let_expr;
impl<'a> From<(&'a hir::Let<'a>, hir::HirId)> for Declaration<'a> {
fn from((let_expr, hir_id): (&'a hir::Let<'a>, hir::HirId)) -> Self {
let hir::Let { pat, ty, span, init, is_recovered: _ } = *let_expr;
Declaration { hir_id, pat, ty, span, init: Some(init), origin: DeclOrigin::LetExpr }
}
}
Expand Down Expand Up @@ -125,9 +125,11 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
intravisit::walk_local(self, local)
}

fn visit_let_expr(&mut self, let_expr: &'tcx hir::Let<'tcx>) {
self.declare(let_expr.into());
intravisit::walk_let_expr(self, let_expr);
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
if let hir::ExprKind::Let(let_expr) = expr.kind {
self.declare((let_expr, expr.hir_id).into());
}
intravisit::walk_expr(self, expr)
}

fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
Expand Down
37 changes: 35 additions & 2 deletions compiler/rustc_mir_build/src/build/matches/simplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
use crate::build::expr::as_place::PlaceBuilder;
use crate::build::matches::{Ascription, Binding, Candidate, MatchPair};
use crate::build::Builder;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_middle::thir::{self, *};
use rustc_middle::ty;

use std::mem;

Expand Down Expand Up @@ -149,7 +151,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
ref subpattern,
ascription: thir::Ascription { ref annotation, variance },
} => {
// Apply the type ascription to the value at `match_pair.place`, which is the
// Apply the type ascription to the value at `match_pair.place`
if let Some(source) = match_pair.place.try_to_place(self) {
candidate.ascriptions.push(Ascription {
annotation: annotation.clone(),
Expand Down Expand Up @@ -205,7 +207,38 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Err(match_pair)
}

PatKind::InlineConstant { subpattern: ref pattern, def: _ } => {
PatKind::InlineConstant { subpattern: ref pattern, def } => {
// Apply a type ascription for the inline constant to the value at `match_pair.place`
if let Some(source) = match_pair.place.try_to_place(self) {
let span = match_pair.pattern.span;
let parent_id = self.tcx.typeck_root_def_id(self.def_id.to_def_id());
let args = ty::InlineConstArgs::new(
self.tcx,
ty::InlineConstArgsParts {
parent_args: ty::GenericArgs::identity_for_item(self.tcx, parent_id),
ty: self.infcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::MiscVariable,
span,
}),
},
)
.args;
let user_ty =
self.infcx.canonicalize_user_type_annotation(ty::UserType::TypeOf(
def.to_def_id(),
ty::UserArgs { args, user_self_ty: None },
));
let annotation = ty::CanonicalUserTypeAnnotation {
inferred_ty: pattern.ty,
span,
user_ty: Box::new(user_ty),
};
candidate.ascriptions.push(Ascription {
annotation,
source,
variance: ty::Contravariant,
});
}
candidate.match_pairs.push(MatchPair::new(match_pair.place, pattern, self));

Ok(())
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_parse/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,20 @@ parse_unexpected_const_param_declaration = unexpected `const` parameter declarat
parse_unexpected_default_value_for_lifetime_in_generic_parameters = unexpected default lifetime parameter
.label = lifetime parameters cannot have default values
parse_unexpected_expr_in_pat =
expected {$is_bound ->
[true] a pattern range bound
*[false] a pattern
}, found {$is_method_call ->
[true] a method call
*[false] an expression
}
.label = {$is_method_call ->
[true] method calls
*[false] arbitrary expressions
} are not allowed in patterns
parse_unexpected_if_with_if = unexpected `if` in the condition expression
.suggestion = remove the `if`
Expand Down
Loading

0 comments on commit 9ee33fb

Please sign in to comment.