Skip to content

Commit

Permalink
Use more accurate ConstraintCategorys
Browse files Browse the repository at this point in the history
Adds UseAsConst and UseAsStatic to replace Return in consts/statics.
Don't report the arguments to an overloaded operator as CallArguments.
Also don't report "escaping data" in these items.
  • Loading branch information
matthewjasper committed Oct 20, 2018
1 parent a2c2487 commit 049bee0
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 6 deletions.
2 changes: 2 additions & 0 deletions src/librustc/ich/impls_mir.rs
Expand Up @@ -557,6 +557,8 @@ impl_stable_hash_for!(struct mir::ClosureOutlivesRequirement<'tcx> {

impl_stable_hash_for!(enum mir::ConstraintCategory {
Return,
UseAsConst,
UseAsStatic,
TypeAnnotation,
Cast,
ClosureBounds,
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/mir/mod.rs
Expand Up @@ -2725,6 +2725,8 @@ pub struct ClosureOutlivesRequirement<'tcx> {
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub enum ConstraintCategory {
Return,
UseAsConst,
UseAsStatic,
TypeAnnotation,
Cast,

Expand Down
Expand Up @@ -40,6 +40,8 @@ impl ConstraintDescription for ConstraintCategory {
match self {
ConstraintCategory::Assignment => "assignment ",
ConstraintCategory::Return => "returning this value ",
ConstraintCategory::UseAsConst => "using this value as a constant ",
ConstraintCategory::UseAsStatic => "using this value as a static ",
ConstraintCategory::Cast => "cast ",
ConstraintCategory::CallArgument => "argument ",
ConstraintCategory::TypeAnnotation => "type annotation ",
Expand Down Expand Up @@ -375,12 +377,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let outlived_fr_name_and_span =
self.get_var_name_and_span_for_region(infcx.tcx, mir, outlived_fr);

let escapes_from = if infcx.tcx.is_closure(mir_def_id) { "closure" } else { "function" };
let escapes_from = match self.universal_regions.defining_ty {
DefiningTy::Closure(..) => "closure",
DefiningTy::Generator(..) => "generator",
DefiningTy::FnDef(..) => "function",
DefiningTy::Const(..) => "const"
};

// Revert to the normal error in these cases.
// Assignments aren't "escapes" in function items.
if (fr_name_and_span.is_none() && outlived_fr_name_and_span.is_none())
|| (category == ConstraintCategory::Assignment && escapes_from == "function")
|| escapes_from == "const"
{
return self.report_general_error(mir, infcx, mir_def_id,
fr, true, outlived_fr, false,
Expand Down
47 changes: 42 additions & 5 deletions src/librustc_mir/borrow_check/nll/type_check/mod.rs
Expand Up @@ -23,7 +23,7 @@ use borrow_check::nll::renumber;
use borrow_check::nll::type_check::free_region_relations::{
CreateResult, UniversalRegionRelations,
};
use borrow_check::nll::universal_regions::UniversalRegions;
use borrow_check::nll::universal_regions::{DefiningTy, UniversalRegions};
use borrow_check::nll::ToRegionVid;
use dataflow::move_paths::MoveData;
use dataflow::FlowAtLocation;
Expand Down Expand Up @@ -1209,7 +1209,21 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
// of lowering. Assignments to other sorts of places *are* interesting
// though.
let category = match *place {
Place::Local(RETURN_PLACE) => ConstraintCategory::Return,
Place::Local(RETURN_PLACE) => if let Some(BorrowCheckContext {
universal_regions: UniversalRegions {
defining_ty: DefiningTy::Const(def_id, _),
..
},
..
}) = self.borrowck_context {
if tcx.is_static(*def_id).is_some() {
ConstraintCategory::UseAsStatic
} else {
ConstraintCategory::UseAsConst
}
} else {
ConstraintCategory::Return
}
Place::Local(l) if !mir.local_decls[l].is_user_variable.is_some() => {
ConstraintCategory::Boring
}
Expand Down Expand Up @@ -1391,6 +1405,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
ref func,
ref args,
ref destination,
from_hir_call,
..
} => {
let func_ty = func.ty(mir, tcx);
Expand Down Expand Up @@ -1435,7 +1450,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
}
}

self.check_call_inputs(mir, term, &sig, args, term_location);
self.check_call_inputs(mir, term, &sig, args, term_location, from_hir_call);
}
TerminatorKind::Assert {
ref cond, ref msg, ..
Expand Down Expand Up @@ -1493,7 +1508,23 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
Some((ref dest, _target_block)) => {
let dest_ty = dest.ty(mir, tcx).to_ty(tcx);
let category = match *dest {
Place::Local(RETURN_PLACE) => ConstraintCategory::Return,
Place::Local(RETURN_PLACE) => {
if let Some(BorrowCheckContext {
universal_regions: UniversalRegions {
defining_ty: DefiningTy::Const(def_id, _),
..
},
..
}) = self.borrowck_context {
if tcx.is_static(*def_id).is_some() {
ConstraintCategory::UseAsStatic
} else {
ConstraintCategory::UseAsConst
}
} else {
ConstraintCategory::Return
}
},
Place::Local(l) if !mir.local_decls[l].is_user_variable.is_some() => {
ConstraintCategory::Boring
}
Expand Down Expand Up @@ -1538,18 +1569,24 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
sig: &ty::FnSig<'tcx>,
args: &[Operand<'tcx>],
term_location: Location,
from_hir_call: bool,
) {
debug!("check_call_inputs({:?}, {:?})", sig, args);
if args.len() < sig.inputs().len() || (args.len() > sig.inputs().len() && !sig.variadic) {
span_mirbug!(self, term, "call to {:?} with wrong # of args", sig);
}
for (n, (fn_arg, op_arg)) in sig.inputs().iter().zip(args).enumerate() {
let op_arg_ty = op_arg.ty(mir, self.tcx());
let category = if from_hir_call {
ConstraintCategory::CallArgument
} else {
ConstraintCategory::Boring
};
if let Err(terr) = self.sub_types(
op_arg_ty,
fn_arg,
term_location.to_locations(),
ConstraintCategory::CallArgument,
category,
) {
span_mirbug!(
self,
Expand Down

0 comments on commit 049bee0

Please sign in to comment.