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 #41413

Merged
merged 11 commits into from
Apr 20, 2017
Merged
10 changes: 7 additions & 3 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1597,9 +1597,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// generic so we don't have to do anything quite this
// terrible.
let trace = TypeTrace::dummy(self.tcx);
self.equate(true, trace, a, b).map(|InferOk { obligations, .. }| {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty());
self.equate(true, trace, a, b).map(|InferOk { obligations: _, .. }| {
// We can intentionally ignore obligations here, since
// this is part of a simple test for general
// "equatability". However, it's not entirely clear
// that we *ought* to be, perhaps a better thing would
// be to use a mini-fulfillment context or something
// like that.
})
})
}
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,15 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
debug!("overlap: b_impl_header={:?}", b_impl_header);

// Do `a` and `b` unify? If not, no overlap.
match selcx.infcx().eq_impl_headers(true,
let obligations = match selcx.infcx().eq_impl_headers(true,
&ObligationCause::dummy(),
&a_impl_header,
&b_impl_header) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty());
obligations
}
Err(_) => return None
}
};

debug!("overlap: unification check succeeded");

Expand All @@ -78,6 +77,7 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
.map(|p| Obligation { cause: ObligationCause::dummy(),
recursion_depth: 0,
predicate: p })
.chain(obligations)
.find(|o| !selcx.evaluate_obligation(o));

if let Some(failing_obligation) = opt_failing_obligation {
Expand Down
28 changes: 13 additions & 15 deletions src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,22 +329,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
Some(val) => Some(val),
None => {
span_err!(self.tcx.sess, err_sp, E0272,
"the #[rustc_on_unimplemented] \
attribute on \
trait definition for {} refers to \
non-existent type parameter {}",
trait_str, s);
"the #[rustc_on_unimplemented] attribute on trait \
definition for {} refers to non-existent type \
parameter {}",
trait_str, s);
errored = true;
None
}
},
_ => {
span_err!(self.tcx.sess, err_sp, E0273,
"the #[rustc_on_unimplemented] attribute \
on trait definition for {} must have \
named format arguments, eg \
`#[rustc_on_unimplemented = \
\"foo {{T}}\"]`", trait_str);
"the #[rustc_on_unimplemented] attribute on trait \
definition for {} must have named format arguments, eg \
`#[rustc_on_unimplemented = \"foo {{T}}\"]`",
trait_str);
errored = true;
None
}
Expand Down Expand Up @@ -485,8 +483,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
"impl has stricter requirements than trait");

if let Some(trait_item_span) = self.tcx.hir.span_if_local(trait_item_def_id) {
err.span_label(trait_item_span,
&format!("definition of `{}` from trait", item_name));
let span = self.tcx.sess.codemap().def_span(trait_item_span);
err.span_label(span, &format!("definition of `{}` from trait", item_name));
}

