diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index 4a67614be756fd5e21ffa8694fd8063b8354f7f4..aa13f0422c95459a11e9641d21d5f2dde7fc1cd2 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -1107,13 +1107,12 @@ def validate_names(self):
                     raise UnknownVariantError(spec.name, vname)
 
 
-    def constrain(self, other, **kwargs):
+    def constrain(self, other, deps=True):
         """Merge the constraints of other with self.
 
         Returns True if the spec changed as a result, False if not.
         """
         other = self._autospec(other)
-        constrain_deps = kwargs.get('deps', True)
 
         if not self.name == other.name:
             raise UnsatisfiableSpecNameError(self.name, other.name)
@@ -1146,7 +1145,7 @@ def constrain(self, other, **kwargs):
         self.architecture = self.architecture or other.architecture
         changed |= (self.architecture != old)
 
-        if constrain_deps:
+        if deps:
             changed |= self._constrain_dependencies(other)
 
         return changed
@@ -1154,6 +1153,8 @@ def constrain(self, other, **kwargs):
 
     def _constrain_dependencies(self, other):
         """Apply constraints of other spec's dependencies to this spec."""
+        other = self._autospec(other)
+
         if not self.dependencies or not other.dependencies:
             return False
 
@@ -1260,6 +1261,8 @@ def satisfies(self, other, deps=True, strict=False):
 
     def satisfies_dependencies(self, other, strict=False):
         """This checks constraints on common dependencies against each other."""
+        other = self._autospec(other)
+
         if strict:
             if other.dependencies and not self.dependencies:
                 return False
diff --git a/lib/spack/spack/test/spec_semantics.py b/lib/spack/spack/test/spec_semantics.py
index 8614b74c7a296e80c717634ed0eff14a69e55567..20df2603f5b3416ef1b06652e2891c194dc56271 100644
--- a/lib/spack/spack/test/spec_semantics.py
+++ b/lib/spack/spack/test/spec_semantics.py
@@ -64,6 +64,16 @@ def check_constrain(self, expected, spec, constraint):
         self.assertEqual(exp, spec)
 
 
+    def check_constrain_changed(self, spec, constraint):
+        spec = Spec(spec)
+        self.assertTrue(spec.constrain(constraint))
+
+
+    def check_constrain_not_changed(self, spec, constraint):
+        spec = Spec(spec)
+        self.assertFalse(spec.constrain(constraint))
+
+
     def check_invalid_constraint(self, spec, constraint):
         spec = Spec(spec)
         constraint = Spec(constraint)
@@ -200,6 +210,11 @@ def test_constrain_arch(self):
         self.check_constrain('libelf=bgqos_0', 'libelf', 'libelf=bgqos_0')
 
 
+    def test_constrain_compiler(self):
+        self.check_constrain('libelf=bgqos_0', 'libelf=bgqos_0', 'libelf=bgqos_0')
+        self.check_constrain('libelf=bgqos_0', 'libelf', 'libelf=bgqos_0')
+
+
     def test_invalid_constraint(self):
         self.check_invalid_constraint('libelf@0:2.0', 'libelf@2.1:3')
         self.check_invalid_constraint('libelf@0:2.5%gcc@4.8:4.9', 'libelf@2.1:3%gcc@4.5:4.7')
@@ -208,3 +223,47 @@ def test_invalid_constraint(self):
         self.check_invalid_constraint('libelf+debug~foo', 'libelf+debug+foo')
 
         self.check_invalid_constraint('libelf=bgqos_0', 'libelf=x86_54')
+
+
+    def test_constrain_changed(self):
+        self.check_constrain_changed('libelf', '@1.0')
+        self.check_constrain_changed('libelf', '@1.0:5.0')
+        self.check_constrain_changed('libelf', '%gcc')
+        self.check_constrain_changed('libelf%gcc', '%gcc@4.5')
+        self.check_constrain_changed('libelf', '+debug')
+        self.check_constrain_changed('libelf', '~debug')
+        self.check_constrain_changed('libelf', '=bgqos_0')
+
+
+    def test_constrain_not_changed(self):
+        self.check_constrain_not_changed('libelf', 'libelf')
+        self.check_constrain_not_changed('libelf@1.0', '@1.0')
+        self.check_constrain_not_changed('libelf@1.0:5.0', '@1.0:5.0')
+        self.check_constrain_not_changed('libelf%gcc', '%gcc')
+        self.check_constrain_not_changed('libelf%gcc@4.5', '%gcc@4.5')
+        self.check_constrain_not_changed('libelf+debug', '+debug')
+        self.check_constrain_not_changed('libelf~debug', '~debug')
+        self.check_constrain_not_changed('libelf=bgqos_0', '=bgqos_0')
+        self.check_constrain_not_changed('libelf^foo', 'libelf^foo')
+        self.check_constrain_not_changed('libelf^foo^bar', 'libelf^foo^bar')
+
+
+    def test_constrain_dependency_changed(self):
+        self.check_constrain_changed('libelf^foo', 'libelf^foo@1.0')
+        self.check_constrain_changed('libelf^foo', 'libelf^foo@1.0:5.0')
+        self.check_constrain_changed('libelf^foo', 'libelf^foo%gcc')
+        self.check_constrain_changed('libelf^foo%gcc', 'libelf^foo%gcc@4.5')
+        self.check_constrain_changed('libelf^foo', 'libelf^foo+debug')
+        self.check_constrain_changed('libelf^foo', 'libelf^foo~debug')
+        self.check_constrain_changed('libelf^foo', 'libelf^foo=bgqos_0')
+
+
+    def test_constrain_dependency_not_changed(self):
+        self.check_constrain_not_changed('libelf^foo@1.0', 'libelf^foo@1.0')
+        self.check_constrain_not_changed('libelf^foo@1.0:5.0', 'libelf^foo@1.0:5.0')
+        self.check_constrain_not_changed('libelf^foo%gcc', 'libelf^foo%gcc')
+        self.check_constrain_not_changed('libelf^foo%gcc@4.5', 'libelf^foo%gcc@4.5')
+        self.check_constrain_not_changed('libelf^foo+debug', 'libelf^foo+debug')
+        self.check_constrain_not_changed('libelf^foo~debug', 'libelf^foo~debug')
+        self.check_constrain_not_changed('libelf^foo=bgqos_0', 'libelf^foo=bgqos_0')
+