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 10 pull requests #79190

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
91eabf5
Add a sane error for rust-call functions not taking tuples during typ…
CraftSpider Nov 11, 2020
bf04b04
Missing feature-gate-abi file
CraftSpider Nov 11, 2020
1e9d5c7
Minor stylistic / review changes
CraftSpider Nov 12, 2020
43bfbb1
Add column number support to Backtrace
est31 Nov 12, 2020
2b7ffec
Don't special case constant operands when lowering intrinsics
tmiasko Nov 16, 2020
92aa0e6
Use `span_suggestion_verbose` instead of `span_suggestion` for `fn` w…
ThePuzzlemaker Nov 15, 2020
b8ed466
Fix ui tests for `fn`s with qualifiers in `extern` blocks
ThePuzzlemaker Nov 15, 2020
c825c74
Move change to check_fn, fix up overloaded-calls-nontuple
CraftSpider Nov 17, 2020
42e45f8
Tidy should not check line lengths
Anthuang Oct 15, 2020
e8426a6
Remove unnecessary abi import
CraftSpider Nov 17, 2020
2c22c05
Fix tests
Anthuang Oct 15, 2020
614a748
Highlight MIR as Rust on GitHub
camelid Nov 17, 2020
7faebe5
Move capture lowering from THIR to MIR
arora-aman Nov 17, 2020
9f70e78
Remove THIR::ExprKind::SelfRef
arora-aman Nov 17, 2020
5163912
Allow using `download-ci-llvm` from directories other than the root
jyn514 Nov 18, 2020
efcbf1b
Permit standalone generic parameters as const generic arguments in ma…
varkor Nov 18, 2020
85bc953
Add tests for multi-segment paths in const generic arguments
varkor Nov 18, 2020
2098ade
Remove redundant notes in E0275
estebank Nov 16, 2020
3527964
Account for indirect cyclic requirements
estebank Nov 18, 2020
c12e77b
review comment
estebank Nov 18, 2020
956135c
Rollup merge of #77675 - Anthuang:tidy-line-length, r=Mark-Simulacrum
Dylan-DPC Nov 19, 2020
517a33a
Rollup merge of #78961 - CraftSpider:22565, r=oli-obk
Dylan-DPC Nov 19, 2020
424fdd8
Rollup merge of #79002 - est31:backtrace_colno, r=dtolnay
Dylan-DPC Nov 19, 2020
60a6e17
Rollup merge of #79082 - ThePuzzlemaker:issue-78941-fix, r=estebank
Dylan-DPC Nov 19, 2020
773ca5e
Rollup merge of #79101 - tmiasko:lower-func-type, r=jonas-schievink
Dylan-DPC Nov 19, 2020
42ab0d3
Rollup merge of #79110 - estebank:issue-58964, r=oli-obk
Dylan-DPC Nov 19, 2020
a35eb22
Rollup merge of #79147 - camelid:mir-gitattributes, r=oli-obk
Dylan-DPC Nov 19, 2020
843720b
Rollup merge of #79149 - sexxi-goose:upvar_ref, r=nikomatsakis
Dylan-DPC Nov 19, 2020
406281b
Rollup merge of #79156 - jyn514:relative-llvm, r=Mark-Simulacrum
Dylan-DPC Nov 19, 2020
37e64af
Rollup merge of #79164 - varkor:unbraced-single-segment-const-argumen…
Dylan-DPC Nov 19, 2020
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
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*.h rust
*.rs rust diff=rust
*.fixed linguist-language=Rust
*.mir linguist-language=Rust
src/etc/installer/gfx/* binary
*.woff binary
src/vendor/** -text
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ impl<'a> AstValidator<'a> {
self.err_handler()
.struct_span_err(ident.span, "functions in `extern` blocks cannot have qualifiers")
.span_label(self.current_extern_span(), "in this `extern` block")
.span_suggestion(
.span_suggestion_verbose(
span.until(ident.span.shrink_to_lo()),
"remove the qualifiers",
"fn ".to_string(),
Expand Down
12 changes: 4 additions & 8 deletions compiler/rustc_mir/src/transform/lower_intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,11 @@ pub struct LowerIntrinsics;

impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
for block in body.basic_blocks_mut() {
let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
for block in basic_blocks {
let terminator = block.terminator.as_mut().unwrap();
if let TerminatorKind::Call {
func: Operand::Constant(box Constant { literal: ty::Const { ty: func_ty, .. }, .. }),
args,
destination,
..
} = &mut terminator.kind
{
if let TerminatorKind::Call { func, args, destination, .. } = &mut terminator.kind {
let func_ty = func.ty(local_decls, tcx);
let (intrinsic_name, substs) = match resolve_rust_intrinsic(tcx, func_ty) {
None => continue,
Some(it) => it,
Expand Down
80 changes: 79 additions & 1 deletion compiler/rustc_mir_build/src/build/expr/as_place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,30 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
expr_span,
source_info,
),
ExprKind::SelfRef => block.and(PlaceBuilder::from(Local::new(1))),
ExprKind::UpvarRef { closure_def_id, var_hir_id } => {
let capture = this
.hir
.typeck_results
.closure_captures
.get(&closure_def_id)
.and_then(|captures| captures.get_full(&var_hir_id));

if capture.is_none() {
if !this.hir.tcx().features().capture_disjoint_fields {
bug!(
"No associated capture found for {:?} even though \
capture_disjoint_fields isn't enabled",
expr.kind
)
}
// FIXME(project-rfc-2229#24): Handle this case properly
}

// Unwrap until the FIXME has been resolved
let (capture_index, _, upvar_id) = capture.unwrap();
this.lower_closure_capture(block, capture_index, *upvar_id)
}

ExprKind::VarRef { id } => {
let place_builder = if this.is_bound_var_in_guard(id) {
let index = this.var_local_id(id, RefWithinGuard);
Expand Down Expand Up @@ -270,6 +293,61 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}

/// Lower a closure/generator capture by representing it as a field
/// access within the desugared closure/generator.
///
/// `capture_index` is the index of the capture within the desugared
/// closure/generator.
fn lower_closure_capture(
&mut self,
block: BasicBlock,
capture_index: usize,
upvar_id: ty::UpvarId,
) -> BlockAnd<PlaceBuilder<'tcx>> {
let closure_ty = self
.hir
.typeck_results()
.node_type(self.hir.tcx().hir().local_def_id_to_hir_id(upvar_id.closure_expr_id));

// Captures are represented using fields inside a structure.
// This represents accessing self in the closure structure
let mut place_builder = PlaceBuilder::from(Local::new(1));

// In case of Fn/FnMut closures we must deref to access the fields
// Generators are considered FnOnce, so we ignore this step for them.
if let ty::Closure(_, closure_substs) = closure_ty.kind() {
match self.hir.infcx().closure_kind(closure_substs).unwrap() {
ty::ClosureKind::Fn | ty::ClosureKind::FnMut => {
place_builder = place_builder.deref();
}
ty::ClosureKind::FnOnce => {}
}
}

let substs = match closure_ty.kind() {
ty::Closure(_, substs) => ty::UpvarSubsts::Closure(substs),
ty::Generator(_, substs, _) => ty::UpvarSubsts::Generator(substs),
_ => bug!("Lowering capture for non-closure type {:?}", closure_ty)
};

// Access the capture by accessing the field within the Closure struct.
//
// We must have inferred the capture types since we are building MIR, therefore
// it's safe to call `upvar_tys` and we can unwrap here because
// we know that the capture exists and is the `capture_index`-th capture.
let var_ty = substs.upvar_tys().nth(capture_index).unwrap();
place_builder = place_builder.field(Field::new(capture_index), var_ty);

// If the variable is captured via ByRef(Immutable/Mutable) Borrow,
// we need to deref it
match self.hir.typeck_results.upvar_capture(upvar_id) {
ty::UpvarCapture::ByRef(_) => {
block.and(place_builder.deref())
}
ty::UpvarCapture::ByValue(_) => block.and(place_builder),
}
}

/// Lower an index expression
///
/// This has two complications;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
| ExprKind::Deref { .. }
| ExprKind::Index { .. }
| ExprKind::VarRef { .. }
| ExprKind::SelfRef
| ExprKind::UpvarRef { .. }
| ExprKind::Break { .. }
| ExprKind::Continue { .. }
| ExprKind::Return { .. }
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/build/expr/category.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl Category {
ExprKind::Field { .. }
| ExprKind::Deref { .. }
| ExprKind::Index { .. }
| ExprKind::SelfRef
| ExprKind::UpvarRef { .. }
| ExprKind::VarRef { .. }
| ExprKind::PlaceTypeAscription { .. }
| ExprKind::ValueTypeAscription { .. } => Some(Category::Place),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/build/expr/into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {

// Avoid creating a temporary
ExprKind::VarRef { .. }
| ExprKind::SelfRef
| ExprKind::UpvarRef { .. }
| ExprKind::PlaceTypeAscription { .. }
| ExprKind::ValueTypeAscription { .. } => {
debug_assert!(Category::of(&expr.kind) == Some(Category::Place));
Expand Down
132 changes: 14 additions & 118 deletions compiler/rustc_mir_build/src/thir/cx/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -880,130 +880,26 @@ fn convert_path_expr<'a, 'tcx>(
ExprKind::Deref { arg: Expr { ty, temp_lifetime, span: expr.span, kind }.to_ref() }
}

Res::Local(var_hir_id) => convert_var(cx, expr, var_hir_id),
Res::Local(var_hir_id) => convert_var(cx, var_hir_id),

_ => span_bug!(expr.span, "res `{:?}` not yet implemented", res),
}
}

fn convert_var<'tcx>(
cx: &mut Cx<'_, 'tcx>,
expr: &'tcx hir::Expr<'tcx>,
var_hir_id: hir::HirId,
) -> ExprKind<'tcx> {
let upvar_index = cx
.typeck_results()
.closure_captures
.get(&cx.body_owner)
.and_then(|upvars| upvars.get_full(&var_hir_id).map(|(i, _, _)| i));

debug!(
"convert_var({:?}): upvar_index={:?}, body_owner={:?}",
var_hir_id, upvar_index, cx.body_owner
);

let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id);

match upvar_index {
None => ExprKind::VarRef { id: var_hir_id },
fn convert_var<'tcx>(cx: &mut Cx<'_, 'tcx>, var_hir_id: hir::HirId) -> ExprKind<'tcx> {
// We want upvars here not captures.
// Captures will be handled in MIR.
let is_upvar = cx
.tcx
.upvars_mentioned(cx.body_owner)
.map_or(false, |upvars| upvars.contains_key(&var_hir_id));

Some(upvar_index) => {
let closure_def_id = cx.body_owner;
let upvar_id = ty::UpvarId {
var_path: ty::UpvarPath { hir_id: var_hir_id },
closure_expr_id: closure_def_id.expect_local(),
};
let var_ty = cx.typeck_results().node_type(var_hir_id);
debug!("convert_var({:?}): is_upvar={}, body_owner={:?}", var_hir_id, is_upvar, cx.body_owner);

// FIXME free regions in closures are not right
let closure_ty = cx
.typeck_results()
.node_type(cx.tcx.hir().local_def_id_to_hir_id(upvar_id.closure_expr_id));

// FIXME we're just hard-coding the idea that the
// signature will be &self or &mut self and hence will
// have a bound region with number 0
let region = ty::ReFree(ty::FreeRegion {
scope: closure_def_id,
bound_region: ty::BoundRegion::BrAnon(0),
});
let region = cx.tcx.mk_region(region);

let self_expr = if let ty::Closure(_, closure_substs) = closure_ty.kind() {
match cx.infcx.closure_kind(closure_substs).unwrap() {
ty::ClosureKind::Fn => {
let ref_closure_ty = cx.tcx.mk_ref(
region,
ty::TypeAndMut { ty: closure_ty, mutbl: hir::Mutability::Not },
);
Expr {
ty: closure_ty,
temp_lifetime,
span: expr.span,
kind: ExprKind::Deref {
arg: Expr {
ty: ref_closure_ty,
temp_lifetime,
span: expr.span,
kind: ExprKind::SelfRef,
}
.to_ref(),
},
}
}
ty::ClosureKind::FnMut => {
let ref_closure_ty = cx.tcx.mk_ref(
region,
ty::TypeAndMut { ty: closure_ty, mutbl: hir::Mutability::Mut },
);
Expr {
ty: closure_ty,
temp_lifetime,
span: expr.span,
kind: ExprKind::Deref {
arg: Expr {
ty: ref_closure_ty,
temp_lifetime,
span: expr.span,
kind: ExprKind::SelfRef,
}
.to_ref(),
},
}
}
ty::ClosureKind::FnOnce => Expr {
ty: closure_ty,
temp_lifetime,
span: expr.span,
kind: ExprKind::SelfRef,
},
}
} else {
Expr { ty: closure_ty, temp_lifetime, span: expr.span, kind: ExprKind::SelfRef }
};

// at this point we have `self.n`, which loads up the upvar
let field_kind =
ExprKind::Field { lhs: self_expr.to_ref(), name: Field::new(upvar_index) };

// ...but the upvar might be an `&T` or `&mut T` capture, at which
// point we need an implicit deref
match cx.typeck_results().upvar_capture(upvar_id) {
ty::UpvarCapture::ByValue(_) => field_kind,
ty::UpvarCapture::ByRef(borrow) => ExprKind::Deref {
arg: Expr {
temp_lifetime,
ty: cx.tcx.mk_ref(
borrow.region,
ty::TypeAndMut { ty: var_ty, mutbl: borrow.kind.to_mutbl_lossy() },
),
span: expr.span,
kind: field_kind,
}
.to_ref(),
},
}
}
if is_upvar {
ExprKind::UpvarRef { closure_def_id: cx.body_owner, var_hir_id }
} else {
ExprKind::VarRef { id: var_hir_id }
}
}

Expand Down Expand Up @@ -1102,7 +998,7 @@ fn capture_upvar<'tcx>(
temp_lifetime,
ty: var_ty,
span: closure_expr.span,
kind: convert_var(cx, closure_expr, var_hir_id),
kind: convert_var(cx, var_hir_id),
};
match upvar_capture {
ty::UpvarCapture::ByValue(_) => captured_var.to_ref(),
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_mir_build/src/thir/cx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ impl<'a, 'tcx> Cx<'a, 'tcx> {
ty.needs_drop(self.tcx, self.param_env)
}

crate fn infcx(&self) -> &'a InferCtxt<'a, 'tcx> {
self.infcx
}

crate fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx
}
Expand Down
10 changes: 8 additions & 2 deletions compiler/rustc_mir_build/src/thir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,14 @@ crate enum ExprKind<'tcx> {
VarRef {
id: hir::HirId,
},
/// first argument, used for self in a closure
SelfRef,
/// Used to represent upvars mentioned in a closure/generator
UpvarRef {
/// DefId of the closure/generator
closure_def_id: DefId,

/// HirId of the root variable
var_hir_id: hir::HirId,
},
Borrow {
borrow_kind: BorrowKind,
arg: ExprRef<'tcx>,
Expand Down
10 changes: 7 additions & 3 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1808,9 +1808,13 @@ impl<'a> Parser<'a> {
return Ok(false); // Don't continue.
}

/// Handle a generic const argument that had not been enclosed in braces, and suggest enclosing
/// it braces. In this situation, unlike in `handle_ambiguous_unbraced_const_arg`, this is
/// almost certainly a const argument, so we always offer a suggestion.
/// Attempt to parse a generic const argument that has not been enclosed in braces.
/// There are a limited number of expressions that are permitted without being encoded
/// in braces:
/// - Literals.
/// - Single-segment paths (i.e. standalone generic const parameters).
/// All other expressions that can be parsed will emit an error suggesting the expression be
/// wrapped in braces.
pub fn handle_unambiguous_unbraced_const_arg(&mut self) -> PResult<'a, P<Expr>> {
let start = self.token.span;
let expr = self.parse_expr_res(Restrictions::CONST_EXPR, None).map_err(|mut err| {
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_parse/src/parser/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,13 +489,21 @@ impl<'a> Parser<'a> {
/// - An expression surrounded in `{}`.
/// - A literal.
/// - A numeric literal prefixed by `-`.
/// - A single-segment path.
pub(super) fn expr_is_valid_const_arg(&self, expr: &P<rustc_ast::Expr>) -> bool {
match &expr.kind {
ast::ExprKind::Block(_, _) | ast::ExprKind::Lit(_) => true,
ast::ExprKind::Unary(ast::UnOp::Neg, expr) => match &expr.kind {
ast::ExprKind::Lit(_) => true,
_ => false,
},
// We can only resolve single-segment paths at the moment, because multi-segment paths
// require type-checking: see `visit_generic_arg` in `src/librustc_resolve/late.rs`.
ast::ExprKind::Path(None, path)
if path.segments.len() == 1 && path.segments[0].args.is_none() =>
{
true
}
_ => false,
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
&obligation.predicate,
&obligation.cause.code,
&mut vec![],
&mut Default::default(),
);

err.emit();
Expand Down Expand Up @@ -1700,6 +1701,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
&obligation.predicate,
&obligation.cause.code,
&mut vec![],
&mut Default::default(),
);
self.suggest_unsized_bound_if_applicable(err, obligation);
}
Expand Down
Loading