err.span_label(
Expand Down Expand Up @@ -692,6 +690,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
{
assert!(type_def_id.is_local());
let span = self.hir.span_if_local(type_def_id).unwrap();
let span = self.sess.codemap().def_span(span);
let mut err = struct_span_err!(self.sess, span, E0072,
"recursive type `{}` has infinite size",
self.item_path_str(type_def_id));
Expand All @@ -709,13 +708,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
-> DiagnosticBuilder<'tcx>
{
let trait_str = self.item_path_str(trait_def_id);
let span = self.sess.codemap().def_span(span);
let mut err = struct_span_err!(
self.sess, span, E0038,
"the trait `{}` cannot be made into an object",
trait_str);
err.span_label(span, &format!(
"the trait `{}` cannot be made into an object", trait_str
));
err.span_label(span, &format!("the trait `{}` cannot be made into an object", trait_str));

let mut reported_violations = FxHashSet();
for violation in violations {
Expand Down
10 changes: 10 additions & 0 deletions src/librustc/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,16 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
});
}

pub fn register_predicate_obligations(&mut self,
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
obligations: Vec<PredicateObligation<'tcx>>)
{
for obligation in obligations {
self.register_predicate_obligation(infcx, obligation);
}
}


pub fn region_obligations(&self,
body_id: ast::NodeId)
-> &[RegionObligation<'tcx>]
Expand Down
7 changes: 3 additions & 4 deletions src/librustc/traits/specialize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
-> Result<&'tcx Substs<'tcx>, ()> {
let selcx = &mut SelectionContext::new(&infcx);
let target_substs = infcx.fresh_substs_for_item(DUMMY_SP, target_impl);
let (target_trait_ref, obligations) = impl_trait_ref_and_oblig(selcx,
let (target_trait_ref, mut obligations) = impl_trait_ref_and_oblig(selcx,
target_impl,
target_substs);

Expand All @@ -227,9 +227,8 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
&ObligationCause::dummy(),
source_trait_ref,
target_trait_ref) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty())
Ok(InferOk { obligations: o, .. }) => {
obligations.extend(o);
}
Err(_) => {
debug!("fulfill_implication: {:?} does not unify with {:?}",
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_driver/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
pub fn check_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
match self.sub(t1, t2) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) once obligations are being propagated, assert the right thing.
// None of these tests should require nested obligations:
assert!(obligations.is_empty());
}
Err(ref e) => {
Expand All @@ -400,7 +400,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
pub fn check_lub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>, t_lub: Ty<'tcx>) {
match self.lub(t1, t2) {
Ok(InferOk { obligations, value: t }) => {
// FIXME(#32730) once obligations are being propagated, assert the right thing.
// None of these tests should require nested obligations:
assert!(obligations.is_empty());

self.assert_eq(t, t_lub);
Expand All @@ -415,7 +415,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
match self.glb(t1, t2) {
Err(e) => panic!("unexpected error computing LUB: {:?}", e),
Ok(InferOk { obligations, value: t }) => {
// FIXME(#32730) once obligations are being propagated, assert the right thing.
// None of these tests should require nested obligations:
assert!(obligations.is_empty());

self.assert_eq(t, t_glb);
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_trans/cabi_x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,12 @@ pub fn compute_abi_info<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fty: &mut FnType
};

if in_mem {
// `sret` / `byval` parameter thus one less integer register available
int_regs -= 1;

arg.make_indirect(ccx);
if is_arg {
arg.attrs.set(ArgAttribute::ByVal);
} else {
// `sret` parameter thus one less integer register available
int_regs -= 1;
}
} else {
// split into sized chunks passed individually
Expand Down
7 changes: 3 additions & 4 deletions src/librustc_typeck/check/compare_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,10 +294,9 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
debug!("compare_impl_method: trait_fty={:?}", trait_fty);

let sub_result = infcx.sub_types(false, &cause, impl_fty, trait_fty)
.map(|InferOk { obligations, .. }| {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty());
});
.map(|InferOk { obligations, .. }| {
inh.register_predicates(obligations);
});

if let Err(terr) = sub_result {
debug!("sub_types failed: impl ty {:?}, trait ty {:?}",
Expand Down
5 changes: 2 additions & 3 deletions src/librustc_typeck/check/dropck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
// check that the impl type can be made to match the trait type.

let impl_param_env = ty::ParameterEnvironment::for_item(tcx, self_type_node_id);
tcx.infer_ctxt(impl_param_env, Reveal::UserFacing).enter(|infcx| {
tcx.infer_ctxt(impl_param_env, Reveal::UserFacing).enter(|ref infcx| {
let tcx = infcx.tcx;
let mut fulfillment_cx = traits::FulfillmentContext::new();

Expand All @@ -97,8 +97,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
let cause = &ObligationCause::misc(drop_impl_span, drop_impl_node_id);
match infcx.eq_types(true, cause, named_type, fresh_impl_self_ty) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty());
fulfillment_cx.register_predicate_obligations(infcx, obligations);
}
Err(_) => {
let item_span = tcx.hir.span(self_type_node_id);
Expand Down
17 changes: 12 additions & 5 deletions src/librustc_typeck/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ use rustc::infer::InferOk;
use rustc::ty::subst::Substs;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::maps::Providers;
use rustc::traits::{ObligationCause, ObligationCauseCode, Reveal};
use rustc::traits::{FulfillmentContext, ObligationCause, ObligationCauseCode, Reveal};
use session::config;
use util::common::time;

Expand Down Expand Up @@ -153,15 +153,22 @@ fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
expected: Ty<'tcx>,
actual: Ty<'tcx>)
-> bool {
tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| {
tcx.infer_ctxt((), Reveal::UserFacing).enter(|ref infcx| {
let mut fulfill_cx = FulfillmentContext::new();
match infcx.eq_types(false, &cause, expected, actual) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty());
true
fulfill_cx.register_predicate_obligations(infcx, obligations);
}
Err(err) => {
infcx.report_mismatched_types(cause, expected, actual, err).emit();
return false;
}
}

match fulfill_cx.select_all_or_error(infcx) {
Ok(()) => true,
Err(errors) => {
infcx.report_fulfillment_errors(&errors);
false
}
}
Expand Down
18 changes: 17 additions & 1 deletion src/libstd/ffi/os_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -677,7 +677,13 @@ impl Borrow<OsStr> for OsString {
#[stable(feature = "rust1", since = "1.0.0")]
impl ToOwned for OsStr {
type Owned = OsString;
fn to_owned(&self) -> OsString { self.to_os_string() }
fn to_owned(&self) -> OsString {
self.to_os_string()
}
fn clone_into(&self, target: &mut OsString) {
target.clear();
target.push(self);
}
}

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -863,4 +869,14 @@ mod tests {
let boxed = <Box<OsStr>>::default();
assert!(boxed.is_empty());
}

#[test]
fn test_os_str_clone_into() {
let mut os_string = OsString::with_capacity(123);
os_string.push("hello");
let os_str = OsStr::new("bonjour");
os_str.clone_into(&mut os_string);
assert_eq!(os_str, os_string);
assert!(os_string.capacity() >= 123);
}
}
1 change: 1 addition & 0 deletions src/libstd/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@
#![feature(str_utf16)]
#![feature(test, rustc_private)]
#![feature(thread_local)]
#![feature(toowned_clone_into)]
#![feature(try_from)]
#![feature(unboxed_closures)]
#![feature(unicode)]
Expand Down
12 changes: 12 additions & 0 deletions src/libstd/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1414,6 +1414,9 @@ impl ToOwned for Path {
fn to_owned(&self) -> PathBuf {
self.to_path_buf()
}
fn clone_into(&self, target: &mut PathBuf) {
self.inner.clone_into(&mut target.inner);
}
}

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -3859,4 +3862,13 @@ mod tests {
assert_eq!(&*boxed, &*path_buf);
assert_eq!(&*path_buf, path);
}

#[test]
fn test_clone_into() {
let mut path_buf = PathBuf::from("supercalifragilisticexpialidocious");
let path = Path::new("short");
path.clone_into(&mut path_buf);
assert_eq!(path, path_buf);
assert!(path_buf.into_os_string().capacity() >= 15);
}
}
19 changes: 19 additions & 0 deletions src/libsyntax/codemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,25 @@ impl CodeMap {
}
}

/// Given a `Span`, try to get a shorter span ending before the first occurrence of `c` `char`
pub fn span_until_char(&self, sp: Span, c: char) -> Span {
match self.span_to_snippet(sp) {
Ok(snippet) => {
let snippet = snippet.split(c).nth(0).unwrap_or("").trim_right();
if snippet.len() > 0 && !snippet.contains('\n') {
Span { hi: BytePos(sp.lo.0 + snippet.len() as u32), ..sp }
} else {
sp
}
}
_ => sp,
}
}

pub fn def_span(&self, sp: Span) -> Span {
self.span_until_char(sp, '{')
}

pub fn get_filemap(&self, filename: &str) -> Option<Rc<FileMap>> {
for fm in self.files.borrow().iter() {
if filename == fm.name {
Expand Down
2 changes: 1 addition & 1 deletion src/stage0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
# tarball for a stable release you'll likely see `1.x.0-$date` where `1.x.0` was
# released on `$date`

rustc: beta-2017-03-21
rustc: beta-2017-04-05
15 changes: 15 additions & 0 deletions src/test/run-make/extern-fn-struct-passing-abi/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,21 @@ void byval_rect_with_float(int32_t a, int32_t b, float c, int32_t d,
assert(s.d == 556);
}

// System V x86_64 ABI:
// a, b, d, e, f should be byval pointer (on the stack)
// g passed via register (fixes #41375)
//
// Win64 ABI:
// a, b, d, e, f, g should be byval pointer
void byval_rect_with_many_huge(struct Huge a, struct Huge b, struct Huge c,
struct Huge d, struct Huge e, struct Huge f,
struct Rect g) {
assert(g.a == 123);
assert(g.b == 456);
assert(g.c == 789);
assert(g.d == 420);
}

// System V x86_64 & Win64 ABI:
// a, b should be in registers
// s should be split across 2 integer registers
Expand Down
8 changes: 8 additions & 0 deletions src/test/run-make/extern-fn-struct-passing-abi/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ extern {

fn byval_rect_with_float(a: i32, b: i32, c: f32, d: i32, e: i32, f: i32, s: Rect);

fn byval_rect_with_many_huge(a: Huge, b: Huge, c: Huge, d: Huge, e: Huge, f: Huge, g: Rect);

fn split_rect(a: i32, b: i32, s: Rect);

fn split_rect_floats(a: f32, b: f32, s: FloatRect);
Expand Down Expand Up @@ -95,6 +97,12 @@ fn main() {
byval_many_rect(1, 2, 3, 4, 5, 6, s);
byval_rect_floats(1., 2., 3., 4., 5., 6., 7., s, u);
byval_rect_with_float(1, 2, 3.0, 4, 5, 6, s);
byval_rect_with_many_huge(v, v, v, v, v, v, Rect {
a: 123,
b: 456,
c: 789,
d: 420
});
split_rect(1, 2, s);
split_rect_floats(1., 2., u);
split_rect_with_floats(1, 2, 3.0, 4, 5.0, 6, s);
Expand Down
Loading